From 6decea8316ea11b4fb0feba370e36b6f482f0f56 Mon Sep 17 00:00:00 2001 From: Repo Admin Date: Sun, 20 Jun 2004 11:35:13 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'GNUPG-1-9-BRANCH-MO'. --- ABOUT-NLS | 625 -- AUTHORS | 0 COPYING | 340 - ChangeLog | 452 - INSTALL | 229 - Makefile.am | 64 - NEWS | 171 - README | 511 - README.CVS | 51 - THANKS | 5 - TODO | 78 - acinclude.m4 | 436 - am/cmacros.am | 45 - autogen.sh | 161 - common/ChangeLog | 340 - common/Makefile.am | 62 - common/README | 11 - common/asshelp.c | 166 - common/asshelp.h | 36 - common/b64enc.c | 211 - common/dynload.h | 71 - common/errors.h | 112 - common/fseeko.c | 40 - common/ftello.c | 45 - common/gettime.c | 278 - common/i18n.h | 47 - common/iobuf.c | 2415 ----- common/iobuf.h | 170 - common/isascii.c | 29 - common/maperror.c | 105 - common/membuf.c | 89 - common/membuf.h | 41 - common/miscellaneous.c | 127 - common/mkdtemp.c | 96 - common/mkerrors | 72 - common/mkerrtok | 67 - common/putc_unlocked.c | 31 - common/sexp-parse.h | 99 - common/signal.c | 226 - common/simple-pwquery.c | 493 - common/simple-pwquery.h | 69 - common/sysutils.c | 230 - common/sysutils.h | 31 - common/ttyio.c | 555 - common/ttyio.h | 44 - common/util.h | 171 - common/vasprintf.c | 169 - common/xasprintf.c | 44 - common/xreadline.c | 116 - common/yesno.c | 96 - configure.ac | 1123 --- doc/ChangeLog | 102 - doc/Makefile.am | 28 - doc/assuan.texi | 189 - doc/contrib.texi | 124 - doc/debugging.texi | 82 - doc/fdl.texi | 401 - doc/gnupg.texi | 174 - doc/gpg-agent.texi | 791 -- doc/gpg.texi | 1806 ---- doc/gpgsm.texi | 848 -- doc/gpl.texi | 397 - doc/scdaemon.texi | 387 - g10/ChangeLog | 8948 ----------------- g10/Makefile.am | 121 - g10/OPTIONS | 24 - g10/armor.c | 1334 --- g10/build-packet.c | 1203 --- g10/call-agent.c | 893 -- g10/call-agent.h | 94 - g10/card-util.c | 884 -- g10/cipher.c | 165 - g10/comment.c | 112 - g10/compress.c | 329 - g10/dearmor.c | 123 - g10/decrypt.c | 142 - g10/delkey.c | 209 - g10/encode.c | 821 -- g10/encr-data.c | 269 - g10/exec.c | 619 -- g10/exec.h | 43 - g10/export.c | 546 - g10/filter.h | 155 - g10/free-packet.c | 542 - g10/g10.c | 3367 ------- g10/getkey.c | 2618 ----- g10/global.h | 31 - g10/gpg.h | 38 - g10/gpgv.c | 389 - g10/helptext.c | 316 - g10/import.c | 1906 ---- g10/kbnode.c | 401 - g10/keydb.c | 725 -- g10/keydb.h | 283 - g10/keyedit.c | 3856 ------- g10/keygen.c | 2916 ------ g10/keyid.c | 609 -- g10/keylist.c | 1466 --- g10/keyring.c | 1588 --- g10/keyring.h | 46 - g10/keyserver-internal.h | 21 - g10/keyserver.c | 1381 --- g10/main.h | 272 - g10/mainproc.c | 1758 ---- g10/mdfilter.c | 76 - g10/misc.c | 1000 -- g10/mkdtemp.c | 98 - g10/openfile.c | 391 - g10/options.h | 255 - g10/options.skel | 212 - g10/packet.h | 514 - g10/parse-packet.c | 2332 ----- g10/passphrase.c | 1237 --- g10/photoid.c | 333 - g10/photoid.h | 34 - g10/pipemode.c | 317 - g10/pkclist.c | 1372 --- g10/pkglue.c | 342 - g10/pkglue.h | 35 - g10/plaintext.c | 458 - g10/progress.c | 118 - g10/pubkey-enc.c | 345 - g10/pubring.asc | 458 - g10/revoke.c | 690 -- g10/seckey-cert.c | 452 - g10/seskey.c | 244 - g10/sig-check.c | 575 -- g10/sign.c | 1412 --- g10/signal.c | 226 - g10/skclist.c | 176 - g10/status.c | 472 - g10/status.h | 124 - g10/tdbdump.c | 223 - g10/tdbio.c | 1636 --- g10/tdbio.h | 117 - g10/textfilter.c | 235 - g10/trustdb.c | 2158 ---- g10/trustdb.h | 86 - g10/verify.c | 197 - include/ChangeLog | 403 - include/_regex.h | 574 -- include/cipher.h | 97 - include/distfiles | 13 - include/errors.h | 101 - include/host2net.h | 43 - include/http.h | 82 - include/i18n.h | 54 - include/keyserver.h | 42 - include/memory.h | 93 - include/mpi.h | 201 - include/types.h | 135 - include/util.h | 300 - include/zlib-riscos.h | 134 - intl/ChangeLog | 4 - intl/Makefile.in | 479 - intl/VERSION | 1 - intl/bindtextdom.c | 374 - intl/config.charset | 467 - intl/dcgettext.c | 59 - intl/dcigettext.c | 1238 --- intl/dcngettext.c | 60 - intl/dgettext.c | 59 - intl/dngettext.c | 61 - intl/eval-plural.h | 114 - intl/explodename.c | 192 - intl/finddomain.c | 195 - intl/gettext.c | 64 - intl/gettextP.h | 224 - intl/gmo.h | 148 - intl/hash-string.h | 59 - intl/intl-compat.c | 151 - intl/l10nflist.c | 453 - intl/libgnuintl.h | 296 - intl/libgnuintl.h.in | 309 - intl/loadinfo.h | 156 - intl/loadmsgcat.c | 1322 --- intl/localcharset.c | 398 - intl/localcharset.h | 42 - intl/locale.alias | 78 - intl/localealias.c | 419 - intl/localename.c | 772 -- intl/log.c | 104 - intl/ngettext.c | 68 - intl/os2compat.c | 98 - intl/os2compat.h | 46 - intl/osdep.c | 24 - intl/plural-exp.c | 156 - intl/plural-exp.h | 126 - intl/plural.c | 1518 --- intl/plural.y | 409 - intl/ref-add.sin | 31 - intl/ref-del.sin | 26 - intl/relocatable.c | 439 - intl/relocatable.h | 67 - intl/textdomain.c | 142 - jnlib/ChangeLog | 209 - jnlib/Makefile.am | 43 - jnlib/README | 7 - jnlib/argparse.c | 999 -- jnlib/argparse.h | 67 - jnlib/dotlock.c | 436 - jnlib/dotlock.h | 36 - jnlib/libjnlib-config.h | 72 - jnlib/logging.c | 558 - jnlib/logging.h | 83 - jnlib/mischelp.h | 54 - jnlib/stringhelp.c | 627 -- jnlib/stringhelp.h | 90 - jnlib/strlist.c | 172 - jnlib/strlist.h | 51 - jnlib/types.h | 101 - jnlib/utf8conv.c | 448 - jnlib/utf8conv.h | 31 - jnlib/xmalloc.c | 88 - jnlib/xmalloc.h | 31 - kbx/ChangeLog | 166 - kbx/Makefile.am | 52 - kbx/Manifest | 8 - kbx/kbxutil.c | 357 - kbx/keybox-blob.c | 1031 -- kbx/keybox-defs.h | 191 - kbx/keybox-dump.c | 484 - kbx/keybox-errors.c | 47 - kbx/keybox-file.c | 146 - kbx/keybox-init.c | 127 - kbx/keybox-search-desc.h | 72 - kbx/keybox-search.c | 944 -- kbx/keybox-update.c | 698 -- kbx/keybox-util.c | 72 - kbx/keybox.h | 115 - kbx/mkerrors | 71 - m4/ChangeLog | 30 - m4/Makefile.am | 3 - m4/codeset.m4 | 23 - m4/gettext.m4 | 415 - m4/glibc21.m4 | 32 - m4/gpg-error.m4 | 56 - m4/iconv.m4 | 103 - m4/intdiv0.m4 | 72 - m4/inttypes-pri.m4 | 32 - m4/inttypes.m4 | 27 - m4/inttypes_h.m4 | 28 - m4/isc-posix.m4 | 26 - m4/ksba.m4 | 76 - m4/lcmessage.m4 | 32 - m4/lib-ld.m4 | 110 - m4/lib-link.m4 | 551 - m4/lib-prefix.m4 | 155 - m4/libassuan.m4 | 76 - m4/libgcrypt.m4 | 108 - m4/nls.m4 | 49 - m4/po.m4 | 197 - m4/progtest.m4 | 91 - m4/stdint_h.m4 | 28 - m4/uintmax_t.m4 | 32 - m4/ulonglong.m4 | 23 - po/ChangeLog | 44 - po/LINGUAS | 5 - po/Makefile.in.in | 353 - po/Makevars | 41 - po/POTFILES.in | 36 - po/Rules-quot | 42 - po/boldquot.sed | 10 - po/de.po | 1193 --- po/en@boldquot.header | 25 - po/en@quot.header | 22 - po/insert-header.sin | 23 - po/quot.sed | 6 - po/remove-potcdate.sed | 11 - po/remove-potcdate.sin | 19 - scd/ChangeLog | 659 -- scd/Makefile.am | 85 - scd/apdu.c | 1981 ---- scd/apdu.h | 85 - scd/app-common.h | 170 - scd/app-dinsig.c | 427 - scd/app-help.c | 162 - scd/app-nks.c | 515 - scd/app-openpgp.c | 1640 --- scd/app.c | 391 - scd/atr.c | 287 - scd/atr.h | 28 - scd/card-common.h | 73 - scd/card-dinsig.c | 258 - scd/card-p15.c | 500 - scd/card.c | 570 -- scd/ccid-driver.c | 1277 --- scd/ccid-driver.h | 76 - scd/command.c | 1268 --- scd/iso7816.c | 617 -- scd/iso7816.h | 73 - scd/pcsc-wrapper.c | 631 -- scd/sc-copykeys.c | 735 -- scd/sc-investigate.c | 770 -- scd/scdaemon.c | 933 -- scd/scdaemon.h | 130 - scd/tlv.c | 208 - scd/tlv.h | 84 - scripts/compile | 107 - scripts/config.guess | 1321 --- scripts/config.rpath | 548 - scripts/config.sub | 1443 --- scripts/depcomp | 472 - scripts/install-sh | 294 - scripts/mdate-sh | 133 - scripts/missing | 336 - scripts/mkinstalldirs | 111 - scripts/texinfo.tex | 6773 ------------- sm/ChangeLog | 1220 --- sm/Makefile.am | 56 - sm/base64.c | 655 -- sm/call-agent.c | 635 -- sm/call-dirmngr.c | 785 -- sm/certchain.c | 976 -- sm/certcheck.c | 303 - sm/certdump.c | 696 -- sm/certlist.c | 427 - sm/certreqgen.c | 739 -- sm/decrypt.c | 512 - sm/delete.c | 172 - sm/encrypt.c | 511 - sm/export.c | 736 -- sm/fingerprint.c | 331 - sm/gpgsm.c | 1700 ---- sm/gpgsm.h | 311 - sm/import.c | 725 -- sm/keydb.c | 1532 --- sm/keydb.h | 85 - sm/keylist.c | 1252 --- sm/misc.c | 65 - sm/server.c | 1121 --- sm/sign.c | 666 -- sm/verify.c | 540 - .../567064FE6D14A17B2D811ABB407728BC558AA455 | 18 - tests/ChangeLog | 73 - tests/Makefile.am | 77 - tests/asschk.c | 1059 -- tests/cert_cci_sphinx_ca.pem | 18 - tests/cert_cci_test_wzs.pem | 4 - tests/cert_cci_test_zs.pem | 16 - tests/cert_cci_user02.pem | 17 - tests/cert_cci_user03.pem | 17 - tests/cert_cci_user04.pem | 17 - tests/cert_cci_user06.pem | 17 - tests/cert_cci_user07.pem | 17 - tests/cert_testpki_testpca.pem | 21 - tests/crl_testpki_testpca.pem | 18 - tests/extrasamples/README | 5 - tests/extrasamples/dod-test9.p12 | Bin 3934 -> 0 bytes tests/inittests | 99 - tests/key_g10code_pete1.pem | 18 - tests/key_g10code_theo1.pem | 21 - tests/runtest | 4 - ...100C27173EF6E9C4E9A25D3D69F86D37A4F939.key | 18 - ...6D17B4B94BBE8304926C016D2C5C7805EB6705.key | 10 - tests/samplekeys/README | 17 - tests/samplekeys/cert_g10code_enconly_1.pem | 26 - tests/samplekeys/cert_g10code_pete1.pem | 24 - tests/samplekeys/cert_g10code_test1.pem | 19 - tests/samplekeys/cert_g10code_test_ca.pem | 27 - tests/samplekeys/cert_g10code_theo1.pem | 40 - tests/samplekeys/cryptlib-key.p12 | Bin 1559 -> 0 bytes tests/samplekeys/opensc-test.p12 | Bin 2397 -> 0 bytes tests/samplekeys/ossl-rentec-user.pem | 44 - tests/samplekeys/ov-server.p12 | Bin 2133 -> 0 bytes tests/samplekeys/ov-user.p12 | Bin 2141 -> 0 bytes tests/samplekeys/webdeca.der | Bin 1857 -> 0 bytes tests/samplekeys/webderoot.der | Bin 2009 -> 0 bytes tests/samplemsgs/webde-buenemann-signed.cms | Bin 3368 -> 0 bytes tests/skey_g10code_test1.pem | 19 - tests/sm-sign+verify | 73 - tests/sm-verify | 114 - tests/text-1.dsig.pem | 27 - tests/text-1.osig-bad.pem | 45 - tests/text-1.osig-badusage.pem | 75 - tests/text-1.osig.pem | 48 - tests/text-1.txt | 17 - tests/text-2.osig-bad.pem | 28 - tests/text-2.osig.pem | 29 - tests/text-2.txt | 2 - tests/text-3.txt | 2 - tools/ChangeLog | 252 - tools/Makefile.am | 39 - tools/Manifest | 6 - tools/README.gpgconf | 422 - tools/addgnupghome | 122 - tools/der-to-pem | 27 - tools/gpgconf-comp.c | 2434 ----- tools/gpgconf.c | 206 - tools/gpgconf.h | 58 - tools/gpgparsemail.c | 705 -- tools/no-libgcrypt.c | 105 - tools/rfc822parse.c | 1235 --- tools/rfc822parse.h | 79 - tools/watchgnupg.c | 389 - 395 files changed, 155087 deletions(-) delete mode 100644 ABOUT-NLS delete mode 100644 AUTHORS delete mode 100644 COPYING delete mode 100644 ChangeLog delete mode 100644 INSTALL delete mode 100644 Makefile.am delete mode 100644 NEWS delete mode 100644 README delete mode 100644 README.CVS delete mode 100644 THANKS delete mode 100644 TODO delete mode 100644 acinclude.m4 delete mode 100644 am/cmacros.am delete mode 100755 autogen.sh delete mode 100644 common/ChangeLog delete mode 100644 common/Makefile.am delete mode 100644 common/README delete mode 100644 common/asshelp.c delete mode 100644 common/asshelp.h delete mode 100644 common/b64enc.c delete mode 100644 common/dynload.h delete mode 100644 common/errors.h delete mode 100644 common/fseeko.c delete mode 100644 common/ftello.c delete mode 100644 common/gettime.c delete mode 100644 common/i18n.h delete mode 100644 common/iobuf.c delete mode 100644 common/iobuf.h delete mode 100644 common/isascii.c delete mode 100644 common/maperror.c delete mode 100644 common/membuf.c delete mode 100644 common/membuf.h delete mode 100644 common/miscellaneous.c delete mode 100644 common/mkdtemp.c delete mode 100755 common/mkerrors delete mode 100755 common/mkerrtok delete mode 100644 common/putc_unlocked.c delete mode 100644 common/sexp-parse.h delete mode 100644 common/signal.c delete mode 100644 common/simple-pwquery.c delete mode 100644 common/simple-pwquery.h delete mode 100644 common/sysutils.c delete mode 100644 common/sysutils.h delete mode 100644 common/ttyio.c delete mode 100644 common/ttyio.h delete mode 100644 common/util.h delete mode 100644 common/vasprintf.c delete mode 100644 common/xasprintf.c delete mode 100644 common/xreadline.c delete mode 100644 common/yesno.c delete mode 100644 configure.ac delete mode 100644 doc/ChangeLog delete mode 100644 doc/Makefile.am delete mode 100644 doc/assuan.texi delete mode 100644 doc/contrib.texi delete mode 100644 doc/debugging.texi delete mode 100644 doc/fdl.texi delete mode 100644 doc/gnupg.texi delete mode 100644 doc/gpg-agent.texi delete mode 100644 doc/gpg.texi delete mode 100644 doc/gpgsm.texi delete mode 100644 doc/gpl.texi delete mode 100644 doc/scdaemon.texi delete mode 100644 g10/ChangeLog delete mode 100644 g10/Makefile.am delete mode 100644 g10/OPTIONS delete mode 100644 g10/armor.c delete mode 100644 g10/build-packet.c delete mode 100644 g10/call-agent.c delete mode 100644 g10/call-agent.h delete mode 100644 g10/card-util.c delete mode 100644 g10/cipher.c delete mode 100644 g10/comment.c delete mode 100644 g10/compress.c delete mode 100644 g10/dearmor.c delete mode 100644 g10/decrypt.c delete mode 100644 g10/delkey.c delete mode 100644 g10/encode.c delete mode 100644 g10/encr-data.c delete mode 100644 g10/exec.c delete mode 100644 g10/exec.h delete mode 100644 g10/export.c delete mode 100644 g10/filter.h delete mode 100644 g10/free-packet.c delete mode 100644 g10/g10.c delete mode 100644 g10/getkey.c delete mode 100644 g10/global.h delete mode 100644 g10/gpg.h delete mode 100644 g10/gpgv.c delete mode 100644 g10/helptext.c delete mode 100644 g10/import.c delete mode 100644 g10/kbnode.c delete mode 100644 g10/keydb.c delete mode 100644 g10/keydb.h delete mode 100644 g10/keyedit.c delete mode 100644 g10/keygen.c delete mode 100644 g10/keyid.c delete mode 100644 g10/keylist.c delete mode 100644 g10/keyring.c delete mode 100644 g10/keyring.h delete mode 100644 g10/keyserver-internal.h delete mode 100644 g10/keyserver.c delete mode 100644 g10/main.h delete mode 100644 g10/mainproc.c delete mode 100644 g10/mdfilter.c delete mode 100644 g10/misc.c delete mode 100644 g10/mkdtemp.c delete mode 100644 g10/openfile.c delete mode 100644 g10/options.h delete mode 100644 g10/options.skel delete mode 100644 g10/packet.h delete mode 100644 g10/parse-packet.c delete mode 100644 g10/passphrase.c delete mode 100644 g10/photoid.c delete mode 100644 g10/photoid.h delete mode 100644 g10/pipemode.c delete mode 100644 g10/pkclist.c delete mode 100644 g10/pkglue.c delete mode 100644 g10/pkglue.h delete mode 100644 g10/plaintext.c delete mode 100644 g10/progress.c delete mode 100644 g10/pubkey-enc.c delete mode 100644 g10/pubring.asc delete mode 100644 g10/revoke.c delete mode 100644 g10/seckey-cert.c delete mode 100644 g10/seskey.c delete mode 100644 g10/sig-check.c delete mode 100644 g10/sign.c delete mode 100644 g10/signal.c delete mode 100644 g10/skclist.c delete mode 100644 g10/status.c delete mode 100644 g10/status.h delete mode 100644 g10/tdbdump.c delete mode 100644 g10/tdbio.c delete mode 100644 g10/tdbio.h delete mode 100644 g10/textfilter.c delete mode 100644 g10/trustdb.c delete mode 100644 g10/trustdb.h delete mode 100644 g10/verify.c delete mode 100644 include/ChangeLog delete mode 100644 include/_regex.h delete mode 100644 include/cipher.h delete mode 100644 include/distfiles delete mode 100644 include/errors.h delete mode 100644 include/host2net.h delete mode 100644 include/http.h delete mode 100644 include/i18n.h delete mode 100644 include/keyserver.h delete mode 100644 include/memory.h delete mode 100644 include/mpi.h delete mode 100644 include/types.h delete mode 100644 include/util.h delete mode 100644 include/zlib-riscos.h delete mode 100644 intl/ChangeLog delete mode 100644 intl/Makefile.in delete mode 100644 intl/VERSION delete mode 100644 intl/bindtextdom.c delete mode 100755 intl/config.charset delete mode 100644 intl/dcgettext.c delete mode 100644 intl/dcigettext.c delete mode 100644 intl/dcngettext.c delete mode 100644 intl/dgettext.c delete mode 100644 intl/dngettext.c delete mode 100644 intl/eval-plural.h delete mode 100644 intl/explodename.c delete mode 100644 intl/finddomain.c delete mode 100644 intl/gettext.c delete mode 100644 intl/gettextP.h delete mode 100644 intl/gmo.h delete mode 100644 intl/hash-string.h delete mode 100644 intl/intl-compat.c delete mode 100644 intl/l10nflist.c delete mode 100644 intl/libgnuintl.h delete mode 100644 intl/libgnuintl.h.in delete mode 100644 intl/loadinfo.h delete mode 100644 intl/loadmsgcat.c delete mode 100644 intl/localcharset.c delete mode 100644 intl/localcharset.h delete mode 100644 intl/locale.alias delete mode 100644 intl/localealias.c delete mode 100644 intl/localename.c delete mode 100644 intl/log.c delete mode 100644 intl/ngettext.c delete mode 100644 intl/os2compat.c delete mode 100644 intl/os2compat.h delete mode 100644 intl/osdep.c delete mode 100644 intl/plural-exp.c delete mode 100644 intl/plural-exp.h delete mode 100644 intl/plural.c delete mode 100644 intl/plural.y delete mode 100644 intl/ref-add.sin delete mode 100644 intl/ref-del.sin delete mode 100644 intl/relocatable.c delete mode 100644 intl/relocatable.h delete mode 100644 intl/textdomain.c delete mode 100644 jnlib/ChangeLog delete mode 100644 jnlib/Makefile.am delete mode 100644 jnlib/README delete mode 100644 jnlib/argparse.c delete mode 100644 jnlib/argparse.h delete mode 100644 jnlib/dotlock.c delete mode 100644 jnlib/dotlock.h delete mode 100644 jnlib/libjnlib-config.h delete mode 100644 jnlib/logging.c delete mode 100644 jnlib/logging.h delete mode 100644 jnlib/mischelp.h delete mode 100644 jnlib/stringhelp.c delete mode 100644 jnlib/stringhelp.h delete mode 100644 jnlib/strlist.c delete mode 100644 jnlib/strlist.h delete mode 100644 jnlib/types.h delete mode 100644 jnlib/utf8conv.c delete mode 100644 jnlib/utf8conv.h delete mode 100644 jnlib/xmalloc.c delete mode 100644 jnlib/xmalloc.h delete mode 100644 kbx/ChangeLog delete mode 100644 kbx/Makefile.am delete mode 100644 kbx/Manifest delete mode 100644 kbx/kbxutil.c delete mode 100644 kbx/keybox-blob.c delete mode 100644 kbx/keybox-defs.h delete mode 100644 kbx/keybox-dump.c delete mode 100644 kbx/keybox-errors.c delete mode 100644 kbx/keybox-file.c delete mode 100644 kbx/keybox-init.c delete mode 100644 kbx/keybox-search-desc.h delete mode 100644 kbx/keybox-search.c delete mode 100644 kbx/keybox-update.c delete mode 100644 kbx/keybox-util.c delete mode 100644 kbx/keybox.h delete mode 100755 kbx/mkerrors delete mode 100644 m4/ChangeLog delete mode 100644 m4/Makefile.am delete mode 100644 m4/codeset.m4 delete mode 100644 m4/gettext.m4 delete mode 100644 m4/glibc21.m4 delete mode 100644 m4/gpg-error.m4 delete mode 100644 m4/iconv.m4 delete mode 100644 m4/intdiv0.m4 delete mode 100644 m4/inttypes-pri.m4 delete mode 100644 m4/inttypes.m4 delete mode 100644 m4/inttypes_h.m4 delete mode 100644 m4/isc-posix.m4 delete mode 100644 m4/ksba.m4 delete mode 100644 m4/lcmessage.m4 delete mode 100644 m4/lib-ld.m4 delete mode 100644 m4/lib-link.m4 delete mode 100644 m4/lib-prefix.m4 delete mode 100644 m4/libassuan.m4 delete mode 100644 m4/libgcrypt.m4 delete mode 100644 m4/nls.m4 delete mode 100644 m4/po.m4 delete mode 100644 m4/progtest.m4 delete mode 100644 m4/stdint_h.m4 delete mode 100644 m4/uintmax_t.m4 delete mode 100644 m4/ulonglong.m4 delete mode 100644 po/ChangeLog delete mode 100644 po/LINGUAS delete mode 100644 po/Makefile.in.in delete mode 100644 po/Makevars delete mode 100644 po/POTFILES.in delete mode 100644 po/Rules-quot delete mode 100644 po/boldquot.sed delete mode 100644 po/de.po delete mode 100644 po/en@boldquot.header delete mode 100644 po/en@quot.header delete mode 100644 po/insert-header.sin delete mode 100644 po/quot.sed delete mode 100644 po/remove-potcdate.sed delete mode 100644 po/remove-potcdate.sin delete mode 100644 scd/ChangeLog delete mode 100644 scd/Makefile.am delete mode 100644 scd/apdu.c delete mode 100644 scd/apdu.h delete mode 100644 scd/app-common.h delete mode 100644 scd/app-dinsig.c delete mode 100644 scd/app-help.c delete mode 100644 scd/app-nks.c delete mode 100644 scd/app-openpgp.c delete mode 100644 scd/app.c delete mode 100644 scd/atr.c delete mode 100644 scd/atr.h delete mode 100644 scd/card-common.h delete mode 100644 scd/card-dinsig.c delete mode 100644 scd/card-p15.c delete mode 100644 scd/card.c delete mode 100644 scd/ccid-driver.c delete mode 100644 scd/ccid-driver.h delete mode 100644 scd/command.c delete mode 100644 scd/iso7816.c delete mode 100644 scd/iso7816.h delete mode 100644 scd/pcsc-wrapper.c delete mode 100644 scd/sc-copykeys.c delete mode 100644 scd/sc-investigate.c delete mode 100644 scd/scdaemon.c delete mode 100644 scd/scdaemon.h delete mode 100644 scd/tlv.c delete mode 100644 scd/tlv.h delete mode 100755 scripts/compile delete mode 100755 scripts/config.guess delete mode 100755 scripts/config.rpath delete mode 100755 scripts/config.sub delete mode 100755 scripts/depcomp delete mode 100755 scripts/install-sh delete mode 100755 scripts/mdate-sh delete mode 100755 scripts/missing delete mode 100755 scripts/mkinstalldirs delete mode 100644 scripts/texinfo.tex delete mode 100644 sm/ChangeLog delete mode 100644 sm/Makefile.am delete mode 100644 sm/base64.c delete mode 100644 sm/call-agent.c delete mode 100644 sm/call-dirmngr.c delete mode 100644 sm/certchain.c delete mode 100644 sm/certcheck.c delete mode 100644 sm/certdump.c delete mode 100644 sm/certlist.c delete mode 100644 sm/certreqgen.c delete mode 100644 sm/decrypt.c delete mode 100644 sm/delete.c delete mode 100644 sm/encrypt.c delete mode 100644 sm/export.c delete mode 100644 sm/fingerprint.c delete mode 100644 sm/gpgsm.c delete mode 100644 sm/gpgsm.h delete mode 100644 sm/import.c delete mode 100644 sm/keydb.c delete mode 100644 sm/keydb.h delete mode 100644 sm/keylist.c delete mode 100644 sm/misc.c delete mode 100644 sm/server.c delete mode 100644 sm/sign.c delete mode 100644 sm/verify.c delete mode 100644 tests/567064FE6D14A17B2D811ABB407728BC558AA455 delete mode 100644 tests/ChangeLog delete mode 100644 tests/Makefile.am delete mode 100644 tests/asschk.c delete mode 100644 tests/cert_cci_sphinx_ca.pem delete mode 100644 tests/cert_cci_test_wzs.pem delete mode 100644 tests/cert_cci_test_zs.pem delete mode 100644 tests/cert_cci_user02.pem delete mode 100644 tests/cert_cci_user03.pem delete mode 100644 tests/cert_cci_user04.pem delete mode 100644 tests/cert_cci_user06.pem delete mode 100644 tests/cert_cci_user07.pem delete mode 100644 tests/cert_testpki_testpca.pem delete mode 100644 tests/crl_testpki_testpca.pem delete mode 100644 tests/extrasamples/README delete mode 100644 tests/extrasamples/dod-test9.p12 delete mode 100755 tests/inittests delete mode 100644 tests/key_g10code_pete1.pem delete mode 100644 tests/key_g10code_theo1.pem delete mode 100755 tests/runtest delete mode 100644 tests/samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key delete mode 100644 tests/samplekeys/8D6D17B4B94BBE8304926C016D2C5C7805EB6705.key delete mode 100644 tests/samplekeys/README delete mode 100644 tests/samplekeys/cert_g10code_enconly_1.pem delete mode 100644 tests/samplekeys/cert_g10code_pete1.pem delete mode 100644 tests/samplekeys/cert_g10code_test1.pem delete mode 100644 tests/samplekeys/cert_g10code_test_ca.pem delete mode 100644 tests/samplekeys/cert_g10code_theo1.pem delete mode 100644 tests/samplekeys/cryptlib-key.p12 delete mode 100644 tests/samplekeys/opensc-test.p12 delete mode 100644 tests/samplekeys/ossl-rentec-user.pem delete mode 100644 tests/samplekeys/ov-server.p12 delete mode 100644 tests/samplekeys/ov-user.p12 delete mode 100644 tests/samplekeys/webdeca.der delete mode 100644 tests/samplekeys/webderoot.der delete mode 100644 tests/samplemsgs/webde-buenemann-signed.cms delete mode 100644 tests/skey_g10code_test1.pem delete mode 100644 tests/sm-sign+verify delete mode 100644 tests/sm-verify delete mode 100644 tests/text-1.dsig.pem delete mode 100644 tests/text-1.osig-bad.pem delete mode 100644 tests/text-1.osig-badusage.pem delete mode 100644 tests/text-1.osig.pem delete mode 100644 tests/text-1.txt delete mode 100644 tests/text-2.osig-bad.pem delete mode 100644 tests/text-2.osig.pem delete mode 100644 tests/text-2.txt delete mode 100644 tests/text-3.txt delete mode 100644 tools/ChangeLog delete mode 100644 tools/Makefile.am delete mode 100644 tools/Manifest delete mode 100644 tools/README.gpgconf delete mode 100755 tools/addgnupghome delete mode 100755 tools/der-to-pem delete mode 100644 tools/gpgconf-comp.c delete mode 100644 tools/gpgconf.c delete mode 100644 tools/gpgconf.h delete mode 100644 tools/gpgparsemail.c delete mode 100644 tools/no-libgcrypt.c delete mode 100644 tools/rfc822parse.c delete mode 100644 tools/rfc822parse.h delete mode 100644 tools/watchgnupg.c diff --git a/ABOUT-NLS b/ABOUT-NLS deleted file mode 100644 index 47d5e39f0..000000000 --- a/ABOUT-NLS +++ /dev/null @@ -1,625 +0,0 @@ -Notes on the Free Translation Project -************************************* - - Free software is going international! The Free Translation Project -is a way to get maintainers of free software, translators, and users all -together, so that will gradually become able to speak many languages. -A few packages already provide translations for their messages. - - If you found this `ABOUT-NLS' file inside a distribution, you may -assume that the distributed package does use GNU `gettext' internally, -itself available at your nearest GNU archive site. But you do _not_ -need to install GNU `gettext' prior to configuring, installing or using -this package with messages translated. - - Installers will find here some useful hints. These notes also -explain how users should proceed for getting the programs to use the -available translations. They tell how people wanting to contribute and -work at translations should contact the appropriate team. - - When reporting bugs in the `intl/' directory or bugs which may be -related to internationalization, you should tell about the version of -`gettext' which is used. The information can be found in the -`intl/VERSION' file, in internationalized packages. - -Quick configuration advice -========================== - - If you want to exploit the full power of internationalization, you -should configure it using - - ./configure --with-included-gettext - -to force usage of internationalizing routines provided within this -package, despite the existence of internationalizing capabilities in the -operating system where this package is being installed. So far, only -the `gettext' implementation in the GNU C library version 2 provides as -many features (such as locale alias, message inheritance, automatic -charset conversion or plural form handling) as the implementation here. -It is also not possible to offer this additional functionality on top -of a `catgets' implementation. Future versions of GNU `gettext' will -very likely convey even more functionality. So it might be a good idea -to change to GNU `gettext' as soon as possible. - - So you need _not_ provide this option if you are using GNU libc 2 or -you have installed a recent copy of the GNU gettext package with the -included `libintl'. - -INSTALL Matters -=============== - - Some packages are "localizable" when properly installed; the -programs they contain can be made to speak your own native language. -Most such packages use GNU `gettext'. Other packages have their own -ways to internationalization, predating GNU `gettext'. - - By default, this package will be installed to allow translation of -messages. It will automatically detect whether the system already -provides the GNU `gettext' functions. If not, the GNU `gettext' own -library will be used. This library is wholly contained within this -package, usually in the `intl/' subdirectory, so prior installation of -the GNU `gettext' package is _not_ required. Installers may use -special options at configuration time for changing the default -behaviour. The commands: - - ./configure --with-included-gettext - ./configure --disable-nls - -will respectively bypass any pre-existing `gettext' to use the -internationalizing routines provided within this package, or else, -_totally_ disable translation of messages. - - When you already have GNU `gettext' installed on your system and run -configure without an option for your new package, `configure' will -probably detect the previously built and installed `libintl.a' file and -will decide to use this. This might be not what is desirable. You -should use the more recent version of the GNU `gettext' library. I.e. -if the file `intl/VERSION' shows that the library which comes with this -package is more recent, you should use - - ./configure --with-included-gettext - -to prevent auto-detection. - - The configuration process will not test for the `catgets' function -and therefore it will not be used. The reason is that even an -emulation of `gettext' on top of `catgets' could not provide all the -extensions of the GNU `gettext' library. - - Internationalized packages have usually many `po/LL.po' files, where -LL gives an ISO 639 two-letter code identifying the language. Unless -translations have been forbidden at `configure' time by using the -`--disable-nls' switch, all available translations are installed -together with the package. However, the environment variable `LINGUAS' -may be set, prior to configuration, to limit the installed set. -`LINGUAS' should then contain a space separated list of two-letter -codes, stating which languages are allowed. - -Using This Package -================== - - As a user, if your language has been installed for this package, you -only have to set the `LANG' environment variable to the appropriate -`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code, -and `CC' is an ISO 3166 two-letter country code. For example, let's -suppose that you speak German and live in Germany. At the shell -prompt, merely execute `setenv LANG de_DE' (in `csh'), -`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). -This can be done from your `.login' or `.profile' file, once and for -all. - - You might think that the country code specification is redundant. -But in fact, some languages have dialects in different countries. For -example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The -country code serves to distinguish the dialects. - - The locale naming convention of `LL_CC', with `LL' denoting the -language and `CC' denoting the country, is the one use on systems based -on GNU libc. On other systems, some variations of this scheme are -used, such as `LL' or `LL_CC.ENCODING'. You can get the list of -locales supported by your system for your country by running the command -`locale -a | grep '^LL''. - - Not all programs have translations for all languages. By default, an -English message is shown in place of a nonexistent translation. If you -understand other languages, you can set up a priority list of languages. -This is done through a different environment variable, called -`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' -for the purpose of message handling, but you still need to have `LANG' -set to the primary language; this is required by other parts of the -system libraries. For example, some Swedish users who would rather -read translations in German than English for when Swedish is not -available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. - - In the `LANGUAGE' environment variable, but not in the `LANG' -environment variable, `LL_CC' combinations can be abbreviated as `LL' -to denote the language's main dialect. For example, `de' is equivalent -to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' -(Portuguese as spoken in Portugal) in this context. - -Translating Teams -================= - - For the Free Translation Project to be a success, we need interested -people who like their own language and write it well, and who are also -able to synergize with other translators speaking the same language. -Each translation team has its own mailing list. The up-to-date list of -teams can be found at the Free Translation Project's homepage, -`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams" -area. - - If you'd like to volunteer to _work_ at translating messages, you -should become a member of the translating team for your own language. -The subscribing address is _not_ the same as the list itself, it has -`-request' appended. For example, speakers of Swedish can send a -message to `sv-request@li.org', having this message body: - - subscribe - - Keep in mind that team members are expected to participate -_actively_ in translations, or at solving translational difficulties, -rather than merely lurking around. If your team does not exist yet and -you want to start one, or if you are unsure about what to do or how to -get started, please write to `translation@iro.umontreal.ca' to reach the -coordinator for all translator teams. - - The English team is special. It works at improving and uniformizing -the terminology in use. Proven linguistic skill are praised more than -programming skill, here. - -Available Packages -================== - - Languages are not equally supported in all packages. The following -matrix shows the current state of internationalization, as of May 2003. -The matrix shows, in regard of each package, for which languages PO -files have been submitted to translation coordination, with a -translation percentage of at least 50%. - - Ready PO files am az be bg ca cs da de el en en_GB eo es - +-------------------------------------------+ - a2ps | [] [] [] [] | - aegis | () | - anubis | | - ap-utils | | - bash | [] [] [] | - batchelor | | - bfd | [] [] | - binutils | [] [] | - bison | [] [] [] | - bluez-pin | [] [] | - clisp | | - clisp | [] [] [] | - coreutils | [] [] [] [] | - cpio | [] [] [] | - darkstat | () [] | - diffutils | [] [] [] [] [] [] [] | - e2fsprogs | [] [] | - enscript | [] [] [] [] | - error | [] [] [] [] [] | - fetchmail | [] () [] [] [] [] | - fileutils | [] [] [] | - findutils | [] [] [] [] [] [] | - flex | [] [] [] [] | - gas | [] | - gawk | [] [] [] [] | - gcal | [] | - gcc | [] [] | - gettext | [] [] [] [] [] | - gettext-runtime | [] [] [] [] [] | - gettext-tools | [] [] | - gimp-print | [] [] [] [] [] | - gliv | | - glunarclock | [] [] [] | - gnucash | () [] | - gnucash-glossary | [] () [] | - gnupg | [] () [] [] [] [] | - gpe-calendar | [] | - gpe-conf | [] | - gpe-contacts | [] | - gpe-edit | | - gpe-login | [] | - gpe-ownerinfo | [] | - gpe-sketchbook | [] | - gpe-timesheet | | - gpe-today | [] | - gpe-todo | [] | - gphoto2 | [] [] [] [] | - gprof | [] [] | - gpsdrive | () () () | - grep | [] [] [] [] [] | - gretl | [] | - hello | [] [] [] [] [] [] | - id-utils | [] [] | - indent | [] [] [] [] | - jpilot | [] [] [] [] | - jwhois | [] | - kbd | [] [] [] [] [] | - ld | [] [] | - libc | [] [] [] [] [] [] | - libgpewidget | [] | - libiconv | [] [] [] [] [] | - lifelines | [] () | - lilypond | [] | - lingoteach | | - lingoteach_lessons | () () | - lynx | [] [] [] [] | - m4 | [] [] [] [] | - mailutils | [] [] | - make | [] [] [] | - man-db | [] () [] [] () | - mysecretdiary | [] [] [] | - nano | [] () [] [] [] | - nano_1_0 | [] () [] [] [] | - opcodes | [] [] | - parted | [] [] [] [] [] | - ptx | [] [] [] [] [] | - python | | - radius | | - recode | [] [] [] [] [] [] | - screem | | - sed | [] [] [] [] [] | - sh-utils | [] [] [] | - sharutils | [] [] [] [] [] [] | - sketch | [] () [] | - soundtracker | [] [] [] | - sp | [] | - tar | [] [] [] [] | - texinfo | [] [] [] [] | - textutils | [] [] [] [] | - tin | () () | - util-linux | [] [] [] [] [] | - vorbis-tools | [] [] [] | - wastesedge | () | - wdiff | [] [] [] [] | - wget | [] [] [] [] [] [] [] | - xchat | [] [] [] | - xpad | | - +-------------------------------------------+ - am az be bg ca cs da de el en en_GB eo es - 0 1 4 2 31 17 54 60 14 1 4 12 56 - - et fa fi fr ga gl he hr hu id it ja ko - +----------------------------------------+ - a2ps | [] [] [] () () | - aegis | | - anubis | [] | - ap-utils | [] | - bash | [] [] | - batchelor | [] | - bfd | [] [] | - binutils | [] [] | - bison | [] [] [] [] | - bluez-pin | [] [] [] [] | - clisp | | - clisp | [] | - coreutils | [] [] [] [] | - cpio | [] [] [] [] | - darkstat | () [] [] [] | - diffutils | [] [] [] [] [] [] [] | - e2fsprogs | | - enscript | [] [] | - error | [] [] [] [] | - fetchmail | [] | - fileutils | [] [] [] [] [] | - findutils | [] [] [] [] [] [] [] [] [] [] [] | - flex | [] [] | - gas | [] | - gawk | [] [] | - gcal | [] | - gcc | [] | - gettext | [] [] [] | - gettext-runtime | [] [] [] [] | - gettext-tools | [] | - gimp-print | [] [] | - gliv | () | - glunarclock | [] [] [] [] | - gnucash | [] | - gnucash-glossary | [] | - gnupg | [] [] [] [] [] [] [] | - gpe-calendar | [] | - gpe-conf | | - gpe-contacts | [] | - gpe-edit | [] [] | - gpe-login | [] | - gpe-ownerinfo | [] [] [] | - gpe-sketchbook | [] | - gpe-timesheet | [] [] [] | - gpe-today | [] [] | - gpe-todo | [] [] | - gphoto2 | [] [] [] | - gprof | [] [] | - gpsdrive | () [] () () | - grep | [] [] [] [] [] [] [] [] [] [] [] | - gretl | [] | - hello | [] [] [] [] [] [] [] [] [] [] [] [] [] | - id-utils | [] [] [] | - indent | [] [] [] [] [] [] [] [] | - jpilot | [] () | - jwhois | [] [] [] [] | - kbd | [] | - ld | [] | - libc | [] [] [] [] [] [] | - libgpewidget | [] [] [] | - libiconv | [] [] [] [] [] [] [] [] | - lifelines | () | - lilypond | [] | - lingoteach | [] [] | - lingoteach_lessons | | - lynx | [] [] [] [] | - m4 | [] [] [] [] | - mailutils | | - make | [] [] [] [] [] [] | - man-db | [] () () | - mysecretdiary | [] [] | - nano | [] [] [] [] | - nano_1_0 | [] [] [] [] | - opcodes | [] [] | - parted | [] [] [] | - ptx | [] [] [] [] [] [] [] | - python | | - radius | | - recode | [] [] [] [] [] [] | - screem | | - sed | [] [] [] [] [] [] [] [] | - sh-utils | [] [] [] [] [] [] | - sharutils | [] [] [] [] [] | - sketch | [] | - soundtracker | [] [] [] | - sp | [] () | - tar | [] [] [] [] [] [] [] [] [] | - texinfo | [] [] [] [] | - textutils | [] [] [] [] [] | - tin | [] () | - util-linux | [] [] [] [] () [] | - vorbis-tools | [] | - wastesedge | () | - wdiff | [] [] [] [] [] | - wget | [] [] [] [] [] [] [] [] | - xchat | [] [] [] | - xpad | | - +----------------------------------------+ - et fa fi fr ga gl he hr hu id it ja ko - 20 1 15 73 14 24 8 10 30 31 19 31 9 - - lg lt lv ms nb nl nn no pl pt pt_BR ro - +----------------------------------------+ - a2ps | [] [] () () () [] [] | - aegis | () | - anubis | [] [] | - ap-utils | () | - bash | [] | - batchelor | | - bfd | | - binutils | | - bison | [] [] [] [] | - bluez-pin | [] | - clisp | | - clisp | [] | - coreutils | [] | - cpio | [] [] [] | - darkstat | [] [] [] [] | - diffutils | [] [] [] | - e2fsprogs | | - enscript | [] [] | - error | [] [] | - fetchmail | () () | - fileutils | [] | - findutils | [] [] [] [] | - flex | [] | - gas | | - gawk | [] | - gcal | | - gcc | | - gettext | [] | - gettext-runtime | [] | - gettext-tools | | - gimp-print | [] | - gliv | [] | - glunarclock | [] | - gnucash | | - gnucash-glossary | [] [] | - gnupg | | - gpe-calendar | [] [] | - gpe-conf | [] [] | - gpe-contacts | [] | - gpe-edit | [] [] | - gpe-login | [] [] | - gpe-ownerinfo | [] [] | - gpe-sketchbook | [] [] | - gpe-timesheet | [] [] | - gpe-today | [] [] | - gpe-todo | [] [] | - gphoto2 | | - gprof | [] | - gpsdrive | () () () | - grep | [] [] [] [] | - gretl | | - hello | [] [] [] [] [] [] [] [] [] | - id-utils | [] [] [] | - indent | [] [] [] | - jpilot | () () | - jwhois | [] [] [] | - kbd | | - ld | | - libc | [] [] [] [] | - libgpewidget | [] [] | - libiconv | [] [] | - lifelines | | - lilypond | [] | - lingoteach | | - lingoteach_lessons | | - lynx | [] [] | - m4 | [] [] [] [] | - mailutils | | - make | [] [] | - man-db | [] | - mysecretdiary | [] | - nano | [] [] [] [] | - nano_1_0 | [] [] [] [] | - opcodes | [] [] [] | - parted | [] [] [] | - ptx | [] [] [] [] [] [] [] | - python | | - radius | | - recode | [] [] [] | - screem | | - sed | [] [] | - sh-utils | [] | - sharutils | [] | - sketch | [] | - soundtracker | | - sp | | - tar | [] [] [] [] [] [] | - texinfo | [] | - textutils | [] | - tin | | - util-linux | [] [] | - vorbis-tools | [] [] | - wastesedge | | - wdiff | [] [] [] [] | - wget | [] [] [] | - xchat | [] [] | - xpad | [] | - +----------------------------------------+ - lg lt lv ms nb nl nn no pl pt pt_BR ro - 0 0 2 11 7 26 3 4 18 15 34 34 - - ru sk sl sr sv ta tr uk vi wa zh_CN zh_TW - +-------------------------------------------+ - a2ps | [] [] [] [] [] | 16 - aegis | () | 0 - anubis | [] [] | 5 - ap-utils | () | 1 - bash | [] | 7 - batchelor | | 1 - bfd | [] [] [] | 7 - binutils | [] [] [] | 7 - bison | [] [] | 13 - bluez-pin | | 7 - clisp | | 0 - clisp | | 5 - coreutils | [] [] [] [] [] | 14 - cpio | [] [] [] | 13 - darkstat | [] () () | 9 - diffutils | [] [] [] [] | 21 - e2fsprogs | [] | 3 - enscript | [] [] [] | 11 - error | [] [] [] | 14 - fetchmail | [] | 7 - fileutils | [] [] [] [] [] [] | 15 - findutils | [] [] [] [] [] [] | 27 - flex | [] [] [] | 10 - gas | [] | 3 - gawk | [] [] | 9 - gcal | [] [] | 4 - gcc | [] | 4 - gettext | [] [] [] [] [] [] | 15 - gettext-runtime | [] [] [] [] [] [] | 16 - gettext-tools | [] [] | 5 - gimp-print | [] [] | 10 - gliv | | 1 - glunarclock | [] [] [] | 11 - gnucash | [] [] | 4 - gnucash-glossary | [] [] [] | 8 - gnupg | [] [] [] [] | 16 - gpe-calendar | [] | 5 - gpe-conf | | 3 - gpe-contacts | [] | 4 - gpe-edit | [] | 5 - gpe-login | [] | 5 - gpe-ownerinfo | [] | 7 - gpe-sketchbook | [] | 5 - gpe-timesheet | [] | 6 - gpe-today | [] | 6 - gpe-todo | [] | 6 - gphoto2 | [] [] | 9 - gprof | [] [] | 7 - gpsdrive | [] [] | 3 - grep | [] [] [] [] | 24 - gretl | | 2 - hello | [] [] [] [] [] | 33 - id-utils | [] [] [] | 11 - indent | [] [] [] [] | 19 - jpilot | [] [] [] [] [] | 10 - jwhois | () () [] [] | 10 - kbd | [] [] | 8 - ld | [] [] | 5 - libc | [] [] [] [] | 20 - libgpewidget | | 6 - libiconv | [] [] [] [] [] [] | 21 - lifelines | [] | 2 - lilypond | [] | 4 - lingoteach | | 2 - lingoteach_lessons | () | 0 - lynx | [] [] [] [] | 14 - m4 | [] [] [] | 15 - mailutils | | 2 - make | [] [] [] [] | 15 - man-db | [] | 6 - mysecretdiary | [] [] | 8 - nano | [] [] [] | 15 - nano_1_0 | [] [] [] | 15 - opcodes | [] [] | 9 - parted | [] [] | 13 - ptx | [] [] [] | 22 - python | | 0 - radius | | 0 - recode | [] [] [] [] | 19 - screem | [] | 1 - sed | [] [] [] [] [] | 20 - sh-utils | [] [] [] | 13 - sharutils | [] [] [] [] | 16 - sketch | [] | 5 - soundtracker | [] | 7 - sp | [] | 3 - tar | [] [] [] [] [] | 24 - texinfo | [] [] [] [] | 13 - textutils | [] [] [] [] [] | 15 - tin | | 1 - util-linux | [] [] | 14 - vorbis-tools | [] | 7 - wastesedge | | 0 - wdiff | [] [] [] [] | 17 - wget | [] [] [] [] [] [] [] | 25 - xchat | [] [] [] | 11 - xpad | | 1 - +-------------------------------------------+ - 50 teams ru sk sl sr sv ta tr uk vi wa zh_CN zh_TW - 97 domains 32 19 16 0 56 0 48 10 1 1 12 23 913 - - Some counters in the preceding matrix are higher than the number of -visible blocks let us expect. This is because a few extra PO files are -used for implementing regional variants of languages, or language -dialects. - - For a PO file in the matrix above to be effective, the package to -which it applies should also have been internationalized and -distributed as such by its maintainer. There might be an observable -lag between the mere existence a PO file and its wide availability in a -distribution. - - If May 2003 seems to be old, you may fetch a more recent copy of -this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date -matrix with full percentage details can be found at -`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'. - -Using `gettext' in new packages -=============================== - - If you are writing a freely available program and want to -internationalize it you are welcome to use GNU `gettext' in your -package. Of course you have to respect the GNU Library General Public -License which covers the use of the GNU `gettext' library. This means -in particular that even non-free programs can use `libintl' as a shared -library, whereas only free software can use `libintl' as a static -library or use modified versions of `libintl'. - - Once the sources are changed appropriately and the setup can handle -the use of `gettext' the only thing missing are the translations. The -Free Translation Project is also available for packages which are not -developed inside the GNU project. Therefore the information given above -applies also for every other Free Software Project. Contact -`translation@iro.umontreal.ca' to make the `.pot' files available to -the translation teams. - diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index e69de29bb..000000000 diff --git a/COPYING b/COPYING deleted file mode 100644 index d60c31a97..000000000 --- a/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index f71334c9e..000000000 --- a/ChangeLog +++ /dev/null @@ -1,452 +0,0 @@ -2004-06-08 Werner Koch - - Released 1.9.9. - -2004-06-06 Werner Koch - - * configure.ac: Require libksba 0.9.7. - -2004-04-29 Werner Koch - - Released 1.9.8. - -2004-04-20 Werner Koch - - * configure.ac: Remove the fopencookie test. We don't need the - dummy function because we conditionally use fopencookie, - fpencookie or a replacement at place. - -2004-04-02 Thomas Schwinge - - * autogen.sh: Added ACLOCAL_FLAGS. - -2004-04-06 Werner Koch - - Released 1.9.7. - - * configure.ac: Require libgcrypt 1.1.94. - Introduce PACKAGE_GT and set it to gnupg2. - -2004-03-23 Werner Koch - - * configure.ac: Define SAFE_VERSION_DASH and SAFE_VERSION_DOT. - -2004-03-09 Werner Koch - - * configure.ac (NEED_GPG_ERROR_VERSION): Set to 0.7. - -2004-03-06 Werner Koch - - Released 1.9.6. - - * configure.ac: Check the Libgcrypt API. - -2004-02-25 Werner Koch - - * configure.ac: New option --disable-threads to inhibit - unintentional builds without Pth. - -2004-02-21 Werner Koch - - Released 1.9.5. - -2004-02-20 Werner Koch - - * configure.ac: Fixed URLs in the notice messages. - -2004-02-18 Werner Koch - - * acinclude.m4: Removed macros to detect gpg-error, libgcrypt, - libassuan and ksba as they are now distributed in m4/. - -2004-02-13 Werner Koch - - * configure.ac: Require libksba 0.9.4 and libgcrypt 1.1.92. - -2004-02-12 Werner Koch - - * autogen.sh: Removed cruft from debugging. - - * am/cmacros.am: New. - -2004-02-11 Werner Koch - - * configure.ac: Removed the need for g10defs.h. Reworked the - --with-foo-pgm stuff. - - * autogen.sh (check_version): Removed bashism and simplified. - * acinclude.m4 (AM_PATH_OPENSC): Kludge to avoid error output for - a bad opensc-config. - -2004-01-30 Werner Koch - - Released 1.9.4. - - * configure.ac: Require libksba 0.9.3 due to another bug fix there. - -2004-01-29 Werner Koch - - * README: Updated. - - * configure.ac: Require libksba 0.9.2 due to bug fixes. - -2004-01-24 Werner Koch - - * configure.ac: Now requires libassuan 0.6.3. - -2003-12-23 Werner Koch - - Released 1.9.3. - - * README-alpha: Removed. - * configure.ac, Makefile.am: Add the tests and tools directories. - -2003-12-19 Werner Koch - - * configure.ac: Now require libgcrypt 1.1.91 to help testing the - latest libgcrypt changes. Requires libksab 0.9.1. - -2003-12-17 Werner Koch - - * configure.ac: Requires now libassuan 0.6.2. - (CFLAGS): Add --Wformat-noliteral in gcc mode. - -2003-12-16 Werner Koch - - * configure.ac: Check for funopen and fopencookie as part of the - jnlib checks. - -2003-12-09 Werner Koch - - * configure.ac: Add a min_automake_version. - * README.CVS: New. - * autogen.sh: Revamped except for the --build-w32 hack. - * Makefile.am: Add README.CVS - -2003-11-17 Werner Koch - - Release 1.9.2. - - * configure.ac: Requires now libassuan 0.6.1. - -2003-10-31 Werner Koch - - * configure.ac (NEED_KSBA_VERSION): Set to 0.9.0 due the changed - time interface. - -2003-10-21 Werner Koch - - * configure.ac (PRINTABLE_OS_NAME): Remove special case for The - Hurd; Robert Millan reported that the uname test is now - sufficient. - -2003-10-01 Werner Koch - - * configure.ac (AH_BOTTOM): Define GNUPG_MAJOR_VERSION. - -2003-09-23 Werner Koch - - Merged most of David Shaw's changes in 1.3 since 2003-06-03. - - * configure.ac: Drop all TIGER/192 support. - (uint64_t): Check for UINT64_C to go along with uint64_t. - (getaddrinfo): Check for it. - (sigset_t): Check for sigset_t and struct sigaction. This is for - Forte c89 on Solaris which seems to define only the function call - half of the two pairs by default. - (W32LIBS): Include wsock32 in W32LIBS. This is different from - NETLIBS so we don't need to force other platforms to pull in the - netlibs when they aren't actually needed. - -2003-09-06 Werner Koch - - Released 1.9.1. - - * configure.ac: Require newer versions of some libraries. - -2003-09-02 Werner Koch - - * configure.ac (HAVE_LIBUSB): Added a simple test for libusb. - -2003-08-19 Marcus Brinkmann - - * configure.ac (AM_PATH_GPG_ERROR): Add missing comma in - invocation. - -2003-08-06 Werner Koch - - * configure.ac: Check for libgpg-error. Print infos about missing - libraries more nicely. - * acinclude.m4 (AM_PATH_GPG_ERROR): Added. - -2003-08-05 Werner Koch - - Released 1.9.0. - - * configure.ac (GNUPG_DEFAULT_HONMEDIR): Changed back to ~/.gnupg. - -2003-07-31 Werner Koch - - * Makefile.am (DISTCLEANFILES): Add g10defs.h - -2003-06-18 Werner Koch - - * configure.ac (GNUPG_DEFAULT_HOMEDIR): Changed temporary to - .gnupg2 to avoid accidential use with production keys. - -2003-06-11 Werner Koch - - * configure.ac: Merged all stuff from current 1.3 version in. - * acinclude.m4: Merged required macros from current 1.2 version in. - -2003-06-04 Werner Koch - - * configure.ac, Makefile.am: Enable building of gpg. - -2003-04-29 Werner Koch - - * configure.ac: Build a limited version of scdaemon if libopensc - is not available. - - * configure.ac (ALL_LINUGAS): Removed. - - * Makefile.am (ACLOCAL_AMFLAGS): New. - * configure.ac (AM_GNU_GETTEXT_VERSION): New. Set to 0.11.5. - -2003-04-29 gettextize - - * Makefile.am (SUBDIRS): Add m4. - (ACLOCAL_AMFLAGS): New variable. - (EXTRA_DIST): Add scripts/config.rpath. - * configure.ac (AC_CONFIG_FILES): Add m4/Makefile. - -2003-04-29 Werner Koch - - * assuan/ : Removed. We now use libassuan. - * Makefile.am (SUBDIRS): Removed assuan - - * configure.ac: Check for libassuan. - -2003-01-09 Werner Koch - - * configure.ac (GNUPG_PROTECT_TOOL): New option --with-protect-tool. - (NEED_KSBA_VERSION): Does now require 0.4.6. - - * README: Noted where to find gpg-protect-tool. - -2002-10-31 Neal H. Walfield - - * configure.ac: Check for flockfile and funlockfile. Check for - isascii and putc_unlocked replacing them if not found. - - * configure.ac (PTH_LIBS): If pth is found, add the output of - `$PTH_CONFIG --ldflags`, not just `$PTH_CONFIG --libs`. - -2002-10-19 Werner Koch - - * configure.ac: Bumped version number to 1.9.0-cvs. - - NewPG (Aegypten project) to GnuPG merge. - -2002-09-20 Werner Koch - - Released 0.9.2. - -2002-09-05 Neal H. Walfield - - * configure.ac: Check for makeinfo. - -2002-09-03 Neal H. Walfield - - * autogen.sh (have_version): New function. Generalize and - simplify logic for finding and determining the versions of GNU - programs. Use it. - -2002-08-23 Werner Koch - - Released 0.9.1. - - * acinclude.m4 (AM_PATH_LIBGCRYPT): Updated from Libgcrypt. - (AM_PATH_OPENSC): Strip non-digits from the micro version. - -2002-08-21 Werner Koch - - Released 0.9.0. - - * configure.ac: Changed the default homedir to .gnupg. - * README-alpha: Removed. - -2002-08-19 Werner Koch - - * acinclude.m4: Removed -lpcsclite from KSBA_LIBS; copy+paste bug. - -2002-08-13 Werner Koch - - * acinclude.m4 (AM_PATH_OPENSC, AM_PATH_KSBA): New. - * configure.ac: Use them. - -2002-08-10 Werner Koch - - Released 0.3.10. - - * configure.ac (NEED_LIBKSBA_VERSION): Require 0.4.4. Add support - for gettext. - -2002-07-22 Werner Koch - - * configure.ac: Check for ftello and provide a replacement. - -2002-07-01 Werner Koch - - Released 0.3.9. - - * README: Short note on how to export in pkcs-12 format. - -2002-06-29 Werner Koch - - * configure.ac: Define --with options to set the default location - of the agent, scdaemon, pinentry and dirmngr. - -2002-06-27 Werner Koch - - * README: Short blurb on how to import a PKCS-12 file. - - * configure.ac (AH_BOTTOM): New to define some constants. - -2002-06-25 Werner Koch - - Released 0.3.8. - - * configure.ac (NEED_LIBGCRYPT_VERSION): Set to 1.1.8. - -2002-06-12 Werner Koch - - * configure.ac (NEED_LIBKSBA_VERSION): We need 0.4.3 now. - -2002-06-04 Werner Koch - - Released 0.3.7. - -2002-05-21 Werner Koch - - * configure.ac: We now require libgcrypt 1.1.7 and libksba 0.4.2. - -2002-05-14 Werner Koch - - * doc/: New - * configure.ac, Makefile.am: Added doc/ - -2002-05-03 Werner Koch - - Released 0.3.6. - -2002-04-25 Werner Koch - - * configure.ac: Check for setlocale. - -2002-04-24 Marcus Brinkmann - - * configure.ac: Check for locale.h. - -2002-04-15 Werner Koch - - Released 0.3.5. - - * NEWS: Started to describe release notes. - - * configure.ac (NEED_LIBKSBA_VERSION, NEED_LIBGCRYPT_VERSION): Defined - -2002-04-01 Werner Koch - - Released 0.3.4. - -2002-03-18 Werner Koch - - Released 0.3.3. - -2002-03-08 Werner Koch - - * README: Add some explanation on how to specify a user ID. - -2002-03-06 Werner Koch - - Released 0.3.2. - -2002-03-04 Werner Koch - - Released 0.3.1. - - * README: Explained some options and files. - -2002-02-14 Werner Koch - - * configure.ac: Fixed status messages related to presence of Pth. - -2002-02-13 Werner Koch - - * acinclude.m4 (GNUPG_SYS_SO_PEERCRED): New. - * configure.ac: use it. - -2002-02-12 Werner Koch - - * configure.ac: Check for PTH. Provide replacement fucntions for - apsrintf and fopencookie. - - * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): New. - -2002-02-07 Werner Koch - - Released 0.3.0. - - * configure.ac: Require libgcrypt 1.1.6. - -2002-02-01 Marcus Brinkmann - - * configure.ac (KSBA_CONFIG): Remove superfluous x in front of - variable. - -2002-01-26 Werner Koch - - * configure.ac: Add options to disable the build of some programs - and print a configure status at the end. - * acinclude.m4 (GNUPG_BUILD_PROGRAM): New. - - * scd/ : New. Added to Makefile and configure. - * configure.ac: Check for libopensc - * Makefile.am: Build scd only when libopensc is available - -2002-01-23 Werner Koch - - * configure.ac (mkdtemp): See whether we have to provide a - replacement. - -2001-12-18 Werner Koch - - Released 0.0.0. - -2001-12-17 Werner Koch - - * acinclude.m4: Add AM_PATH_LIBGCRYPT macro. - * configure.ac: and use it here. Figure out the location of libksba - -2001-12-15 Werner Koch - - * configure.ac (missing_dir): Bail out if asprintf and fopencookie - are not available. - -2001-12-04 Werner Koch - - * configure.ac (HAVE_JNLIB_LOGGING): always define it. - - - Copyright 2001, 2002, 2004 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. - - diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 54caf7c19..000000000 --- a/INSTALL +++ /dev/null @@ -1,229 +0,0 @@ -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software -Foundation, Inc. - - This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - - These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is -disabled by default to prevent problems with accidental use of stale -cache files.) - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. - -Installation Names -================== - - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the `--target=TYPE' option to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -will cause the specified gcc to be used as the C compiler (unless it is -overridden in the site shell script). - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 8f7d1771c..000000000 --- a/Makefile.am +++ /dev/null @@ -1,64 +0,0 @@ -# Makefile.am - main makefile for NewPG/GnuPG -# Copyright (C) 2001 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -ACLOCAL_AMFLAGS = -I m4 - -EXTRA_DIST = scripts/config.rpath autogen.sh README.CVS -DISTCLEANFILES = g10defs.h - -if BUILD_GPG -gpg = g10 -else -gpg = -endif -if BUILD_GPGSM -sm = sm -else -sm = -endif -if BUILD_AGENT -agent = agent -else -agent = -endif -if BUILD_SCDAEMON -scd = scd -else -scd = -endif - -SUBDIRS = m4 intl jnlib common kbx \ - ${gpg} ${sm} ${agent} ${scd} tools po doc tests - -dist-hook: - @set -e; \ - for file in `cd $(top_srcdir); \ - find scripts include -type f -name distfiles`; do \ - dir=`dirname $$file` ; $(mkinstalldirs) $(distdir)/$$dir ; \ - for i in distfiles `cat $(top_srcdir)/$$file` ; do \ - ln $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i 2> /dev/null \ - || cp -p $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i; \ - done ; \ - done - echo "$(VERSION)" > $(distdir)/VERSION - - - diff --git a/NEWS b/NEWS deleted file mode 100644 index 3d9b4ca34..000000000 --- a/NEWS +++ /dev/null @@ -1,171 +0,0 @@ -Noteworthy changes in version 1.9.10 ------------------------------------------------- - - -Noteworthy changes in version 1.9.9 (2004-06-08) ------------------------------------------------- - - * [gpg-agent] The new option --allow-mark-trusted is now required to - allow gpg-agent to add a key to the trustlist.txt after user - confirmation. - - * Creating PKCS#10 requests does now honor the key usage. - - -Noteworthy changes in version 1.9.8 (2004-04-29) ------------------------------------------------- - - * [scdaemon] Overhauled the internal CCID driver. - - * [scdaemon] Status files named ~/.gnupg/reader_.status are now - written when using the internal CCID driver. - - * [gpgsm] New commands --dump-{,secret,external}-keys to show a very - detailed view of the certificates. - - * The keybox gets now compressed after 3 hours and ephemeral - stored certificates are deleted after about a day. - - * [gpg] Usability fixes for --card-edit. Note, that this has already - been ported back to gnupg-1.3 - - -Noteworthy changes in version 1.9.7 (2004-04-06) ------------------------------------------------- - - * Instrumented the modules for gpgconf. - - * Added support for DINSIG card applications. - - * Include the smimeCapabilities attribute with signed messages. - - * Now uses the gettext domain "gnupg2" to avoid conflicts with gnupg - versions < 1.9. - - -Noteworthy changes in version 1.9.6 (2004-03-06) ------------------------------------------------- - - * Code cleanups and bug fixes. - - -Noteworthy changes in version 1.9.5 (2004-02-21) ------------------------------------------------- - - * gpg-protect-tool gets now installed into libexec as it ought to be. - Cleaned up the build system to better comply with the coding - standards. - - * [gpgsm] The --import command is now able to autodetect pkcs#12 - files and import secret and private keys from this file format. - A new command --export-secret-key-p12 is provided to allow - exporting of secret keys in PKCS\#12 format. - - * [gpgsm] The pinentry will now present a description of the key for - whom the passphrase is requested. - - * [gpgsm] New option --with-validation to check the validity of key - while listing it. - - * New option --debug-level={none,basic,advanced,expert,guru} to map - the debug flags to sensitive levels on a per program base. - - -Noteworthy changes in version 1.9.4 (2004-01-30) ------------------------------------------------- - - * Added support for the Telesec NKS 2.0 card application. - - * Added simple tool addgnupghome to create .gnupg directories from - /etc/skel/.gnupg. - - * Various minor bug fixes and cleanups; mainly gpgsm and gpg-agent - related. - - -Noteworthy changes in version 1.9.3 (2003-12-23) ------------------------------------------------- - - * New gpgsm options --{enable,disable}-ocsp to validate keys using - OCSP. This option requires a not yet released DirMngr version. - Default is disabled. - - * The --log-file option may now be used to print logs to a socket. - Prefix the socket name with "socket://" to enable this. This does - not work on all systems and falls back to stderr if there is a - problem with the socket. - - * The options --encrypt-to and --no-encrypt-to now work the same in - gpgsm as in gpg. Note, they are also used in server mode. - - * Duplicated recipients are now silently removed in gpgsm. - - -Noteworthy changes in version 1.9.2 (2003-11-17) ------------------------------------------------- - - * On card key generation is no longer done using the --gen-key - command but from the menu provided by the new --card-edit command. - - * PINs are now properly cached and there are only 2 PINs visible. - The 3rd PIN (CHV2) is internally syncronized with the regular PIN. - - * All kind of other internal stuff. - - -Noteworthy changes in version 1.9.1 (2003-09-06) ------------------------------------------------- - - * Support for OpenSC is back. scdaemon supports a --disable-opensc to - disable OpenSC use at runtime, so that PC/SC or ct-API can still be - used directly. - - * Rudimentary support for the SCR335 smartcard reader using an - internal driver. Requires current libusb from CVS. - - * Bug fixes. - - -Noteworthy changes in version 1.9.0 (2003-08-05) ------------------------------------------------- - - ====== PLEASE SEE README-alpha ======= - - * gpg has been renamed to gpg2 and gpgv to gpgv2. This is a - temporary change to allow co-existing with stable gpg versions. - - * ~/.gnupg/gpg.conf-1.9.0 is fist tried as config file before the - usual gpg.conf. - - * Removed the -k, -kv and -kvv commands. -k is now an alias to - --list-keys. New command -K as alias for --list-secret-keys. - - * Removed --run-as-shm-coprocess feature. - - * gpg does now also use libgcrypt, libgpg-error is required. - - * New gpgsm commands --call-dirmngr and --call-protect-tool. - - * Changing a passphrase is now possible using "gpgsm --passwd" - - * The content-type attribute is now recognized and created. - - * The agent does now reread certain options on receiving a HUP. - - * The pinentry is now forked for each request so that clients with - different environments are supported. When running in daemon mode - and --keep-display is not used the DISPLAY variable is ignored. - - * Merged stuff from the newpg branch and started this new - development branch. - - - Copyright 2002, 2003 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. diff --git a/README b/README deleted file mode 100644 index 5b4a69027..000000000 --- a/README +++ /dev/null @@ -1,511 +0,0 @@ - The GNU Privacy Guard 2 - ========================= - Version 1.9.x - - -GnuPG 1.9 is the future version of GnuPG; it is based on the gnupg-1.3 -code and the previous newpg package. It will eventually lead to a -GnuPG 2.0 release. Note that GnuPG 1.3 and 1.9 are not always in sync -and thus features and bug fixes done in 1.3 are not necessary -available in 1.9. - - -BUILD INSTRUCTIONS -================== - -GnuPG 1.9 depends on the following packages: - - libgpg-error (ftp://ftp.gnupg.org/gcrypt/alpha/libgpg-error/) - libgcrypt (ftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/) - libassuan (ftp://ftp.gnupg.org/gcrypt/alpha/libassuan/) - libksba (ftp://ftp.gnupg.org/gcrypt/alpha/libksba/) - -You also need the pinentry package for most function of GnupG; however -it is not a build requirement. pinentry is available at -ftp://ftp.gnupg.org/gcrypt/pinentry/ . - -You should get the latest versions of course, the GnuPG configure -script complains if a version is not sufficient. - -After building and installing the above packages in the order as given -above, you may now continue with GnupG installation (you may also just -try to build GnuPG to see whether your already installed versions are -sufficient). - -As with all packages, you just have to do - - ./configure - make - make install - -(Before doing install you might need to become root.) - -If everything succeeds, you have a working GnuPG with support for -S/MIME and smartcards. Note that there is no binary gpg but a gpg2 so -that this package won't confict with a GnuPG 1.2 or1.3 -installation. gpg2 behaves just like gpg and it is possible to symlink -oto gpg if you want to use gpg 1.9. - -In case of problem please ask on gpa-dev@gnupg.org for advise. Note -that this release is only expected to build on GNU and *BSD systems. - -A texinfo manual named `gnupg.info' will get installed. Some commands -and options given below. See also the section `SMARTCARD INTRO'. - - -COMMANDS -======== - -gpgsm: ------- - ---learn-card - - Read information about the private keys from the smartcard and - import the certificates from there. - ---export - - Export all certificates stored in the Keybox or those specified on - the command line. When using --armor a few informational lines are - prepended before each block. - - -gpg2: ------ - ---card-status - - Show information pertaining smartcards implementing the OpenPGP - application. - ---change-pin - - Offers a menu to change the PIN of OpenPGP smartcards and to reset - the retry counters. - ---card-edit - - Offers a menu to change any data object on the card and to generate - the keys. - - -OPTIONS -======= - -gpgsm: ------- - ---include-certs - - Using N of -2 includes all certificate except for the Root cert, - -1 includes all certs, 0 does not include any certs, 1 includes only - the signers cert (this is the default) and all other positives - values include up to N certs starting with the signer cert. - ---policy-file - - Chnage the deault name of the policy file - ---enable-policy-checks ---disable-policy-checks - - By default policy checks are enabled. These options may be used to - change it. - ---enable-crl-checks ---disable-crl-checks - - By default the CRL checks are enabled and the DirMngr is used to - check for revoked certificates. The disable option is most useful - with a off-line connection to suppres this check. - ---agent-program - - Specify an agent program to be used for secret key operations. The - default value is "../agent/gpg-agent". This is only used as a - fallback when the envrionment varaibale GPG_AGENT_INFO is not set or - a running agent can't be connected. - ---dirmngr-program - - Specify a dirmngr program to be used for CRL checks. The default - value is "/usr/sbin/dirmngr". This is only used as a fallback when - the environment varaibale DIRMNGR_INFO is not set or a running - dirmngr can't be connected. - ---no-secmem-warning - - Don't print the warning "no secure memory" - ---armor - - Create PEM ecoded output. Default is binary output. - ---base64 - - Create Base-64 encoded output; i.e. PEM without the header lines. - ---assume-armor - - Assume the input data is PEM encoded. Default is to autodetect the - encoding but this is may fail. - ---assume-base64 - - Assume the input data is plain base-64 encoded. - ---assume-binary - - Assume the input data is binary encoded. - ---server - - Run in server mode. This is used by GPGME to control gpgsm. See - the assuan specification regarding gpgsm about the used protocol. - Some options are ignored in server mode. - ---local-user - - Set the user to be used for signing. The default is the first - secret key found in the database. - ---with-key-data - - Displays extra information with the --list-keys commands. Especially - a line tagged "grp" is printed which tells you the keygrip of a - key. This is string is for example used as the filename of the - secret key. - - - -gpg-agent: ---------- - ---pinentry-program - - Specify the PINentry program. The default value is - "/bin/pinentry" so you most likely want to specify it. - ---no-grab - - Tell the pinentry not to grab keybourd and mouse. You most likely - want to give this option during testing and development to avoid - lockups in case of bugs. - - -scdaemon: --------- - ---ctapi-driver - - The default for Scdaemon is to use the PC/SC API currently provided - by libpcsclite.so. As an alternative the ctAPI can be used by - specify this option with the appropriate driver name - (e.g. libtowitoko.so). - ---reader-port - - This specifies the port of the chipcard reader. For PC/SC this is - currently ignored and the first PC/SC reader is used. For the - ctAPI, a number must be specified (the default is 32768 for the - first USB port). - ---disable-ccid - - Disable the integrated support for CCID compliant readers. This - allows to fall back to one of the other drivers even if the internal - CCID driver can handle the reader. Note, that CCID support is only - available if libusb was available at build time. - - -FILES -===== - -The default home directory is ~/.gnupg. It can be changed by -either the --homedir option or by seting the environment variable -GNUPGHOME. This is a list of files usually found in this directory: - -gpgsm.conf - - Options for gpgsm. Options are the same as the command line - options but don't enter the leading dashes and give arguments - without an equal sign. Blank lines and lines starting with a - hash mark as the first non whitye space character are ignored. - -gpg-agent.conf - - Options for gpg-agent - -scdaemon.conf - - Options for scdaemon. - -dirmngr.conf - - Options for the DirMngr which is not part of this package and - the option file wilol most likely be moved to /etc - -gpg.conf - - Options for gpg. Note that old versions of gpg use the - filename `options' instead of `gpg.conf'. - -gpg.conf-1.9.x - - Options for gpg; tried before gpg.conf - - -policies.txt - - A list of allowed CA policies. This file should give the - object identifiers of the policies line by line. Empty lines - and lines startung with a hash mark are ignored. - - ++++++++++ - 2.289.9.9 - ++++++++++ - -trustlist.txt - - A list of trusted certificates usually maintained by - gpg-agent. It can however be edited manually. The file will - be created automagically with some explaining comments. - -random_seed - - Used internally for keeping the state of the RNG over - invocations. - -pubring.kbx - - The database file with the certificates. - -pubring.gpg - - The database file with the OpenPGP public keys. This will - eventually be merged with pubring.kbx - -secring.gpg - - The database file with the OpenPGP secret keys. This will be - removed when gpg is changed to make use of the gpg-agent. - - -private-keys-v1.d/ - - Directory holding the private keys maintained by gpg-agent. - For detailed info see agent/keyformat.txt. Note that there is - a helper tool gpg-protect-tool which may be used to protect or - unprotect keys. This is however nothing a user should care - about. - - -SOURCE FILES -============ - -Here is a list of directories with source files: - -jnlib/ utility functions -kbx/ keybox library -g10/ the gpg program here called gpg2 -sm/ the gpgsm program -agent/ the gpg-agent -scd/ the smartcard daemon -doc/ documentation - - - -HOW TO SPECIFY A USER ID -======================== - -Due to the way X.509 certificates are made up we need a few new ways -to specify a certificate (aka key in OpenPGP). In addition to the -ways a user ID can be specified with gpg, I have implemented 3 new -modes for gpgsm, here is the entire list of ways to specify a key: - - * By keyID. - - This format is deducded from the length of the string and its - content or "0x" prefix. For use with OpenPGP a exclamation mark may - be appended to force use of the specified (sub)key. - - As with v34 OpenPGP keys, the keyID of an X509 certificate are the - low 64 bits of the SHA-1 fingerprint. The use of keyIDs is just a - shortcut, for all automated processing the fingerprint should be - used. - - Examples: - - 234567C4 - 0F34E556E - 01347A56A - 0xAB123456 - - 234AABBCC34567C4 - 0F323456784E56EAB - 01AB3FED1347A5612 - 0x234AABBCC34567C4 - - * By fingerprint - - This is format is deduced from the length of the string and its - content or "0x" prefix. Note, that only the 20 byte fingerprint is - used with GPGSM (SHA-1 hash of the certificate). For use with - OpenPGP a exclamation mark may be appended to force use of the - specified (sub)key. - - Examples: - - 1234343434343434C434343434343434 - 123434343434343C3434343434343734349A3434 - 0E12343434343434343434EAB3484343434343434 - 0xE12343434343434343434EAB3484343434343434 - - * Exact match on OpenPGP user ID - - This is denoted by a leading equal sign. It does not make much - sense for X.509. - - Example: - - =Heinrich Heine - - * Exact match on an email address. - - This is indicated by enclosing the email address in the usual way - with left and right angles - - Example: - - - - * Word match - - All words must match exactly (not case sensitive) but can appear in - any order in the user ID or a subjects name. Words are any - sequences of letters, digits, the underscore and all characters - with bit 7 set. - - Example: - - +Heinrich Heine duesseldorf - - * [NEW] Exact match by subject's DN - - This is indicated by a leading slash, directly followed by the - rfc2253 encoded DN of the subject. Note that you can't use the - string printed by "gpgsm --list-keys" because that one as been - reordered and modified for better readability; use --with-colons to - print the raw (but standard escaped) rfc2253 string - - Example: - - /CN=Heinrich Heine,O=Poets,L=Paris,C=FR - - * [NEW] Excact match by issuer's DN - - This is indicated by a leading hash mark, directly followed by a - slash and then directly followed by the rfc2253 encoded DN of the - issuer. This should return the Root cert of the issuer. See note - above. - - Example: - - #/CN=Root Cert,O=Poets,L=Paris,C=FR - - * [NEW] Exact match by serial number and subject's DN - - This is indicated by a hash mark, followed by the hexadecmal - representation of the serial number, the followed by a slahs and - the RFC2253 encoded DN of the issuer. See note above. - - Example: - - #4F03/CN=Root Cert,O=Poets,L=Paris,C=FR - - * Substring match - - By case insensitive substring matching. This is the default mode - but applications may want to explicitly indicate this by putting - the asterisk in front. - - Example: - - Heine - *Heine - - -Please note that we have reused the hash mark indentifier which was -used in old GnuPG versions to indicate the so called local-id. It is -not anymore used and there should be no conflict when used with X.509 -stuff. - -Using the rfc2253 format of DNs has the drawback that it is not -possible to map them back to the original encoding, however we don't -have to do this, because our key database stores this encoding as meta -data. - -Some of the search modes are not yet implemented ;-) - - -HOW TO IMPORT A PRIVATE KEY -=========================== -There is some limited support to import a private key from a PKCS-12 -file. - - gpgsm --import foo.p12 - -This require that the gpg-agent is running. - - -HOW TO EXPORT A PRIVATE KEY -=========================== -There is also limited support to export a private key in PKCS-12 -format. However the certificate is not stored and there is no MAC applied. - - gpgsm --call-protect-tool --p12-export foo.key >foo.p12 - - -SMARTCARD INTRO -=============== - -GPG, the OpenPGP part of GnuPG, supports the OpenPGP smartcard -(surprise!); see http://g10code.com/p-card.html. - -[Fixme: We need to explain this further] - - -GPGSM, the CMS (S/MIME) part of GnuPG, supports two kinds of -smartcards. The most flexible way is to use PKCS#15 compliant cards, -however you must have build GnuPG with support for the OpenSC library. -The build process automagically detects the presence of this library -and will include support for these cards. - -The other card we currently support is the Telesec NetKey card with -the NKS 2.0 card application. - -Before GPGSM can make use of a new card it must gather some -information, like the card's serial number, the public keys and the -certificates stored on the card. Thus for a new card you need to run -the command - - gpgsm --learn-card - -once. This is also a good test to see whether your card reader is -properly installed. See below in case of error. Once this has been -done you may use the keys stored on the card in the same way you use -keys stored on the disk. gpgsm automagically knows whether a card is -required and will pop up the pinentry to ask you to insert the -correct card. - -For selecting the driver, see the options of scdaemon. A useful -debugging flag is "--debug 2048" showing the communication between -scdaemon and the reader. - -[fixme: write more stuff] - - - - - diff --git a/README.CVS b/README.CVS deleted file mode 100644 index ae17923bd..000000000 --- a/README.CVS +++ /dev/null @@ -1,51 +0,0 @@ -If you are building from CVS, run the script - -./autogen.sh - -first, to make sure that you have all the necessary maintainer tools -are installed and to build the actual configuration files. Then run - -./configure --enable-maintainer-mode - -followed by the usual make. - -If autogen.sh complains about insufficient versions of the required -tools, or the tools are not installed, you may use environment -variables to override the default tool names: - - AUTOMAKE_SUFFIX is used as a suffix for all tools from the automake - package. For example - AUTOMAKE_SUFFIX="-1.7" ./autogen.sh - uses "automake-1.7" and "aclocal-1.7. - AUTOMAKE_PREFIX is used as a prefix for all tools from the automake - page and may be combined with AUTOMAKE_SUFFIX. e.g.: - AUTOMAKE_PREFIX=/usr/foo/bin ./autogen.sh - uses "automake" and "aclocal" in the /usr/foo/bin - directory. - AUTOCONF_SUFFIX is used as a suffix for all tools from the automake - package - AUTOCONF_PREFIX is used as a prefix for all tools from the automake - package - GETTEXT_SUFFIX is used as a suffix for all tools from the gettext - package - GETTEXT_PREFIX is used as a prefix for all tools from the gettext - package - -It is also possible to use the variable name AUTOMAKE, AUTOCONF, -ACLOCAL, AUTOHEADER, GETTEXT and MSGMERGE to directly specify the name -of the programs to run. It is however better to use the suffix and -prefix forms as described above because that does not require -knowledge about the actual tools used by autgen.sh. - - -Please don't use autopoint, libtoolize or autoreconf unless you are -the current maintainer and want to update the standard configuration -files. All those files should be in the CVS and only updated manually -if the maintainer decides that newer versions are required. The -maintainer should also make sure that the required version of automake -et al. are properly indicated at the top of configure.ac and take care -to copy the files and not merely use symlinks. - - - - diff --git a/THANKS b/THANKS deleted file mode 100644 index 3f56e29d3..000000000 --- a/THANKS +++ /dev/null @@ -1,5 +0,0 @@ - - -Richard Lefebvre rick at CERCA.UMontreal.CA -Andrew J. Schorr aschorr at telemetry-investments.com -Michael Nottebrock michaelnottebrock at gmx.net diff --git a/TODO b/TODO deleted file mode 100644 index f22a19b41..000000000 --- a/TODO +++ /dev/null @@ -1,78 +0,0 @@ - -*- outline -*- - -* src/base64 -** Make parsing more robust -Currently we don't cope with overlong lines in the best way. - -* sm/call-agent.c -** The protocol uses an incomplete S-expression -We should always use valid S-Exp and not just parts. -** Some code should go into import.c -** When we allow concurrent service request in gpgsm, we -might want to have an agent context for each service request -(i.e. Assuan context). - -* sm/certreqgen.c -** Improve error reporting -** Do some basic checks on the supplied DNs - -* sm/certchain.c -** When a certificate chain was sucessfully verified, make ephemeral certs used in this chain permanent. -** figure out how to auto retrieve a key by serialno+issuer. - Dirmngr is currently not able to parse more than the CN. - -* sm/decrypt.c -** replace leading zero in integer hack by a cleaner solution - -* sm/gpgsm.c -** Support --output for all commands -** mark all unimplemented commands and options. -** Print a hint when MD2 is the cause for a problem. -** Implement --default-key -** Using --export-secret-key-p12 with a non-pth agent - This leads to a lockup because gpgsm is still accessing the agent - while gpg-protect-tool wants to pop up the pinentry. Solution is - to release the connection. This is not trivial, thus we are going - to do that while changing gpgsm to allow concurrent operations. - -* sm/keydb.c -** Check file permissions -** Check that all error code mapping is done. -** Remove the inter-module dependencies between gpgsm and keybox -** Add an source_of_key field - -* agent/gpg-agent.c -** A SIGHUP should also restart the scdaemon - But do this only after all connections terminated. - As of now we only send a RESET. - -* agent/command.c -** Make sure that secure memory is used where appropriate - -* agent/pkdecrypt.c, agent/pksign.c -** Don't use stdio to return results. - -* agent/divert-scd.c - Remove the agent_reset_scd kludge. - -* Move pkcs-1 encoding into libgcrypt. - -* Use a MAC to protect some files. - -* sm/export.c -** Return an error code or a status info per user ID. - -* Where is http.c, regcomp.c, srv.c, w32reg.c ? - -* scd/sc-investigate -** Enhance with card compatibility check - -* tests -** Makefile.am - We use printf(1) to setup the library path, this is not portable. - Furthermore LD_LIBRARY_PATH is not used on all systems. It doesn't - matter for now, because we use some GNU/*BSDish features anyway. - -** Add a test to check the extkeyusage. - - diff --git a/acinclude.m4 b/acinclude.m4 deleted file mode 100644 index f6bbae78e..000000000 --- a/acinclude.m4 +++ /dev/null @@ -1,436 +0,0 @@ -dnl macros to configure gnupg -dnl Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. -dnl -dnl This file is part of GnuPG. -dnl -dnl GnuPG is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 2 of the License, or -dnl (at your option) any later version. -dnl -dnl GnuPG is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -dnl GNUPG_CHECK_TYPEDEF(TYPE, HAVE_NAME) -dnl Check whether a typedef exists and create a #define $2 if it exists -dnl -AC_DEFUN(GNUPG_CHECK_TYPEDEF, - [ AC_MSG_CHECKING(for $1 typedef) - AC_CACHE_VAL(gnupg_cv_typedef_$1, - [AC_TRY_COMPILE([#define _GNU_SOURCE 1 - #include - #include ], [ - #undef $1 - int a = sizeof($1); - ], gnupg_cv_typedef_$1=yes, gnupg_cv_typedef_$1=no )]) - AC_MSG_RESULT($gnupg_cv_typedef_$1) - if test "$gnupg_cv_typedef_$1" = yes; then - AC_DEFINE($2,1,[Defined if a `]$1[' is typedef'd]) - fi - ]) - - -dnl GNUPG_CHECK_GNUMAKE -dnl -AC_DEFUN(GNUPG_CHECK_GNUMAKE, - [ - if ${MAKE-make} --version 2>/dev/null | grep '^GNU ' >/dev/null 2>&1; then - : - else - AC_MSG_WARN([[ -*** -*** It seems that you are not using GNU make. Some make tools have serious -*** flaws and you may not be able to build this software at all. Before you -*** complain, please try GNU make: GNU make is easy to build and available -*** at all GNU archives. It is always available from ftp.gnu.org:/gnu/make. -***]]) - fi - ]) - -dnl GNUPG_CHECK_FAQPROG -dnl -AC_DEFUN(GNUPG_CHECK_FAQPROG, - [ AC_MSG_CHECKING(for faqprog.pl) - if faqprog.pl -V 2>/dev/null | grep '^faqprog.pl ' >/dev/null 2>&1; then - working_faqprog=yes - FAQPROG="faqprog.pl" - else - working_faqprog=no - FAQPROG=": " - fi - AC_MSG_RESULT($working_faqprog) - AC_SUBST(FAQPROG) - AM_CONDITIONAL(WORKING_FAQPROG, test "$working_faqprog" = "yes" ) - -dnl if test $working_faqprog = no; then -dnl AC_MSG_WARN([[ -dnl *** -dnl *** It seems that the faqprog.pl program is not installed; -dnl *** however it is only needed if you want to change the FAQ. -dnl *** (faqprog.pl should be available at: -dnl *** ftp://ftp.gnupg.org/gcrypt/contrib/faqprog.pl ) -dnl *** No need to worry about this warning. -dnl ***]]) -dnl fi - ]) - -dnl GNUPG_CHECK_DOCBOOK_TO_TEXI -dnl -AC_DEFUN(GNUPG_CHECK_DOCBOOK_TO_TEXI, - [ - AC_CHECK_PROG(DOCBOOK_TO_TEXI, docbook2texi, yes, no) - AC_MSG_CHECKING(for sgml to texi tools) - working_sgmltotexi=no - if test "$ac_cv_prog_DOCBOOK_TO_TEXI" = yes; then - if sgml2xml -v /dev/null 2>&1 | grep 'SP version' >/dev/null 2>&1 ; then - working_sgmltotexi=yes - fi - fi - AC_MSG_RESULT($working_sgmltotexi) - AM_CONDITIONAL(HAVE_DOCBOOK_TO_TEXI, test "$working_sgmltotexi" = "yes" ) - ]) - - - -dnl GNUPG_CHECK_ENDIAN -dnl define either LITTLE_ENDIAN_HOST or BIG_ENDIAN_HOST -dnl -define(GNUPG_CHECK_ENDIAN, - [ - tmp_assumed_endian=big - if test "$cross_compiling" = yes; then - case "$host_cpu" in - i@<:@345678@:>@* ) - tmp_assumed_endian=little - ;; - *) - ;; - esac - AC_MSG_WARN(cross compiling; assuming $tmp_assumed_endian endianess) - fi - AC_MSG_CHECKING(endianess) - AC_CACHE_VAL(gnupg_cv_c_endian, - [ gnupg_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], gnupg_cv_c_endian=big, gnupg_cv_c_endian=little)]) - if test "$gnupg_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); - }], - gnupg_cv_c_endian=little, - gnupg_cv_c_endian=big, - gnupg_cv_c_endian=$tmp_assumed_endian - ) - fi - ]) - AC_MSG_RESULT([$gnupg_cv_c_endian]) - if test "$gnupg_cv_c_endian" = little; then - AC_DEFINE(LITTLE_ENDIAN_HOST,1, - [Defined if the host has little endian byte ordering]) - else - AC_DEFINE(BIG_ENDIAN_HOST,1, - [Defined if the host has big endian byte ordering]) - fi - ]) - - - -# Check for the getsockopt SO_PEERCRED -AC_DEFUN(GNUPG_SYS_SO_PEERCRED, - [ AC_MSG_CHECKING(for SO_PEERCRED) - AC_CACHE_VAL(gnupg_cv_sys_so_peercred, - [AC_TRY_COMPILE([#include ], - [struct ucred cr; - int cl = sizeof cr; - getsockopt (1, SOL_SOCKET, SO_PEERCRED, &cr, &cl);], - gnupg_cv_sys_so_peercred=yes, - gnupg_cv_sys_so_peercred=no) - ]) - AC_MSG_RESULT($gnupg_cv_sys_so_peercred) - if test $gnupg_cv_sys_so_peercred = yes; then - AC_DEFINE(HAVE_SO_PEERCRED, 1, - [Defined if SO_PEERCRED is supported (Linux)]) - fi - ]) - - - -# GNUPG_BUILD_PROGRAM(NAME,DEFAULT) -# Add a --enable-NAME option to configure an set the -# shell variable build_NAME either to "yes" or "no". DEFAULT must -# either be "yes" or "no" and decided on the default value for -# build_NAME and whether --enable-NAME or --disable-NAME is shown with -# ./configure --help -AC_DEFUN(GNUPG_BUILD_PROGRAM, - [build_$1=$2 - m4_if([$2],[yes],[ - AC_ARG_ENABLE([$1], AC_HELP_STRING([--disable-$1], - [do not build the $1 program]), - build_$1=$enableval, build_$1=$2) - ],[ - AC_ARG_ENABLE([$1], AC_HELP_STRING([--enable-$1], - [build the $1 program]), - build_$1=$enableval, build_$1=$2) - ]) - case "$build_$1" in - no|yes) - ;; - *) - AC_MSG_ERROR([only yes or no allowed for feature --enable-$1]) - ;; - esac - ]) - - - -# GNUPG_PTH_VERSION_CHECK(REQUIRED) -# -# If the version is sufficient, HAVE_PTH will be set to yes. -# -# Taken form the m4 macros which come with Pth -AC_DEFUN(GNUPG_PTH_VERSION_CHECK, - [ - _pth_version=`$PTH_CONFIG --version | awk 'NR==1 {print [$]3}'` - _req_version="ifelse([$1],,1.2.0,$1)" - for _var in _pth_version _req_version; do - eval "_val=\"\$${_var}\"" - _major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\1/'` - _minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\2/'` - _rtype=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\3/'` - _micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\4/'` - case $_rtype in - "a" ) _rtype=0 ;; - "b" ) _rtype=1 ;; - "." ) _rtype=2 ;; - esac - _hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \ - "major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"` - eval "${_var}_hex=\"\$_hex\"" - done - have_pth=no - if test ".$_pth_version_hex" != .; then - if test ".$_req_version_hex" != .; then - if test $_pth_version_hex -ge $_req_version_hex; then - have_pth=yes - fi - fi - fi - if test $have_pth = no; then - AC_MSG_WARN([[ -*** -*** Found Pth version $_pth_version, but require at least -*** version $_req_version. Please upgrade Pth first. -***]]) - fi - ]) - - -# Check whether mlock is broken (hpux 10.20 raises a SIGBUS if mlock -# is not called from uid 0 (not tested whether uid 0 works) -# For DECs Tru64 we have also to check whether mlock is in librt -# mlock is there a macro using memlk() -dnl GNUPG_CHECK_MLOCK -dnl -define(GNUPG_CHECK_MLOCK, - [ AC_CHECK_FUNCS(mlock) - if test "$ac_cv_func_mlock" = "no"; then - AC_CHECK_HEADERS(sys/mman.h) - if test "$ac_cv_header_sys_mman_h" = "yes"; then - # Add librt to LIBS: - AC_CHECK_LIB(rt, memlk) - AC_CACHE_CHECK([whether mlock is in sys/mman.h], - gnupg_cv_mlock_is_in_sys_mman, - [AC_TRY_LINK([ - #include - #ifdef HAVE_SYS_MMAN_H - #include - #endif - ], [ - int i; - - /* glibc defines this for functions which it implements - * to always fail with ENOSYS. Some functions are actually - * named something starting with __ and the normal name - * is an alias. */ - #if defined (__stub_mlock) || defined (__stub___mlock) - choke me - #else - mlock(&i, 4); - #endif - ; return 0; - ], - gnupg_cv_mlock_is_in_sys_mman=yes, - gnupg_cv_mlock_is_in_sys_mman=no)]) - if test "$gnupg_cv_mlock_is_in_sys_mman" = "yes"; then - AC_DEFINE(HAVE_MLOCK,1, - [Defined if the system supports an mlock() call]) - fi - fi - fi - if test "$ac_cv_func_mlock" = "yes"; then - AC_MSG_CHECKING(whether mlock is broken) - AC_CACHE_VAL(gnupg_cv_have_broken_mlock, - AC_TRY_RUN([ - #include - #include - #include - #include - #include - #include - - int main() - { - char *pool; - int err; - long int pgsize = getpagesize(); - - pool = malloc( 4096 + pgsize ); - if( !pool ) - return 2; - pool += (pgsize - ((long int)pool % pgsize)); - - err = mlock( pool, 4096 ); - if( !err || errno == EPERM ) - return 0; /* okay */ - - return 1; /* hmmm */ - } - - ], - gnupg_cv_have_broken_mlock="no", - gnupg_cv_have_broken_mlock="yes", - gnupg_cv_have_broken_mlock="assume-no" - ) - ) - if test "$gnupg_cv_have_broken_mlock" = "yes"; then - AC_DEFINE(HAVE_BROKEN_MLOCK,1, - [Defined if the mlock() call does not work]) - AC_MSG_RESULT(yes) - AC_CHECK_FUNCS(plock) - else - if test "$gnupg_cv_have_broken_mlock" = "no"; then - AC_MSG_RESULT(no) - else - AC_MSG_RESULT(assuming no) - fi - fi - fi - ]) - - -dnl Stolen from gcc -dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead -dnl of the usual 2. -AC_DEFUN(GNUPG_FUNC_MKDIR_TAKES_ONE_ARG, -[AC_CHECK_HEADERS(sys/stat.h unistd.h direct.h) -AC_CACHE_CHECK([if mkdir takes one argument], gnupg_cv_mkdir_takes_one_arg, -[AC_TRY_COMPILE([ -#include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif -#ifdef HAVE_DIRECT_H -# include -#endif], [mkdir ("foo", 0);], - gnupg_cv_mkdir_takes_one_arg=no, gnupg_cv_mkdir_takes_one_arg=yes)]) -if test $gnupg_cv_mkdir_takes_one_arg = yes ; then - AC_DEFINE(MKDIR_TAKES_ONE_ARG,1, - [Defined if mkdir() does not take permission flags]) -fi -]) - - - - -dnl AM_PATH_OPENSC([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for OpenSC and define OPENSC_CFLAGS and OPENSC_LIBS -dnl -AC_DEFUN(AM_PATH_OPENSC, -[ AC_ARG_WITH(opensc-prefix, - AC_HELP_STRING([--with-opensc-prefix=PFX], - [prefix where OpenSC is installed (optional)]), - opensc_config_prefix="$withval", opensc_config_prefix="") - if test x$opensc_config_prefix != x ; then - opensc_config_args="$opensc_config_args --prefix=$opensc_config_prefix" - if test x${OPENSC_CONFIG+set} != xset ; then - OPENSC_CONFIG=$opensc_config_prefix/bin/opensc-config - fi - fi - - AC_PATH_PROG(OPENSC_CONFIG, opensc-config, no) - min_opensc_version=ifelse([$1], ,0.7.0,$1) - AC_MSG_CHECKING(for OpenSC - version >= $min_opensc_version) - ok=no - if test "$OPENSC_CONFIG" != "no" ; then - req_major=`echo $min_opensc_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` - req_minor=`echo $min_opensc_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - req_micro=`echo $min_opensc_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` - opensc_config_version=`$OPENSC_CONFIG $opensc_config_args --version 2>/dev/null || echo 0.0.0` - major=`echo $opensc_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $opensc_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - micro=`echo $opensc_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -gt "$req_minor"; then - ok=yes - else - if test "$minor" -eq "$req_minor"; then - if test "$micro" -ge "$req_micro"; then - ok=yes - fi - fi - fi - fi - fi - fi - if test $ok = yes; then - OPENSC_CFLAGS=`$OPENSC_CONFIG $opensc_config_args --cflags` - OPENSC_LIBS=`$OPENSC_CONFIG $opensc_config_args --libs` - OPENSC_LIBS="$OPENSC_LIBS -lpcsclite -lpthread" - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - OPENSC_CFLAGS="" - OPENSC_LIBS="" - AC_MSG_RESULT(no) - ifelse([$3], , :, [$3]) - fi - AC_SUBST(OPENSC_CFLAGS) - AC_SUBST(OPENSC_LIBS) -]) - - diff --git a/am/cmacros.am b/am/cmacros.am deleted file mode 100644 index 0f7a09fe0..000000000 --- a/am/cmacros.am +++ /dev/null @@ -1,45 +0,0 @@ -# cmacros.am - C macro definitions -# Copyright (C) 2004 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -localedir = $(datadir)/locale - -AM_CPPFLAGS += -DLOCALEDIR=\"$(localedir)\" - -if ! HAVE_DOSISH_SYSTEM -AM_CPPFLAGS += -DGNUPG_BINDIR="\"$(bindir)\"" \ - -DGNUPG_LIBEXECDIR="\"$(libexecdir)\"" \ - -DGNUPG_LIBDIR="\"$(libdir)/@PACKAGE@\"" \ - -DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\"" -endif - -if GNUPG_AGENT_PGM -AM_CPPFLAGS += -DGNUPG_DEFAULT_AGENT="\"@GNUPG_AGENT_PGM@\"" -endif -if GNUPG_PINENTRY_PGM -AM_CPPFLAGS += -DGNUPG_DEFAULT_PINENTRY="\"@GNUPG_PINENTRY_PGM@\"" -endif -if GNUPG_SCDAEMON_PGM -AM_CPPFLAGS += -DGNUPG_DEFAULT_SCDAEMON="\"@GNUPG_SCDAEMON_PGM@\"" -endif -if GNUPG_DIRMNGR_PGM -AM_CPPFLAGS += -DGNUPG_DEFAULT_DIRMNGR="\"@GNUPG_DIRMNGR_PGM@\"" -endif -if GNUPG_PROTECT_TOOL_PGM -AM_CPPFLAGS += -DGNUPG_DEFAULT_PROTECT_TOOL="\"@GNUPG_PROTECT_TOOL_PGM@\"" -endif diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index a607d63da..000000000 --- a/autogen.sh +++ /dev/null @@ -1,161 +0,0 @@ -#! /bin/sh -# Run this to generate all the initial makefiles, etc. -# -# Copyright (C) 2003 g10 Code GmbH -# -# 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 program 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. - -configure_ac="configure.ac" - -cvtver () { - awk 'NR==1 {split($NF,A,".");X=1000000*A[1]+1000*A[2]+A[3];print X;exit 0}' -} - -check_version () { - if [ `("$1" --version || echo "0") | cvtver` -ge "$2" ]; then - return 0 - fi - echo "**Error**: "\`$1\'" not installed or too old." >&2 - echo ' Version '$3' or newer is required.' >&2 - [ -n "$4" ] && echo ' Note that this is part of '\`$4\''.' >&2 - DIE="yes" - return 1 -} - -# Allow to override the default tool names -AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX} -AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX} - -AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX} -ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX} - -GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX} -MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX} - -DIE=no - -if [ "$1" = "--build-w32" ]; then - shift - target=i386--mingw32 - if [ ! -f ./config.guess ]; then - echo "./config.guess not found" >&2 - exit 1 - fi - host=`./config.guess` - - if ! mingw32 --version >/dev/null; then - echo "We need at least version 0.3 of MingW32/CPD" >&2 - exit 1 - fi - - if [ -f config.h ]; then - if grep HAVE_DOSISH_SYSTEM config.h | grep undef >/dev/null; then - echo "Pease run a 'make distclean' first" >&2 - exit 1 - fi - fi - - crossinstalldir=`mingw32 --install-dir` - crossbindir=`mingw32 --get-bindir 2>/dev/null` \ - || crossbindir="$crossinstalldir/bin" - crossdatadir=`mingw32 --get-datadir 2>/dev/null` \ - || crossdatadir="$crossinstalldir/share" - crosslibdir=`mingw32 --get-libdir 2>/dev/null` \ - || crosslibdir="$crossinstalldir/i386--mingw32/lib" - crossincdir=`mingw32 --get-includedir 2>/dev/null` \ - || crossincdir="$crossinstalldir/i386--mingw32/include" - CC=`mingw32 --get-path gcc` - CPP=`mingw32 --get-path cpp` - AR=`mingw32 --get-path ar` - RANLIB=`mingw32 --get-path ranlib` - export CC CPP AR RANLIB - - disable_foo_tests="" - if [ -n "$lib_config_files" ]; then - for i in $lib_config_files; do - j=`echo $i | tr '[a-z-]' '[A-Z_]'` - eval "$j=${crossbindir}/$i" - export $j - disable_foo_tests="$disable_foo_tests --disable-`echo $i| \ - sed 's,-config$,,'`-test" - if [ ! -f "${crossbindir}/$i" ]; then - echo "$i not installed for MingW32" >&2 - DIE=yes - fi - done - fi - [ $DIE = yes ] && exit 1 - - ./configure --host=${host} --target=${target} ${disable_foo_tests} \ - --bindir=${crossbindir} --libdir=${crosslibdir} \ - --datadir=${crossdatadir} --includedir=${crossincdir} \ - --enable-maintainer-mode $* - exit $? -fi - - - -# Grep the required versions from configure.ac -autoconf_vers=`sed -n '/^AC_PREREQ(/ { -s/^.*(\(.*\))/\1/p -q -}' ${configure_ac}` -autoconf_vers_num=`echo "$autoconf_vers" | cvtver` - -automake_vers=`sed -n '/^min_automake_version=/ { -s/^.*="\(.*\)"/\1/p -q -}' ${configure_ac}` -automake_vers_num=`echo "$automake_vers" | cvtver` - -gettext_vers=`sed -n '/^AM_GNU_GETTEXT_VERSION(/ { -s/^.*(\(.*\))/\1/p -q -}' ${configure_ac}` -gettext_vers_num=`echo "$gettext_vers" | cvtver` - - -if [ -z "$autoconf_vers" -o -z "$automake_vers" -o -z "$gettext_vers" ] -then - echo "**Error**: version information not found in "\`${configure_ac}\'"." >&2 - exit 1 -fi - - -if check_version $AUTOCONF $autoconf_vers_num $autoconf_vers ; then - check_version $AUTOHEADER $autoconf_vers_num $autoconf_vers autoconf -fi -if check_version $AUTOMAKE $automake_vers_num $automake_vers; then - check_version $ACLOCAL $automake_vers_num $autoconf_vers automake -fi -if check_version $GETTEXT $gettext_vers_num $gettext_vers; then - check_version $MSGMERGE $gettext_vers_num $gettext_vers gettext -fi - -if test "$DIE" = "yes"; then - cat < - - * xreadline.c: New. Based on the iobuf_read_line function. - -2004-05-12 Werner Koch - - * util.h (xtrycalloc_secure,xtrymalloc_secure): New. - -2004-05-11 Werner Koch - - * sysutils.c (disable_core_dumps): Only set the current limit. - (enable_core_dumps): New. - -2004-04-13 Werner Koch - - * simple-pwquery.c (copy_and_escape): Relaxed quoting. - -2004-04-05 Werner Koch - - * errors.h (STATUS_NEWSIG): New. - -2004-03-11 Werner Koch - - * dynload.h [__MINGW32__]: Define RTLD_LAZY. - -2004-03-09 Werner Koch - - * maperror.c (map_assuan_err): Map the Locale_Problem item. - -2004-03-03 Werner Koch - - * asshelp.c, asshelp.h: New. - (send_pinentry_environment): New. Code taken from ../sm/call-agent.c. - -2004-02-19 Werner Koch - - * simple-pwquery.c (agent_open): Don't mangle INFOSTR. - -2004-02-17 Werner Koch - - * simple-pwquery.c (agent_open): Ignore an empty GPG_AGENT_INFO. - - * errors.h: Added STATUS_IMPORT_OK. - -2004-02-10 Werner Koch - - * b64enc.c: New. Based on code from ../sm/base64.c. - -2004-01-30 Marcus Brinkmann - - * Makefile.am (libcommon_a_SOURCES): Add xasprintf.c. - * miscellaneous.c (xasprintf): Moved to ... - * xasprintf (xasprintf): ... here. New file. - This allows to use xasprintf without sucking in gpg-error. - -2004-01-27 Werner Koch - - * sexp-parse.h: New; moved from../agent. - - * util.h (xtoi_4): New. - -2003-12-23 Werner Koch - - * maperror.c (map_assuan_err): Prepared for a new error code. - -2003-12-17 Werner Koch - - * gettime.c (asctimestamp): Add a note on a non-avoidable gcc warning. - - * util.h [!HAVE_VASPRINTF]: Add printf format attribute to the - replacement function. - - * miscellaneous.c (xasprintf): New. - -2003-11-14 Werner Koch - - * mkdtemp.c (mkdtemp): Use gcry_create_nonce. - - * cryptmiss.c: Removed. - -2003-11-13 Werner Koch - - * util.h (vasprintf): Also fixed the prototype. - - * vasprintf.c (vasprintf): ARGS should not be a pointer. Fixed - segv on Solaris. Reported by Andrew J. Schorr. - -2003-11-12 Werner Koch - - * maperror.c (map_ksba_err, map_gcry_err, map_kbx_err): Removed. - -2003-10-31 Werner Koch - - * util.h (gnupg_isotime_t): New. - (gnupg_copy_time): New. - - * gettime.c (gnupg_get_isotime): New. - -2003-09-23 Werner Koch - - * iobuf.c (check_special_filename): Replaced is isdigit by digitp - to avoid passing negative values and potential locale problems. - Problem noted by Christian Biere. - - * util.h (ascii_isspace): New. - -2003-09-18 Werner Koch - - * ttyio.c (tty_fprintf): New. - (tty_print_string, tty_print_utf8_string2) - (tty_print_utf8_string): Made P argument const byte*. - -2003-08-20 Marcus Brinkmann - - * maperror.c (map_ksba_err): Map -1. Use gpg_err_make to set - the error source. - -2003-08-14 Timo Schulz - - * dynload.h. New. W32 wrapper around the dynload mechanism. - -2003-07-15 Werner Koch - - * simple-pwquery.c, simple-pwquery.h: New; moved from ../agent. - * Makefile.am (libsimple_pwquery_a_LIBADD): New. - -2003-06-25 Werner Koch - - * maperror.c (map_to_assuan_status): Directly map 0 to 0. - -2003-06-17 Werner Koch - - * gettime.c (scan_isodatestr,add_days_to_timestamp,strtimevalue) - (strtimestamp,asctimestamp): New. Code taken from gnupg 1.3.2 - mischelp.c. - - * yesno.c: New. Code taken from gnupg 1.3.2 mischelp.c - - * miscellaneous.c: New. - - * util.h: Include utf8conf.h - -2003-06-16 Werner Koch - - * gettime.c (make_timestamp): New. - - * ttyio.c: New. Taken from gnupg 1.2. - * ttyio.h: Move from ../include. - -2003-06-13 Werner Koch - - * util.h (seterr): Removed macro. - (xmalloc_secure,xcalloc_secure): New. - -2003-06-11 Werner Koch - - * iobuf.c (iobuf_writebyte,iobuf_write): Return error code from - iobuf_flush. - (iobuf_writestr): Ditto. - -2003-06-10 Werner Koch - - * iobuf.c, iobuf.h: New. Taken from current gnupg 1.3 CVS. Run - indent on it and adjusted error handling to libgpg-error style. - Replaced IOBUF by iobuf_t. Renamed malloc functions. - -2003-06-04 Werner Koch - - * errors.h: Removed all error codes. We keep the status codes for - now. - * Makefile.am: Do not create errors.c anymore; remove it from the - sources. - - * maperror.c: Don't include error.h. Change all error codes to - libgpg-error style. - (map_assuan_err): Changed to new Assuan error code convention. - (map_to_assuan_status): Likewise. - (map_gcry_err,map_kbx_err): Not needed. For now dummy functions. - - * membuf.c, membuf.h: New. Code taken from ../sm/call-agent.h. - * Makefile.am: Added above. - -2003-04-29 Werner Koch - - * util.h (fopencokokie): Removed prototype and struct. - - * fopencookie.c: Removed. - - * maperror.c: Use system assuan.h - -2002-10-31 Neal H. Walfield - - * isascii.c: New file. - * putc_unlocked.c: Likewise. - -2002-10-28 Neal H. Walfield - - * signal.c (caught_fatal_sig): Remove superfluous zero - initializer. - (caught_sigusr1): Likewise. - -2002-09-04 Neal H. Walfield - - * vasprintf.c (vasprintf) [va_copy]: Use va_copy. - [!va_copy && __va_copy]: Use __va_copy. - [!va_copy && !__va_copy]: Only now fall back to using memcpy. - -2002-08-21 Werner Koch - - * errors.h: Added STATUS_IMPORT_PROBLEM. - -2002-08-20 Werner Koch - - * vasprintf.c: Hack to handle NULL for %s. - -2002-08-09 Werner Koch - - * signal.c: New. Taken from GnuPG 1.1.91. - -2002-07-23 Werner Koch - - * util.h (_IO_cookie_io_functions_t): Fixed typo. Noted by - Richard Lefebvre. - -2002-07-22 Werner Koch - - * fseeko.c, ftello.c: New. - -2002-06-28 Werner Koch - - * maperror.c (map_to_assuan_status): Map more errorcodes to Bad - Certificate. - -2002-06-26 Werner Koch - - * maperror.c (map_to_assuan_status): Map EOF to No_Data_Available. - -2002-06-10 Werner Koch - - * errors.h (gnupg_error_token): Add new prototype. - (STATUS_ERROR): New. - - * mkerrtok: New. - * Makefile.am: Use it to create the new error token function. - -2002-06-04 Werner Koch - - * maperror.c (map_to_assuan_status): Map Bad_CA_Certificate. - -2002-05-23 Werner Koch - - * no-pth.c, Makefile.am: Removed. - -2002-05-22 Werner Koch - - * mkdtemp.c: Replaced byte by unsigned char because it is no longer - defined in gcrypt.h. - -2002-05-21 Werner Koch - - * maperror.c (map_gcry_err): Add libgcrypt's new S-expression errors. - (map_ksba_err): Add a few mappings. - -2002-05-14 Werner Koch - - * gettime.c: New. - -2002-05-03 Werner Koch - - * errors.h: Added STARUS_EXPSIG and STATUS_EXPKEYSIG. - -2002-04-15 Werner Koch - - * cryptmiss.c: New. - -2002-02-14 Werner Koch - - * maperror.c: Add more assuan<->gnupg mappings. - -2002-02-12 Werner Koch - - * fopencookie.c: Dummy function. - - * vasprintf.c: New. Taken from binutils-2.9.1 and dropped all non - ANSI-C stuff. Merged with asprintf version. - - * no-pth.c: New. - -2002-01-23 Werner Koch - - * mkdtemp.c: Copied from gnupg-1.0.6c and changed to use libgcrypt. - -2002-01-19 Werner Koch - - * sysutils.c: New. This is the misc.c file from gnupg 1.0.6 with - the OpenPGP stuff removed. - * sysutils.h: New. - -2002-01-15 Werner Koch - - * maperror.c: Add mapping for Not_Trusted. - -2002-01-11 Werner Koch - - * maperror.c (map_assuan_err): Codes for CRL - -2002-01-08 Werner Koch - - * util.h (spacep): New. - -2002-01-02 Werner Koch - - * maperror.c (map_to_assuan_status): New. Merged from ../agent - and ../sm. - -2001-12-20 Werner Koch - - * maperror.c (map_gcry_err): Add some mappings. - -2001-12-18 Werner Koch - - * Makefile.am (AM_CPPFLAGS): Include flags for gcrypt and ksba - -2001-12-14 Werner Koch - - * util.h (digitp, hexdigitp): New ctype like macros. - (atoi_1,atoi_2,atoi_4,xtoi_1,xtoi_2): New. - - - Copyright 2001, 2002 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. - - diff --git a/common/Makefile.am b/common/Makefile.am deleted file mode 100644 index 64b565cd2..000000000 --- a/common/Makefile.am +++ /dev/null @@ -1,62 +0,0 @@ -# Makefile for common gnupg modules -# Copyright (C) 2001, 2003 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -EXTRA_DIST = mkerrors mkerrtok - -noinst_LIBRARIES = libcommon.a libsimple-pwquery.a - -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) - -libcommon_a_SOURCES = \ - util.h i18n.h \ - errors.h \ - sexp-parse.h \ - maperror.c \ - sysutils.c sysutils.h \ - gettime.c \ - yesno.c \ - b64enc.c \ - miscellaneous.c \ - xasprintf.c \ - xreadline.c \ - membuf.c membuf.h \ - iobuf.c iobuf.h \ - ttyio.c ttyio.h \ - asshelp.c asshelp.h \ - signal.c \ - dynload.h - - -libcommon_a_LIBADD = @LIBOBJS@ - -libsimple_pwquery_a_SOURCES = \ - simple-pwquery.c simple-pwquery.h asshelp.c asshelp.h - -libsimple_pwquery_a_LIBADD = @LIBOBJS@ - - - - - - - - - diff --git a/common/README b/common/README deleted file mode 100644 index a90224bab..000000000 --- a/common/README +++ /dev/null @@ -1,11 +0,0 @@ -Stuff used by several modules of GnuPG. - -These directories use it: - -gpg -sm -agent - -These directories don't use it: - -kbx \ No newline at end of file diff --git a/common/asshelp.c b/common/asshelp.c deleted file mode 100644 index 23feca507..000000000 --- a/common/asshelp.c +++ /dev/null @@ -1,166 +0,0 @@ -/* asshelp.c - Helper functions for Assuan - * Copyright (C) 2002, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LOCALE_H -#include -#endif - -#include "util.h" - -#include "asshelp.h" - -/* Send the assuan command pertaining to the pinenry environment. The - OPT_* arguments are optional and may be used to overide the - defaults taken from the current locale. */ -gpg_error_t -send_pinentry_environment (assuan_context_t ctx, - const char *opt_display, - const char *opt_ttyname, - const char *opt_ttytype, - const char *opt_lc_ctype, - const char *opt_lc_messages) -{ - int rc = 0; - char *dft_display = NULL; - char *dft_ttyname = NULL; - char *dft_ttytype = NULL; - char *old_lc = NULL; - char *dft_lc = NULL; - - dft_display = getenv ("DISPLAY"); - if (opt_display || dft_display) - { - char *optstr; - if (asprintf (&optstr, "OPTION display=%s", - opt_display ? opt_display : dft_display) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } - if (!opt_ttyname) - { - dft_ttyname = getenv ("GPG_TTY"); - if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) - dft_ttyname = ttyname (0); - } - if (opt_ttyname || dft_ttyname) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttyname=%s", - opt_ttyname ? opt_ttyname : dft_ttyname) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } - dft_ttytype = getenv ("TERM"); - if (opt_ttytype || (dft_ttyname && dft_ttytype)) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttytype=%s", - opt_ttyname ? opt_ttytype : dft_ttytype) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - old_lc = setlocale (LC_CTYPE, NULL); - if (old_lc) - { - old_lc = strdup (old_lc); - if (!old_lc) - return gpg_error_from_errno (errno); - } - dft_lc = setlocale (LC_CTYPE, ""); -#endif - if (opt_lc_ctype || (dft_ttyname && dft_lc)) - { - char *optstr; - if (asprintf (&optstr, "OPTION lc-ctype=%s", - opt_lc_ctype ? opt_lc_ctype : dft_lc) < 0) - rc = gpg_error_from_errno (errno); - else - { - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - rc = map_assuan_err (rc); - } - } -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - if (old_lc) - { - setlocale (LC_CTYPE, old_lc); - free (old_lc); - } -#endif - if (rc) - return rc; -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - old_lc = setlocale (LC_MESSAGES, NULL); - if (old_lc) - { - old_lc = strdup (old_lc); - if (!old_lc) - return gpg_error_from_errno (errno); - } - dft_lc = setlocale (LC_MESSAGES, ""); -#endif - if (opt_lc_messages || (dft_ttyname && dft_lc)) - { - char *optstr; - if (asprintf (&optstr, "OPTION lc-messages=%s", - opt_lc_messages ? opt_lc_messages : dft_lc) < 0) - rc = gpg_error_from_errno (errno); - else - { - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - rc = map_assuan_err (rc); - } - } -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - if (old_lc) - { - setlocale (LC_MESSAGES, old_lc); - free (old_lc); - } -#endif - - return rc; -} - diff --git a/common/asshelp.h b/common/asshelp.h deleted file mode 100644 index 993594882..000000000 --- a/common/asshelp.h +++ /dev/null @@ -1,36 +0,0 @@ -/* asshelp.h - Helper functions for Assuan - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_ASSHELP_H -#define GNUPG_COMMON_ASSHELP_H - -#include -#include - -gpg_error_t -send_pinentry_environment (assuan_context_t ctx, - const char *opt_display, - const char *opt_ttyname, - const char *opt_ttytype, - const char *opt_lc_ctype, - const char *opt_lc_messages); - - -#endif /*GNUPG_COMMON_ASSHELP_H*/ diff --git a/common/b64enc.c b/common/b64enc.c deleted file mode 100644 index edcf6e3ad..000000000 --- a/common/b64enc.c +++ /dev/null @@ -1,211 +0,0 @@ -/* b64enc.c - Simple Base64 encoder. - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include - -#include "i18n.h" -#include "util.h" - -#define B64ENC_DID_HEADER 1 -#define B64ENC_DID_TRAILER 2 -#define B64ENC_NO_LINEFEEDS 16 - - -/* The base-64 character list */ -static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - -/* Prepare for base-64 writing to the stream FP. If TITLE is not NULL - and not an empty string, this string will be used as the title for - the armor lines, with TITLE being an empty string, we don't write - the header lines and furthermore even don't write any linefeeds. - With TITLE beeing NULL, we merely don't write header but make sure - that lines are not too long. Note, that we don't write any output - unless at least one byte get written using b64enc_write. */ -gpg_error_t -b64enc_start (struct b64state *state, FILE *fp, const char *title) -{ - memset (state, 0, sizeof *state); - state->fp = fp; - if (title && !*title) - state->flags |= B64ENC_NO_LINEFEEDS; - else if (title) - { - state->title = xtrystrdup (title); - if (!state->title) - return gpg_error_from_errno (errno); - } - return 0; -} - - -/* Write NBYTES from BUFFER to the Base 64 stream identified by - STATE. With BUFFER and NBYTES being 0, merely do a fflush on the - stream. */ -gpg_error_t -b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) -{ - unsigned char radbuf[4]; - int idx, quad_count; - const unsigned char *p; - FILE *fp = state->fp; - - - if (!nbytes) - { - if (buffer && fflush (fp)) - goto write_error; - return 0; - } - - if (!(state->flags & B64ENC_DID_HEADER)) - { - if (state->title) - { - if ( fputs ("-----BEGIN ", fp) == EOF - || fputs (state->title, fp) == EOF - || fputs ("-----\n", fp) == EOF) - goto write_error; - } - state->flags |= B64ENC_DID_HEADER; - } - - idx = state->idx; - quad_count = state->quad_count; - assert (idx < 4); - memcpy (radbuf, state->radbuf, idx); - - for (p=buffer; nbytes; p++, nbytes--) - { - radbuf[idx++] = *p; - if (idx > 2) - { - char tmp[4]; - - tmp[0] = bintoasc[(*radbuf >> 2) & 077]; - tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077]; - tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; - tmp[3] = bintoasc[radbuf[2]&077]; - for (idx=0; idx < 4; idx++) - putc (tmp[idx], fp); - idx = 0; - if (ferror (fp)) - goto write_error; - if (++quad_count >= (64/4)) - { - quad_count = 0; - if (!(state->flags & B64ENC_NO_LINEFEEDS) - && fputs ("\n", fp) == EOF) - goto write_error; - } - } - } - memcpy (state->radbuf, radbuf, idx); - state->idx = idx; - state->quad_count = quad_count; - return 0; - - write_error: - return gpg_error_from_errno (errno); -} - -gpg_error_t -b64enc_finish (struct b64state *state) -{ - gpg_error_t err = 0; - unsigned char radbuf[4]; - int idx, quad_count; - FILE *fp; - - if (!(state->flags & B64ENC_DID_HEADER)) - goto cleanup; - - /* Flush the base64 encoding */ - fp = state->fp; - idx = state->idx; - quad_count = state->quad_count; - assert (idx < 4); - memcpy (radbuf, state->radbuf, idx); - - if (idx) - { - char tmp[4]; - - tmp[0] = bintoasc[(*radbuf>>2)&077]; - if (idx == 1) - { - tmp[1] = bintoasc[((*radbuf << 4) & 060) & 077]; - tmp[2] = '='; - tmp[3] = '='; - } - else - { - tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077]; - tmp[2] = bintoasc[((radbuf[1] << 2) & 074) & 077]; - tmp[3] = '='; - } - for (idx=0; idx < 4; idx++) - putc (tmp[idx], fp); - idx = 0; - if (ferror (fp)) - goto write_error; - - if (++quad_count >= (64/4)) - { - quad_count = 0; - if (!(state->flags & B64ENC_NO_LINEFEEDS) - && fputs ("\n", fp) == EOF) - goto write_error; - } - } - - /* Finish the last line and write the trailer. */ - if (quad_count - && !(state->flags & B64ENC_NO_LINEFEEDS) - && fputs ("\n", fp) == EOF) - goto write_error; - - if (state->title) - { - if ( fputs ("-----END ", fp) == EOF - || fputs (state->title, fp) == EOF - || fputs ("-----\n", fp) == EOF) - goto write_error; - } - - goto cleanup; - - write_error: - err = gpg_error_from_errno (errno); - - cleanup: - if (state->title) - { - xfree (state->title); - state->title = NULL; - } - state->fp = NULL; - return err; -} - diff --git a/common/dynload.h b/common/dynload.h deleted file mode 100644 index 3c4652091..000000000 --- a/common/dynload.h +++ /dev/null @@ -1,71 +0,0 @@ -/* dlfcn.h - W32 functions for run-time dynamic loading - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_DYNLOAD_H -#define GNUPG_DYNLOAD_H -#ifndef __MINGW32__ -#include -#else -#include - -#define RTLD_LAZY 0 - -static __inline__ void * -dlopen (const char * name, int flag) -{ - void * hd = LoadLibrary (name); - return hd; -} - -static __inline__ void * -dlsym (void *hd, const char *sym) -{ - if (hd && sym) - { - void * fnc = GetProcAddress (hd, sym); - if (!fnc) - return NULL; - return fnc; - } - return NULL; -} - - -static __inline__ const char * -dlerror (void) -{ - static char buf[32]; - sprintf (buf, "ec=%lu", GetLastError ()); - return buf; -} - - -static __inline__ int -dlclose (void * hd) -{ - if (hd) - { - CloseHandle (hd); - return 0; - } - return -1; -} -#endif /*__MINGW32__*/ -#endif /*GNUPG_DYNLOAD_H*/ diff --git a/common/errors.h b/common/errors.h deleted file mode 100644 index f34f3ba79..000000000 --- a/common/errors.h +++ /dev/null @@ -1,112 +0,0 @@ -/* errors.h - Globally used error codes - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_ERRORS_H -#define GNUPG_COMMON_ERRORS_H - -#include "util.h" - -/* Status codes - fixme: should go into another file */ -enum { - STATUS_ENTER, - STATUS_LEAVE, - STATUS_ABORT, - STATUS_GOODSIG, - STATUS_BADSIG, - STATUS_ERRSIG, - STATUS_BADARMOR, - STATUS_RSA_OR_IDEA, - STATUS_SIGEXPIRED, - STATUS_KEYREVOKED, - STATUS_TRUST_UNDEFINED, - STATUS_TRUST_NEVER, - STATUS_TRUST_MARGINAL, - STATUS_TRUST_FULLY, - STATUS_TRUST_ULTIMATE, - - STATUS_SHM_INFO, - STATUS_SHM_GET, - STATUS_SHM_GET_BOOL, - STATUS_SHM_GET_HIDDEN, - - STATUS_NEED_PASSPHRASE, - STATUS_VALIDSIG, - STATUS_SIG_ID, - STATUS_ENC_TO, - STATUS_NODATA, - STATUS_BAD_PASSPHRASE, - STATUS_NO_PUBKEY, - STATUS_NO_SECKEY, - STATUS_NEED_PASSPHRASE_SYM, - STATUS_DECRYPTION_FAILED, - STATUS_DECRYPTION_OKAY, - STATUS_MISSING_PASSPHRASE, - STATUS_GOOD_PASSPHRASE, - STATUS_GOODMDC, - STATUS_BADMDC, - STATUS_ERRMDC, - STATUS_IMPORTED, - STATUS_IMPORT_OK, - STATUS_IMPORT_PROBLEM, - STATUS_IMPORT_RES, - STATUS_FILE_START, - STATUS_FILE_DONE, - STATUS_FILE_ERROR, - - STATUS_BEGIN_DECRYPTION, - STATUS_END_DECRYPTION, - STATUS_BEGIN_ENCRYPTION, - STATUS_END_ENCRYPTION, - - STATUS_DELETE_PROBLEM, - STATUS_GET_BOOL, - STATUS_GET_LINE, - STATUS_GET_HIDDEN, - STATUS_GOT_IT, - STATUS_PROGRESS, - STATUS_SIG_CREATED, - STATUS_SESSION_KEY, - STATUS_NOTATION_NAME, - STATUS_NOTATION_DATA, - STATUS_POLICY_URL, - STATUS_BEGIN_STREAM, - STATUS_END_STREAM, - STATUS_KEY_CREATED, - STATUS_USERID_HIN, - STATUS_UNEXPECTED, - STATUS_INV_RECP, - STATUS_NO_RECP, - STATUS_ALREADY_SIGNED, - - STATUS_EXPSIG, - STATUS_EXPKEYSIG, - - STATUS_TRUNCATED, - STATUS_ERROR, - STATUS_NEWSIG -}; - - -/*-- errors.c (build by mkerror and mkerrtok) --*/ -const char *gnupg_strerror (int err); -const char *gnupg_error_token (int err); - - -#endif /*GNUPG_COMMON_ERRORS_H*/ diff --git a/common/fseeko.c b/common/fseeko.c deleted file mode 100644 index f151b09ec..000000000 --- a/common/fseeko.c +++ /dev/null @@ -1,40 +0,0 @@ -/* fseeko.c - libc replacement function - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include - -int -fseeko (FILE *stream, off_t off, int whence) -{ - return fseek (stream, off, whence); -} - - - - - - - - - - diff --git a/common/ftello.c b/common/ftello.c deleted file mode 100644 index e3141900d..000000000 --- a/common/ftello.c +++ /dev/null @@ -1,45 +0,0 @@ -/* ftello.c - libc replacement function - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include - -off_t -ftello (FILE *stream) -{ - long int off; - - off = ftell (stream); - if (off == -1) - return (off_t)-1; - return off; -} - - - - - - - - - - diff --git a/common/gettime.c b/common/gettime.c deleted file mode 100644 index 93e4ba113..000000000 --- a/common/gettime.c +++ /dev/null @@ -1,278 +0,0 @@ -/* gettime.c - Wrapper for time functions - * Copyright (C) 1998, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#ifdef HAVE_LANGINFO_H -#include -#endif - -#include "util.h" - -static unsigned long timewarp; -static enum { NORMAL = 0, FROZEN, FUTURE, PAST } timemode; - -/* Wrapper for the time(3). We use this here so we can fake the time - for tests */ -time_t -gnupg_get_time () -{ - time_t current = time (NULL); - if (timemode == NORMAL) - return current; - else if (timemode == FROZEN) - return timewarp; - else if (timemode == FUTURE) - return current + timewarp; - else - return current - timewarp; -} - - -/* Return the current time (possibly faked) in ISO format. */ -void -gnupg_get_isotime (gnupg_isotime_t timebuf) -{ - time_t atime = gnupg_get_time (); - - if (atime < 0) - *timebuf = 0; - else - { - struct tm *tp; -#ifdef HAVE_GMTIME_R - struct tm tmbuf; - - tp = gmtime_r (&atime, &tmbuf); -#else - tp = gmtime (&atime); -#endif - sprintf (timebuf,"%04d%02d%02dT%02d%02d%02d", - 1900 + tp->tm_year, tp->tm_mon+1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec); - } -} - - -/* set the time to NEWTIME so that gnupg_get_time returns a time - starting with this one. With FREEZE set to 1 the returned time - will never change. Just for completeness, a value of (time_t)-1 - for NEWTIME gets you back to rality. Note that this is obviously - not thread-safe but this is not required. */ -void -gnupg_set_time (time_t newtime, int freeze) -{ - time_t current = time (NULL); - - if ( newtime == (time_t)-1 || current == newtime) - { - timemode = NORMAL; - timewarp = 0; - } - else if (freeze) - { - timemode = FROZEN; - timewarp = current; - } - else if (newtime > current) - { - timemode = FUTURE; - timewarp = newtime - current; - } - else - { - timemode = PAST; - timewarp = current - newtime; - } -} - -/* Returns true when we are in timewarp mode */ -int -gnupg_faked_time_p (void) -{ - return timemode; -} - - -/* This function is used by gpg because OpenPGP defines the timestamp - as an unsigned 32 bit value. */ -u32 -make_timestamp (void) -{ - time_t t = gnupg_get_time (); - - if (t == (time_t)-1) - log_fatal ("gnupg_get_time() failed\n"); - return (u32)t; -} - - - -/**************** - * Scan a date string and return a timestamp. - * The only supported format is "yyyy-mm-dd" - * Returns 0 for an invalid date. - */ -u32 -scan_isodatestr( const char *string ) -{ - int year, month, day; - struct tm tmbuf; - time_t stamp; - int i; - - if( strlen(string) != 10 || string[4] != '-' || string[7] != '-' ) - return 0; - for( i=0; i < 4; i++ ) - if( !digitp (string+i) ) - return 0; - if( !digitp (string+5) || !digitp(string+6) ) - return 0; - if( !digitp(string+8) || !digitp(string+9) ) - return 0; - year = atoi(string); - month = atoi(string+5); - day = atoi(string+8); - /* some basic checks */ - if( year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ) - return 0; - memset( &tmbuf, 0, sizeof tmbuf ); - tmbuf.tm_mday = day; - tmbuf.tm_mon = month-1; - tmbuf.tm_year = year - 1900; - tmbuf.tm_isdst = -1; - stamp = mktime( &tmbuf ); - if( stamp == (time_t)-1 ) - return 0; - return stamp; -} - - -u32 -add_days_to_timestamp( u32 stamp, u16 days ) -{ - return stamp + days*86400L; -} - - -/**************** - * Return a string with a time value in the form: x Y, n D, n H - */ - -const char * -strtimevalue( u32 value ) -{ - static char buffer[30]; - unsigned int years, days, hours, minutes; - - value /= 60; - minutes = value % 60; - value /= 60; - hours = value % 24; - value /= 24; - days = value % 365; - value /= 365; - years = value; - - sprintf(buffer,"%uy%ud%uh%um", years, days, hours, minutes ); - if( years ) - return buffer; - if( days ) - return strchr( buffer, 'y' ) + 1; - return strchr( buffer, 'd' ) + 1; -} - - -/**************** - * Note: this function returns GMT - */ -const char * -strtimestamp( u32 stamp ) -{ - static char buffer[11+5]; - struct tm *tp; - time_t atime = stamp; - - if (atime < 0) { - strcpy (buffer, "????" "-??" "-??"); - } - else { - tp = gmtime( &atime ); - sprintf(buffer,"%04d-%02d-%02d", - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday ); - } - return buffer; -} - -/**************** - * Note: this function returns local time - */ -const char * -asctimestamp( u32 stamp ) -{ - static char buffer[50]; -#if defined (HAVE_STRFTIME) && defined (HAVE_NL_LANGINFO) - static char fmt[50]; -#endif - struct tm *tp; - time_t atime = stamp; - - if (atime < 0) { - strcpy (buffer, "????" "-??" "-??"); - return buffer; - } - - tp = localtime( &atime ); -#ifdef HAVE_STRFTIME -#if defined(HAVE_NL_LANGINFO) - mem2str( fmt, nl_langinfo(D_T_FMT), DIM(fmt)-3 ); - if( strstr( fmt, "%Z" ) == NULL ) - strcat( fmt, " %Z"); - /* NOTE: gcc -Wformat-noliteral will complain here. I have - found no way to suppress this warning .*/ - strftime (buffer, DIM(buffer)-1, fmt, tp); -#else - /* FIXME: we should check whether the locale appends a " %Z" - * These locales from glibc don't put the " %Z": - * fi_FI hr_HR ja_JP lt_LT lv_LV POSIX ru_RU ru_SU sv_FI sv_SE zh_CN - */ - strftime( buffer, DIM(buffer)-1, "%c %Z", tp ); -#endif - buffer[DIM(buffer)-1] = 0; -#else - mem2str( buffer, asctime(tp), DIM(buffer) ); -#endif - return buffer; -} - - - - - - - - - - - - - - diff --git a/common/i18n.h b/common/i18n.h deleted file mode 100644 index 0e13dca4d..000000000 --- a/common/i18n.h +++ /dev/null @@ -1,47 +0,0 @@ -/* i18n.h - * Copyright (C) 1998, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_I18N_H -#define GNUPG_COMMON_I18N_H - -#ifdef USE_SIMPLE_GETTEXT - int set_gettext_file( const char *filename ); - const char *gettext( const char *msgid ); -# define _(a) gettext (a) -# define N_(a) (a) -#else -# ifdef HAVE_LOCALE_H -# include -# endif -# ifdef ENABLE_NLS -# include -# define _(a) gettext (a) -# ifdef gettext_noop -# define N_(a) gettext_noop (a) -# else -# define N_(a) (a) -# endif -# else -# define _(a) (a) -# define N_(a) (a) -# endif -#endif /*!USE_SIMPLE_GETTEXT*/ - -#endif /*GNUPG_COMMON_I18N_H*/ diff --git a/common/iobuf.c b/common/iobuf.c deleted file mode 100644 index 4d735397e..000000000 --- a/common/iobuf.c +++ /dev/null @@ -1,2415 +0,0 @@ -/* iobuf.c - file handling - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_DOSISH_SYSTEM -#include -#endif -#ifdef __riscos__ -#include -#include -#endif /* __riscos__ */ - -#include "memory.h" -#include "util.h" -#include "iobuf.h" - -#undef FILE_FILTER_USES_STDIO - -#ifdef HAVE_DOSISH_SYSTEM -#define USE_SETMODE 1 -#endif - -#ifdef FILE_FILTER_USES_STDIO -#define my_fileno(a) fileno ((a)) -#define my_fopen_ro(a,b) fopen ((a),(b)) -#define my_fopen(a,b) fopen ((a),(b)) -typedef FILE *FILEP_OR_FD; -#define INVALID_FP NULL -#define FILEP_OR_FD_FOR_STDIN (stdin) -#define FILEP_OR_FD_FOR_STDOUT (stdout) -typedef struct -{ - FILE *fp; /* open file handle */ - int keep_open; - int no_cache; - int print_only_name; /* flags indicating that fname is not a real file */ - char fname[1]; /* name of the file */ -} -file_filter_ctx_t; -#else -#define my_fileno(a) (a) -#define my_fopen_ro(a,b) fd_cache_open ((a),(b)) -#define my_fopen(a,b) direct_open ((a),(b)) -#ifdef HAVE_DOSISH_SYSTEM -typedef HANDLE FILEP_OR_FD; -#define INVALID_FP ((HANDLE)-1) -#define FILEP_OR_FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE)) -#define FILEP_OR_FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE)) -#undef USE_SETMODE -#else -typedef int FILEP_OR_FD; -#define INVALID_FP (-1) -#define FILEP_OR_FD_FOR_STDIN (0) -#define FILEP_OR_FD_FOR_STDOUT (1) -#endif -typedef struct -{ - FILEP_OR_FD fp; /* open file handle */ - int keep_open; - int no_cache; - int eof_seen; - int print_only_name; /* flags indicating that fname is not a real file */ - char fname[1]; /* name of the file */ -} -file_filter_ctx_t; - -struct close_cache_s -{ - struct close_cache_s *next; - FILEP_OR_FD fp; - char fname[1]; -}; -typedef struct close_cache_s *CLOSE_CACHE; -static CLOSE_CACHE close_cache; -#endif - -#ifdef _WIN32 -typedef struct -{ - int sock; - int keep_open; - int no_cache; - int eof_seen; - int print_only_name; /* flags indicating that fname is not a real file */ - char fname[1]; /* name of the file */ -} -sock_filter_ctx_t; -#endif /*_WIN32*/ - -/* The first partial length header block must be of size 512 - * to make it easier (and efficienter) we use a min. block size of 512 - * for all chunks (but the last one) */ -#define OP_MIN_PARTIAL_CHUNK 512 -#define OP_MIN_PARTIAL_CHUNK_2POW 9 - -typedef struct -{ - int use; - size_t size; - size_t count; - int partial; /* 1 = partial header, 2 in last partial packet */ - char *buffer; /* used for partial header */ - size_t buflen; /* used size of buffer */ - int first_c; /* of partial header (which is > 0) */ - int eof; -} -block_filter_ctx_t; - -static int special_names_enabled; - -static int underflow (iobuf_t a); -static int translate_file_handle (int fd, int for_write); - -#ifndef FILE_FILTER_USES_STDIO - -/* - * Invalidate (i.e. close) a cached iobuf - */ -static void -fd_cache_invalidate (const char *fname) -{ - CLOSE_CACHE cc; - - assert (fname); - if (DBG_IOBUF) - log_debug ("fd_cache_invalidate (%s)\n", fname); - - for (cc = close_cache; cc; cc = cc->next) - { - if (cc->fp != INVALID_FP && !strcmp (cc->fname, fname)) - { - if (DBG_IOBUF) - log_debug (" did (%s)\n", cc->fname); -#ifdef HAVE_DOSISH_SYSTEM - CloseHandle (cc->fp); -#else - close (cc->fp); -#endif - cc->fp = INVALID_FP; - } - } -} - - - -static FILEP_OR_FD -direct_open (const char *fname, const char *mode) -{ -#ifdef HAVE_DOSISH_SYSTEM - unsigned long da, cd, sm; - HANDLE hfile; - - /* Note, that we do not handle all mode combinations */ - - /* According to the ReactOS source it seems that open() of the - * standard MSW32 crt does open the file in share mode which is - * something new for MS applications ;-) - */ - if (strchr (mode, '+')) - { - fd_cache_invalidate (fname); - da = GENERIC_READ | GENERIC_WRITE; - cd = OPEN_EXISTING; - sm = FILE_SHARE_READ | FILE_SHARE_WRITE; - } - else if (strchr (mode, 'w')) - { - fd_cache_invalidate (fname); - da = GENERIC_WRITE; - cd = CREATE_ALWAYS; - sm = FILE_SHARE_WRITE; - } - else - { - da = GENERIC_READ; - cd = OPEN_EXISTING; - sm = FILE_SHARE_READ; - } - - hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL); - return hfile; -#else - int oflag; - int cflag = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - - /* Note, that we do not handle all mode combinations */ - if (strchr (mode, '+')) - { - fd_cache_invalidate (fname); - oflag = O_RDWR; - } - else if (strchr (mode, 'w')) - { - fd_cache_invalidate (fname); - oflag = O_WRONLY | O_CREAT | O_TRUNC; - } - else - { - oflag = O_RDONLY; - } -#ifdef O_BINARY - if (strchr (mode, 'b')) - oflag |= O_BINARY; -#endif -#ifndef __riscos__ - return open (fname, oflag, cflag); -#else - { - struct stat buf; - int rc = stat (fname, &buf); - - /* Don't allow iobufs on directories */ - if (!rc && S_ISDIR (buf.st_mode) && !S_ISREG (buf.st_mode)) - return __set_errno (EISDIR); - else - return open (fname, oflag, cflag); - } -#endif -#endif -} - - -/* - * Instead of closing an FD we keep it open and cache it for later reuse - * Note that this caching strategy only works if the process does not chdir. - */ -static void -fd_cache_close (const char *fname, FILEP_OR_FD fp) -{ - CLOSE_CACHE cc; - - assert (fp); - if (!fname || !*fname) - { -#ifdef HAVE_DOSISH_SYSTEM - CloseHandle (fp); -#else - close (fp); -#endif - if (DBG_IOBUF) - log_debug ("fd_cache_close (%p) real\n", (void *) fp); - return; - } - /* try to reuse a slot */ - for (cc = close_cache; cc; cc = cc->next) - { - if (cc->fp == INVALID_FP && !strcmp (cc->fname, fname)) - { - cc->fp = fp; - if (DBG_IOBUF) - log_debug ("fd_cache_close (%s) used existing slot\n", fname); - return; - } - } - /* add a new one */ - if (DBG_IOBUF) - log_debug ("fd_cache_close (%s) new slot created\n", fname); - cc = xcalloc (1, sizeof *cc + strlen (fname)); - strcpy (cc->fname, fname); - cc->fp = fp; - cc->next = close_cache; - close_cache = cc; -} - -/* - * Do an direct_open on FNAME but first try to reuse one from the fd_cache - */ -static FILEP_OR_FD -fd_cache_open (const char *fname, const char *mode) -{ - CLOSE_CACHE cc; - - assert (fname); - for (cc = close_cache; cc; cc = cc->next) - { - if (cc->fp != INVALID_FP && !strcmp (cc->fname, fname)) - { - FILEP_OR_FD fp = cc->fp; - cc->fp = INVALID_FP; - if (DBG_IOBUF) - log_debug ("fd_cache_open (%s) using cached fp\n", fname); -#ifdef HAVE_DOSISH_SYSTEM - if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff) - { - log_error ("rewind file failed on handle %p: ec=%d\n", - fp, (int) GetLastError ()); - fp = INVALID_FP; - } -#else - if (lseek (fp, 0, SEEK_SET) == (off_t) - 1) - { - log_error ("can't rewind fd %d: %s\n", fp, strerror (errno)); - fp = INVALID_FP; - } -#endif - return fp; - } - } - if (DBG_IOBUF) - log_debug ("fd_cache_open (%s) not cached\n", fname); - return direct_open (fname, mode); -} - - -#endif /*FILE_FILTER_USES_STDIO */ - - -/**************** - * Read data from a file into buf which has an allocated length of *LEN. - * return the number of read bytes in *LEN. OPAQUE is the FILE * of - * the stream. A is not used. - * control may be: - * IOBUFCTRL_INIT: called just before the function is linked into the - * list of function. This can be used to prepare internal - * data structures of the function. - * IOBUFCTRL_FREE: called just before the function is removed from the - * list of functions and can be used to release internal - * data structures or close a file etc. - * IOBUFCTRL_UNDERFLOW: called by iobuf_underflow to fill the buffer - * with new stuff. *RET_LEN is the available size of the - * buffer, and should be set to the number of bytes - * which were put into the buffer. The function - * returns 0 to indicate success, -1 on EOF and - * GPG_ERR_xxxxx for other errors. - * - * IOBUFCTRL_FLUSH: called by iobuf_flush() to write out the collected stuff. - * *RET_LAN is the number of bytes in BUF. - * - * IOBUFCTRL_CANCEL: send to all filters on behalf of iobuf_cancel. The - * filter may take appropriate action on this message. - */ -static int -file_filter (void *opaque, int control, iobuf_t chain, byte * buf, - size_t * ret_len) -{ - file_filter_ctx_t *a = opaque; - FILEP_OR_FD f = a->fp; - size_t size = *ret_len; - size_t nbytes = 0; - int rc = 0; - -#ifdef FILE_FILTER_USES_STDIO - if (control == IOBUFCTRL_UNDERFLOW) - { - assert (size); /* need a buffer */ - if (feof (f)) - { /* On terminals you could easiely read as many EOFs as you call */ - rc = -1; /* fread() or fgetc() repeatly. Every call will block until you press */ - *ret_len = 0; /* CTRL-D. So we catch this case before we call fread() again. */ - } - else - { - clearerr (f); - nbytes = fread (buf, 1, size, f); - if (feof (f) && !nbytes) - { - rc = -1; /* okay: we can return EOF now. */ - } - else if (ferror (f) && errno != EPIPE) - { - rc = gpg_error_from_errno (errno); - log_error ("%s: read error: %s\n", a->fname, strerror (errno)); - } - *ret_len = nbytes; - } - } - else if (control == IOBUFCTRL_FLUSH) - { - if (size) - { - clearerr (f); - nbytes = fwrite (buf, 1, size, f); - if (ferror (f)) - { - rc = gpg_error_from_errno (errno); - log_error ("%s: write error: %s\n", a->fname, strerror (errno)); - } - } - *ret_len = nbytes; - } - else if (control == IOBUFCTRL_INIT) - { - a->keep_open = a->no_cache = 0; - } - else if (control == IOBUFCTRL_DESC) - { - *(char **) buf = "file_filter"; - } - else if (control == IOBUFCTRL_FREE) - { - if (f != stdin && f != stdout) - { - if (DBG_IOBUF) - log_debug ("%s: close fd %d\n", a->fname, fileno (f)); - if (!a->keep_open) - fclose (f); - } - f = NULL; - xfree (a); /* we can free our context now */ - } -#else /* !stdio implementation */ - - if (control == IOBUFCTRL_UNDERFLOW) - { - assert (size); /* need a buffer */ - if (a->eof_seen) - { - rc = -1; - *ret_len = 0; - } - else - { -#ifdef HAVE_DOSISH_SYSTEM - unsigned long nread; - - nbytes = 0; - if (!ReadFile (f, buf, size, &nread, NULL)) - { - int ec = (int) GetLastError (); - if (ec != ERROR_BROKEN_PIPE) - { - rc = gpg_error_from_errno (ec); - log_error ("%s: read error: ec=%d\n", a->fname, ec); - } - } - else if (!nread) - { - a->eof_seen = 1; - rc = -1; - } - else - { - nbytes = nread; - } - -#else - - int n; - - nbytes = 0; - do - { - n = read (f, buf, size); - } - while (n == -1 && errno == EINTR); - if (n == -1) - { /* error */ - if (errno != EPIPE) - { - rc = gpg_error_from_errno (errno); - log_error ("%s: read error: %s\n", - a->fname, strerror (errno)); - } - } - else if (!n) - { /* eof */ - a->eof_seen = 1; - rc = -1; - } - else - { - nbytes = n; - } -#endif - *ret_len = nbytes; - } - } - else if (control == IOBUFCTRL_FLUSH) - { - if (size) - { -#ifdef HAVE_DOSISH_SYSTEM - byte *p = buf; - unsigned long n; - - nbytes = size; - do - { - if (size && !WriteFile (f, p, nbytes, &n, NULL)) - { - int ec = (int) GetLastError (); - rc = gpg_error_from_errno (ec); - log_error ("%s: write error: ec=%d\n", a->fname, ec); - break; - } - p += n; - nbytes -= n; - } - while (nbytes); - nbytes = p - buf; -#else - byte *p = buf; - int n; - - nbytes = size; - do - { - do - { - n = write (f, p, nbytes); - } - while (n == -1 && errno == EINTR); - if (n > 0) - { - p += n; - nbytes -= n; - } - } - while (n != -1 && nbytes); - if (n == -1) - { - rc = gpg_error_from_errno (errno); - log_error ("%s: write error: %s\n", a->fname, strerror (errno)); - } - nbytes = p - buf; -#endif - } - *ret_len = nbytes; - } - else if (control == IOBUFCTRL_INIT) - { - a->eof_seen = 0; - a->keep_open = 0; - a->no_cache = 0; - } - else if (control == IOBUFCTRL_DESC) - { - *(char **) buf = "file_filter(fd)"; - } - else if (control == IOBUFCTRL_FREE) - { -#ifdef HAVE_DOSISH_SYSTEM - if (f != FILEP_OR_FD_FOR_STDIN && f != FILEP_OR_FD_FOR_STDOUT) - { - if (DBG_IOBUF) - log_debug ("%s: close handle %p\n", a->fname, f); - if (!a->keep_open) - fd_cache_close (a->no_cache ? NULL : a->fname, f); - } -#else - if ((int) f != 0 && (int) f != 1) - { - if (DBG_IOBUF) - log_debug ("%s: close fd %d\n", a->fname, f); - if (!a->keep_open) - fd_cache_close (a->no_cache ? NULL : a->fname, f); - } - f = INVALID_FP; -#endif - xfree (a); /* we can free our context now */ - } -#endif /* !stdio implementation */ - return rc; -} - -#ifdef _WIN32 -/* Becuase sockets are an special object under Lose32 we have to - * use a special filter */ -static int -sock_filter (void *opaque, int control, iobuf_t chain, byte * buf, - size_t * ret_len) -{ - sock_filter_ctx_t *a = opaque; - size_t size = *ret_len; - size_t nbytes = 0; - int rc = 0; - - if (control == IOBUFCTRL_UNDERFLOW) - { - assert (size); /* need a buffer */ - if (a->eof_seen) - { - rc = -1; - *ret_len = 0; - } - else - { - int nread; - - nread = recv (a->sock, buf, size, 0); - if (nread == SOCKET_ERROR) - { - int ec = (int) WSAGetLastError (); - rc = gpg_error_from_errno (ec); - log_error ("socket read error: ec=%d\n", ec); - } - else if (!nread) - { - a->eof_seen = 1; - rc = -1; - } - else - { - nbytes = nread; - } - *ret_len = nbytes; - } - } - else if (control == IOBUFCTRL_FLUSH) - { - if (size) - { - byte *p = buf; - int n; - - nbytes = size; - do - { - n = send (a->sock, p, nbytes, 0); - if (n == SOCKET_ERROR) - { - int ec = (int) WSAGetLastError (); - rc = gpg_error_from_errno (ec); - log_error ("socket write error: ec=%d\n", ec); - break; - } - p += n; - nbytes -= n; - } - while (nbytes); - nbytes = p - buf; - } - *ret_len = nbytes; - } - else if (control == IOBUFCTRL_INIT) - { - a->eof_seen = 0; - a->keep_open = 0; - a->no_cache = 0; - } - else if (control == IOBUFCTRL_DESC) - { - *(char **) buf = "sock_filter"; - } - else if (control == IOBUFCTRL_FREE) - { - if (!a->keep_open) - closesocket (a->sock); - xfree (a); /* we can free our context now */ - } - return rc; -} -#endif /*_WIN32*/ - -/**************** - * This is used to implement the block write mode. - * Block reading is done on a byte by byte basis in readbyte(), - * without a filter - */ -static int -block_filter (void *opaque, int control, iobuf_t chain, byte * buf, - size_t * ret_len) -{ - block_filter_ctx_t *a = opaque; - size_t size = *ret_len; - int c, needed, rc = 0; - char *p; - - if (control == IOBUFCTRL_UNDERFLOW) - { - size_t n = 0; - - p = buf; - assert (size); /* need a buffer */ - if (a->eof) /* don't read any further */ - rc = -1; - while (!rc && size) - { - if (!a->size) - { /* get the length bytes */ - if (a->partial == 2) - { - a->eof = 1; - if (!n) - rc = -1; - break; - } - else if (a->partial) - { - /* These OpenPGP introduced huffman like encoded length - * bytes are really a mess :-( */ - if (a->first_c) - { - c = a->first_c; - a->first_c = 0; - } - else if ((c = iobuf_get (chain)) == -1) - { - log_error ("block_filter: 1st length byte missing\n"); - rc = GPG_ERR_BAD_DATA; - break; - } - if (c < 192) - { - a->size = c; - a->partial = 2; - if (!a->size) - { - a->eof = 1; - if (!n) - rc = -1; - break; - } - } - else if (c < 224) - { - a->size = (c - 192) * 256; - if ((c = iobuf_get (chain)) == -1) - { - log_error - ("block_filter: 2nd length byte missing\n"); - rc = GPG_ERR_BAD_DATA; - break; - } - a->size += c + 192; - a->partial = 2; - if (!a->size) - { - a->eof = 1; - if (!n) - rc = -1; - break; - } - } - else if (c == 255) - { - a->size = iobuf_get (chain) << 24; - a->size |= iobuf_get (chain) << 16; - a->size |= iobuf_get (chain) << 8; - if ((c = iobuf_get (chain)) == -1) - { - log_error ("block_filter: invalid 4 byte length\n"); - rc = GPG_ERR_BAD_DATA; - break; - } - a->size |= c; - } - else - { /* next partial body length */ - a->size = 1 << (c & 0x1f); - } - /* log_debug("partial: ctx=%p c=%02x size=%u\n", a, c, a->size); */ - } - else - { /* the gnupg partial length scheme - much better :-) */ - c = iobuf_get (chain); - a->size = c << 8; - c = iobuf_get (chain); - a->size |= c; - if (c == -1) - { - log_error ("block_filter: error reading length info\n"); - rc = GPG_ERR_BAD_DATA; - } - if (!a->size) - { - a->eof = 1; - if (!n) - rc = -1; - break; - } - } - } - - while (!rc && size && a->size) - { - needed = size < a->size ? size : a->size; - c = iobuf_read (chain, p, needed); - if (c < needed) - { - if (c == -1) - c = 0; - log_error - ("block_filter %p: read error (size=%lu,a->size=%lu)\n", - a, (ulong) size + c, (ulong) a->size + c); - rc = GPG_ERR_BAD_DATA; - } - else - { - size -= c; - a->size -= c; - p += c; - n += c; - } - } - } - *ret_len = n; - } - else if (control == IOBUFCTRL_FLUSH) - { - if (a->partial) - { /* the complicated openpgp scheme */ - size_t blen, n, nbytes = size + a->buflen; - - assert (a->buflen <= OP_MIN_PARTIAL_CHUNK); - if (nbytes < OP_MIN_PARTIAL_CHUNK) - { - /* not enough to write a partial block out; so we store it */ - if (!a->buffer) - a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK); - memcpy (a->buffer + a->buflen, buf, size); - a->buflen += size; - } - else - { /* okay, we can write out something */ - /* do this in a loop to use the most efficient block lengths */ - p = buf; - do - { - /* find the best matching block length - this is limited - * by the size of the internal buffering */ - for (blen = OP_MIN_PARTIAL_CHUNK * 2, - c = OP_MIN_PARTIAL_CHUNK_2POW + 1; blen <= nbytes; - blen *= 2, c++) - ; - blen /= 2; - c--; - /* write the partial length header */ - assert (c <= 0x1f); /*;-) */ - c |= 0xe0; - iobuf_put (chain, c); - if ((n = a->buflen)) - { /* write stuff from the buffer */ - assert (n == OP_MIN_PARTIAL_CHUNK); - if (iobuf_write (chain, a->buffer, n)) - rc = gpg_error_from_errno (errno); - a->buflen = 0; - nbytes -= n; - } - if ((n = nbytes) > blen) - n = blen; - if (n && iobuf_write (chain, p, n)) - rc = gpg_error_from_errno (errno); - p += n; - nbytes -= n; - } - while (!rc && nbytes >= OP_MIN_PARTIAL_CHUNK); - /* store the rest in the buffer */ - if (!rc && nbytes) - { - assert (!a->buflen); - assert (nbytes < OP_MIN_PARTIAL_CHUNK); - if (!a->buffer) - a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK); - memcpy (a->buffer, p, nbytes); - a->buflen = nbytes; - } - } - } - else - { /* the gnupg scheme (which is not openpgp compliant) */ - size_t avail, n; - - for (p = buf; !rc && size;) - { - n = size; - avail = a->size - a->count; - if (!avail) - { - if (n > a->size) - { - iobuf_put (chain, (a->size >> 8) & 0xff); - iobuf_put (chain, a->size & 0xff); - avail = a->size; - a->count = 0; - } - else - { - iobuf_put (chain, (n >> 8) & 0xff); - iobuf_put (chain, n & 0xff); - avail = n; - a->count = a->size - n; - } - } - if (n > avail) - n = avail; - if (iobuf_write (chain, p, n)) - rc = gpg_error_from_errno (errno); - a->count += n; - p += n; - size -= n; - } - } - } - else if (control == IOBUFCTRL_INIT) - { - if (DBG_IOBUF) - log_debug ("init block_filter %p\n", a); - if (a->partial) - a->count = 0; - else if (a->use == 1) - a->count = a->size = 0; - else - a->count = a->size; /* force first length bytes */ - a->eof = 0; - a->buffer = NULL; - a->buflen = 0; - } - else if (control == IOBUFCTRL_DESC) - { - *(char **) buf = "block_filter"; - } - else if (control == IOBUFCTRL_FREE) - { - if (a->use == 2) - { /* write the end markers */ - if (a->partial) - { - u32 len; - /* write out the remaining bytes without a partial header - * the length of this header may be 0 - but if it is - * the first block we are not allowed to use a partial header - * and frankly we can't do so, because this length must be - * a power of 2. This is _really_ complicated because we - * have to check the possible length of a packet prior - * to it's creation: a chain of filters becomes complicated - * and we need a lot of code to handle compressed packets etc. - * :-((((((( - */ - /* construct header */ - len = a->buflen; - /*log_debug("partial: remaining length=%u\n", len ); */ - if (len < 192) - rc = iobuf_put (chain, len); - else if (len < 8384) - { - if (!(rc = iobuf_put (chain, ((len - 192) / 256) + 192))) - rc = iobuf_put (chain, ((len - 192) % 256)); - } - else - { /* use a 4 byte header */ - if (!(rc = iobuf_put (chain, 0xff))) - if (!(rc = iobuf_put (chain, (len >> 24) & 0xff))) - if (!(rc = iobuf_put (chain, (len >> 16) & 0xff))) - if (!(rc = iobuf_put (chain, (len >> 8) & 0xff))) - rc = iobuf_put (chain, len & 0xff); - } - if (!rc && len) - rc = iobuf_write (chain, a->buffer, len); - if (rc) - { - log_error ("block_filter: write error: %s\n", - strerror (errno)); - rc = gpg_error_from_errno (errno); - } - xfree (a->buffer); - a->buffer = NULL; - a->buflen = 0; - } - else - { - iobuf_writebyte (chain, 0); - iobuf_writebyte (chain, 0); - } - } - else if (a->size) - { - log_error ("block_filter: pending bytes!\n"); - } - if (DBG_IOBUF) - log_debug ("free block_filter %p\n", a); - xfree (a); /* we can free our context now */ - } - - return rc; -} - - -static void -print_chain (iobuf_t a) -{ - if (!DBG_IOBUF) - return; - for (; a; a = a->chain) - { - size_t dummy_len = 0; - const char *desc = "[none]"; - - if (a->filter) - a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL, - (byte *) & desc, &dummy_len); - - log_debug ("iobuf chain: %d.%d `%s' filter_eof=%d start=%d len=%d\n", - a->no, a->subno, desc, a->filter_eof, - (int) a->d.start, (int) a->d.len); - } -} - -int -iobuf_print_chain (iobuf_t a) -{ - print_chain (a); - return 0; -} - -/**************** - * Allocate a new io buffer, with no function assigned. - * Use is the desired usage: 1 for input, 2 for output, 3 for temp buffer - * BUFSIZE is a suggested buffer size. - */ -iobuf_t -iobuf_alloc (int use, size_t bufsize) -{ - iobuf_t a; - static int number = 0; - - a = xcalloc (1, sizeof *a); - a->use = use; - a->d.buf = xmalloc (bufsize); - a->d.size = bufsize; - a->no = ++number; - a->subno = 0; - a->opaque = NULL; - a->real_fname = NULL; - return a; -} - -int -iobuf_close (iobuf_t a) -{ - iobuf_t a2; - size_t dummy_len = 0; - int rc = 0; - - if (a && a->directfp) - { - fclose (a->directfp); - xfree (a->real_fname); - if (DBG_IOBUF) - log_debug ("iobuf_close -> %p\n", a->directfp); - return 0; - } - - for (; a && !rc; a = a2) - { - a2 = a->chain; - if (a->use == 2 && (rc = iobuf_flush (a))) - log_error ("iobuf_flush failed on close: %s\n", gpg_strerror (rc)); - - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: close `%s'\n", a->no, a->subno, a->desc); - if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, - a->chain, NULL, &dummy_len))) - log_error ("IOBUFCTRL_FREE failed on close: %s\n", gpg_strerror (rc)); - xfree (a->real_fname); - if (a->d.buf) - { - memset (a->d.buf, 0, a->d.size); /* erase the buffer */ - xfree (a->d.buf); - } - xfree (a); - } - return rc; -} - -int -iobuf_cancel (iobuf_t a) -{ - const char *s; - iobuf_t a2; - int rc; -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - char *remove_name = NULL; -#endif - - if (a && a->use == 2) - { - s = iobuf_get_real_fname (a); - if (s && *s) - { -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove_name = m_strdup (s); -#else - remove (s); -#endif - } - } - - /* send a cancel message to all filters */ - for (a2 = a; a2; a2 = a2->chain) - { - size_t dummy; - if (a2->filter) - a2->filter (a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain, NULL, &dummy); - } - - rc = iobuf_close (a); -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - if (remove_name) - { - /* Argg, MSDOS does not allow to remove open files. So - * we have to do it here */ - remove (remove_name); - xfree (remove_name); - } -#endif - return rc; -} - - -/**************** - * create a temporary iobuf, which can be used to collect stuff - * in an iobuf and later be written by iobuf_write_temp() to another - * iobuf. - */ -iobuf_t -iobuf_temp () -{ - iobuf_t a; - - a = iobuf_alloc (3, 8192); - - return a; -} - -iobuf_t -iobuf_temp_with_content (const char *buffer, size_t length) -{ - iobuf_t a; - - a = iobuf_alloc (3, length); - memcpy (a->d.buf, buffer, length); - a->d.len = length; - - return a; -} - -void -iobuf_enable_special_filenames (int yes) -{ - special_names_enabled = yes; -} - -/* - * see whether the filename has the for "-&nnnn", where n is a - * non-zero number. - * Returns this number or -1 if it is not the case. - */ -static int -check_special_filename (const char *fname) -{ - if (special_names_enabled && fname && *fname == '-' && fname[1] == '&') - { - int i; - - fname += 2; - for (i = 0; digitp (fname+i); i++) - ; - if (!fname[i]) - return atoi (fname); - } - return -1; -} - -/**************** - * Create a head iobuf for reading from a file - * returns: NULL if an error occures and sets errno - */ -iobuf_t -iobuf_open (const char *fname) -{ - iobuf_t a; - FILEP_OR_FD fp; - file_filter_ctx_t *fcx; - size_t len; - int print_only = 0; - int fd; - - if (!fname || (*fname == '-' && !fname[1])) - { - fp = FILEP_OR_FD_FOR_STDIN; -#ifdef USE_SETMODE - setmode (my_fileno (fp), O_BINARY); -#endif - fname = "[stdin]"; - print_only = 1; - } - else if ((fd = check_special_filename (fname)) != -1) - return iobuf_fdopen (translate_file_handle (fd, 0), "rb"); - else if ((fp = my_fopen_ro (fname, "rb")) == INVALID_FP) - return NULL; - a = iobuf_alloc (1, 8192); - fcx = xmalloc (sizeof *fcx + strlen (fname)); - fcx->fp = fp; - fcx->print_only_name = print_only; - strcpy (fcx->fname, fname); - if (!print_only) - a->real_fname = xstrdup (fname); - a->filter = file_filter; - a->filter_ov = fcx; - file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); - file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: open `%s' fd=%d\n", - a->no, a->subno, fname, (int) my_fileno (fcx->fp)); - - return a; -} - -/**************** - * Create a head iobuf for reading from a file - * returns: NULL if an error occures and sets errno - */ -iobuf_t -iobuf_fdopen (int fd, const char *mode) -{ - iobuf_t a; - FILEP_OR_FD fp; - file_filter_ctx_t *fcx; - size_t len; - -#ifdef FILE_FILTER_USES_STDIO - if (!(fp = fdopen (fd, mode))) - return NULL; -#else - fp = (FILEP_OR_FD) fd; -#endif - a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, 8192); - fcx = xmalloc (sizeof *fcx + 20); - fcx->fp = fp; - fcx->print_only_name = 1; - sprintf (fcx->fname, "[fd %d]", fd); - a->filter = file_filter; - a->filter_ov = fcx; - file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); - file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: fdopen `%s'\n", a->no, a->subno, fcx->fname); - iobuf_ioctl (a, 3, 1, NULL); /* disable fd caching */ - return a; -} - - -iobuf_t -iobuf_sockopen (int fd, const char *mode) -{ - iobuf_t a; -#ifdef _WIN32 - sock_filter_ctx_t *scx; - size_t len; - - a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, 8192); - scx = m_alloc (sizeof *scx + 25); - scx->sock = fd; - scx->print_only_name = 1; - sprintf (scx->fname, "[sock %d]", fd); - a->filter = sock_filter; - a->filter_ov = scx; - sock_filter (scx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); - sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: sockopen `%s'\n", a->no, a->subno, scx->fname); - iobuf_ioctl (a, 3, 1, NULL); /* disable fd caching */ -#else - a = iobuf_fdopen (fd, mode); -#endif - return a; -} - -/**************** - * create an iobuf for writing to a file; the file will be created. - */ -iobuf_t -iobuf_create (const char *fname) -{ - iobuf_t a; - FILEP_OR_FD fp; - file_filter_ctx_t *fcx; - size_t len; - int print_only = 0; - int fd; - - if (!fname || (*fname == '-' && !fname[1])) - { - fp = FILEP_OR_FD_FOR_STDOUT; -#ifdef USE_SETMODE - setmode (my_fileno (fp), O_BINARY); -#endif - fname = "[stdout]"; - print_only = 1; - } - else if ((fd = check_special_filename (fname)) != -1) - return iobuf_fdopen (translate_file_handle (fd, 1), "wb"); - else if ((fp = my_fopen (fname, "wb")) == INVALID_FP) - return NULL; - a = iobuf_alloc (2, 8192); - fcx = xmalloc (sizeof *fcx + strlen (fname)); - fcx->fp = fp; - fcx->print_only_name = print_only; - strcpy (fcx->fname, fname); - if (!print_only) - a->real_fname = xstrdup (fname); - a->filter = file_filter; - a->filter_ov = fcx; - file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); - file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: create `%s'\n", a->no, a->subno, a->desc); - - return a; -} - -/**************** - * append to an iobuf; if the file does not exist, create it. - * cannot be used for stdout. - * Note: This is not used. - */ -#if 0 /* not used */ -iobuf_t -iobuf_append (const char *fname) -{ - iobuf_t a; - FILE *fp; - file_filter_ctx_t *fcx; - size_t len; - - if (!fname) - return NULL; - else if (!(fp = my_fopen (fname, "ab"))) - return NULL; - a = iobuf_alloc (2, 8192); - fcx = m_alloc (sizeof *fcx + strlen (fname)); - fcx->fp = fp; - strcpy (fcx->fname, fname); - a->real_fname = m_strdup (fname); - a->filter = file_filter; - a->filter_ov = fcx; - file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); - file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: append `%s'\n", a->no, a->subno, a->desc); - - return a; -} -#endif - -iobuf_t -iobuf_openrw (const char *fname) -{ - iobuf_t a; - FILEP_OR_FD fp; - file_filter_ctx_t *fcx; - size_t len; - - if (!fname) - return NULL; - else if ((fp = my_fopen (fname, "r+b")) == INVALID_FP) - return NULL; - a = iobuf_alloc (2, 8192); - fcx = xmalloc (sizeof *fcx + strlen (fname)); - fcx->fp = fp; - strcpy (fcx->fname, fname); - a->real_fname = xstrdup (fname); - a->filter = file_filter; - a->filter_ov = fcx; - file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); - file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: openrw `%s'\n", a->no, a->subno, a->desc); - - return a; -} - - -int -iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval) -{ - if (cmd == 1) - { /* keep system filepointer/descriptor open */ - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: ioctl `%s' keep=%d\n", - a ? a->no : -1, a ? a->subno : -1, a ? a->desc : "?", - intval); - for (; a; a = a->chain) - if (!a->chain && a->filter == file_filter) - { - file_filter_ctx_t *b = a->filter_ov; - b->keep_open = intval; - return 0; - } -#ifdef _WIN32 - else if (!a->chain && a->filter == sock_filter) - { - sock_filter_ctx_t *b = a->filter_ov; - b->keep_open = intval; - return 0; - } -#endif - } - else if (cmd == 2) - { /* invalidate cache */ - if (DBG_IOBUF) - log_debug ("iobuf-*.*: ioctl `%s' invalidate\n", - ptrval ? (char *) ptrval : "?"); - if (!a && !intval && ptrval) - { -#ifndef FILE_FILTER_USES_STDIO - fd_cache_invalidate (ptrval); -#endif - return 0; - } - } - else if (cmd == 3) - { /* disallow/allow caching */ - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: ioctl `%s' no_cache=%d\n", - a ? a->no : -1, a ? a->subno : -1, a ? a->desc : "?", - intval); - for (; a; a = a->chain) - if (!a->chain && a->filter == file_filter) - { - file_filter_ctx_t *b = a->filter_ov; - b->no_cache = intval; - return 0; - } -#ifdef _WIN32 - else if (!a->chain && a->filter == sock_filter) - { - sock_filter_ctx_t *b = a->filter_ov; - b->no_cache = intval; - return 0; - } -#endif - } - - return -1; -} - - -/**************** - * Register an i/o filter. - */ -int -iobuf_push_filter (iobuf_t a, - int (*f) (void *opaque, int control, - iobuf_t chain, byte * buf, size_t * len), - void *ov) -{ - return iobuf_push_filter2 (a, f, ov, 0); -} - -int -iobuf_push_filter2 (iobuf_t a, - int (*f) (void *opaque, int control, - iobuf_t chain, byte * buf, size_t * len), - void *ov, int rel_ov) -{ - iobuf_t b; - size_t dummy_len = 0; - int rc = 0; - - if (a->directfp) - BUG (); - - if (a->use == 2 && (rc = iobuf_flush (a))) - return rc; - /* make a copy of the current stream, so that - * A is the new stream and B the original one. - * The contents of the buffers are transferred to the - * new stream. - */ - b = xmalloc (sizeof *b); - memcpy (b, a, sizeof *b); - /* fixme: it is stupid to keep a copy of the name at every level - * but we need the name somewhere because the name known by file_filter - * may have been released when we need the name of the file */ - b->real_fname = a->real_fname ? xstrdup (a->real_fname) : NULL; - /* remove the filter stuff from the new stream */ - a->filter = NULL; - a->filter_ov = NULL; - a->filter_ov_owner = 0; - a->filter_eof = 0; - if (a->use == 3) - a->use = 2; /* make a write stream from a temp stream */ - - if (a->use == 2) - { /* allocate a fresh buffer for the - original stream */ - b->d.buf = xmalloc (a->d.size); - b->d.len = 0; - b->d.start = 0; - } - else - { /* allocate a fresh buffer for the new - stream */ - a->d.buf = xmalloc (a->d.size); - a->d.len = 0; - a->d.start = 0; - } - /* disable nlimit for the new stream */ - a->ntotal = b->ntotal + b->nbytes; - a->nlimit = a->nbytes = 0; - a->nofast &= ~1; - /* make a link from the new stream to the original stream */ - a->chain = b; - a->opaque = b->opaque; - - /* setup the function on the new stream */ - a->filter = f; - a->filter_ov = ov; - a->filter_ov_owner = rel_ov; - - a->subno = b->subno + 1; - f (ov, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &dummy_len); - - if (DBG_IOBUF) - { - log_debug ("iobuf-%d.%d: push `%s'\n", a->no, a->subno, a->desc); - print_chain (a); - } - - /* now we can initialize the new function if we have one */ - if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_INIT, a->chain, - NULL, &dummy_len))) - log_error ("IOBUFCTRL_INIT failed: %s\n", gpg_strerror (rc)); - return rc; -} - -/**************** - * Remove an i/o filter. - */ -int -pop_filter (iobuf_t a, int (*f) (void *opaque, int control, - iobuf_t chain, byte * buf, size_t * len), - void *ov) -{ - iobuf_t b; - size_t dummy_len = 0; - int rc = 0; - - if (a->directfp) - BUG (); - - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: pop `%s'\n", a->no, a->subno, a->desc); - if (!a->filter) - { /* this is simple */ - b = a->chain; - assert (b); - xfree (a->d.buf); - xfree (a->real_fname); - memcpy (a, b, sizeof *a); - xfree (b); - return 0; - } - for (b = a; b; b = b->chain) - if (b->filter == f && (!ov || b->filter_ov == ov)) - break; - if (!b) - log_bug ("pop_filter(): filter function not found\n"); - - /* flush this stream if it is an output stream */ - if (a->use == 2 && (rc = iobuf_flush (b))) - { - log_error ("iobuf_flush failed in pop_filter: %s\n", gpg_strerror (rc)); - return rc; - } - /* and tell the filter to free it self */ - if (b->filter && (rc = b->filter (b->filter_ov, IOBUFCTRL_FREE, b->chain, - NULL, &dummy_len))) - { - log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc)); - return rc; - } - if (b->filter_ov && b->filter_ov_owner) - { - xfree (b->filter_ov); - b->filter_ov = NULL; - } - - - /* and see how to remove it */ - if (a == b && !b->chain) - log_bug ("can't remove the last filter from the chain\n"); - else if (a == b) - { /* remove the first iobuf from the chain */ - /* everything from b is copied to a. This is save because - * a flush has been done on the to be removed entry - */ - b = a->chain; - xfree (a->d.buf); - xfree (a->real_fname); - memcpy (a, b, sizeof *a); - xfree (b); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: popped filter\n", a->no, a->subno); - } - else if (!b->chain) - { /* remove the last iobuf from the chain */ - log_bug ("Ohh jeee, trying to remove a head filter\n"); - } - else - { /* remove an intermediate iobuf from the chain */ - log_bug ("Ohh jeee, trying to remove an intermediate filter\n"); - } - - return rc; -} - - -/**************** - * read underflow: read more bytes into the buffer and return - * the first byte or -1 on EOF. - */ -static int -underflow (iobuf_t a) -{ - size_t len; - int rc; - - assert (a->d.start == a->d.len); - if (a->use == 3) - return -1; /* EOF because a temp buffer can't do an underflow */ - - if (a->filter_eof) - { - if (a->chain) - { - iobuf_t b = a->chain; - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: pop `%s' in underflow\n", - a->no, a->subno, a->desc); - xfree (a->d.buf); - xfree (a->real_fname); - memcpy (a, b, sizeof *a); - xfree (b); - print_chain (a); - } - else - a->filter_eof = 0; /* for the top level filter */ - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: underflow: eof (due to filter eof)\n", - a->no, a->subno); - return -1; /* return one(!) EOF */ - } - if (a->error) - { - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: error\n", a->no, a->subno); - return -1; - } - - if (a->directfp) - { - FILE *fp = a->directfp; - - len = fread (a->d.buf, 1, a->d.size, fp); - if (len < a->d.size) - { - if (ferror (fp)) - a->error = gpg_error_from_errno (errno); - } - a->d.len = len; - a->d.start = 0; - return len ? a->d.buf[a->d.start++] : -1; - } - - - if (a->filter) - { - len = a->d.size; - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: underflow: req=%lu\n", - a->no, a->subno, (ulong) len); - rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain, - a->d.buf, &len); - if (DBG_IOBUF) - { - log_debug ("iobuf-%d.%d: underflow: got=%lu rc=%d\n", - a->no, a->subno, (ulong) len, rc); -/* if( a->no == 1 ) */ -/* log_hexdump (" data:", a->d.buf, len); */ - } - if (a->use == 1 && rc == -1) - { /* EOF: we can remove the filter */ - size_t dummy_len = 0; - - /* and tell the filter to free itself */ - if ((rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, a->chain, - NULL, &dummy_len))) - log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc)); - if (a->filter_ov && a->filter_ov_owner) - { - xfree (a->filter_ov); - a->filter_ov = NULL; - } - a->filter = NULL; - a->desc = NULL; - a->filter_ov = NULL; - a->filter_eof = 1; - if (!len && a->chain) - { - iobuf_t b = a->chain; - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: pop `%s' in underflow (!len)\n", - a->no, a->subno, a->desc); - xfree (a->d.buf); - xfree (a->real_fname); - memcpy (a, b, sizeof *a); - xfree (b); - print_chain (a); - } - } - else if (rc) - a->error = rc; - - if (!len) - { - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: underflow: eof\n", a->no, a->subno); - return -1; - } - a->d.len = len; - a->d.start = 0; - return a->d.buf[a->d.start++]; - } - else - { - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: underflow: eof (no filter)\n", - a->no, a->subno); - return -1; /* no filter; return EOF */ - } -} - - -int -iobuf_flush (iobuf_t a) -{ - size_t len; - int rc; - - if (a->directfp) - return 0; - - if (a->use == 3) - { /* increase the temp buffer */ - char *newbuf; - size_t newsize = a->d.size + 8192; - - if (DBG_IOBUF) - log_debug ("increasing temp iobuf from %lu to %lu\n", - (ulong) a->d.size, (ulong) newsize); - newbuf = xmalloc (newsize); - memcpy (newbuf, a->d.buf, a->d.len); - xfree (a->d.buf); - a->d.buf = newbuf; - a->d.size = newsize; - return 0; - } - else if (a->use != 2) - log_bug ("flush on non-output iobuf\n"); - else if (!a->filter) - log_bug ("iobuf_flush: no filter\n"); - len = a->d.len; - rc = a->filter (a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len); - if (!rc && len != a->d.len) - { - log_info ("iobuf_flush did not write all!\n"); - rc = GPG_ERR_INTERNAL; - } - else if (rc) - a->error = rc; - a->d.len = 0; - - return rc; -} - - -/**************** - * Read a byte from the iobuf; returns -1 on EOF - */ -int -iobuf_readbyte (iobuf_t a) -{ - int c; - - /* nlimit does not work together with unget */ - /* nbytes is also not valid! */ - if (a->unget.buf) - { - if (a->unget.start < a->unget.len) - return a->unget.buf[a->unget.start++]; - xfree (a->unget.buf); - a->unget.buf = NULL; - a->nofast &= ~2; - } - - if (a->nlimit && a->nbytes >= a->nlimit) - return -1; /* forced EOF */ - - if (a->d.start < a->d.len) - { - c = a->d.buf[a->d.start++]; - } - else if ((c = underflow (a)) == -1) - return -1; /* EOF */ - - a->nbytes++; - return c; -} - - -int -iobuf_read (iobuf_t a, byte * buf, unsigned buflen) -{ - int c, n; - - if (a->unget.buf || a->nlimit) - { - /* handle special cases */ - for (n = 0; n < buflen; n++) - { - if ((c = iobuf_readbyte (a)) == -1) - { - if (!n) - return -1; /* eof */ - break; - } - else if (buf) - *buf = c; - if (buf) - buf++; - } - return n; - } - - n = 0; - do - { - if (n < buflen && a->d.start < a->d.len) - { - unsigned size = a->d.len - a->d.start; - if (size > buflen - n) - size = buflen - n; - if (buf) - memcpy (buf, a->d.buf + a->d.start, size); - n += size; - a->d.start += size; - if (buf) - buf += size; - } - if (n < buflen) - { - if ((c = underflow (a)) == -1) - { - a->nbytes += n; - return n ? n : -1 /*EOF*/; - } - if (buf) - *buf++ = c; - n++; - } - } - while (n < buflen); - a->nbytes += n; - return n; -} - - -/**************** - * Have a look at the iobuf. - * NOTE: This only works in special cases. - */ -int -iobuf_peek (iobuf_t a, byte * buf, unsigned buflen) -{ - int n = 0; - - if (a->filter_eof) - return -1; - - if (!(a->d.start < a->d.len)) - { - if (underflow (a) == -1) - return -1; - /* and unget this character */ - assert (a->d.start == 1); - a->d.start = 0; - } - - for (n = 0; n < buflen && (a->d.start + n) < a->d.len; n++, buf++) - *buf = a->d.buf[n]; - return n; -} - - - - -int -iobuf_writebyte (iobuf_t a, unsigned c) -{ - int rc; - - if (a->directfp) - BUG (); - - if (a->d.len == a->d.size) - if ((rc=iobuf_flush (a))) - return rc; - - assert (a->d.len < a->d.size); - a->d.buf[a->d.len++] = c; - return 0; -} - - -int -iobuf_write (iobuf_t a, byte * buf, unsigned buflen) -{ - int rc; - - if (a->directfp) - BUG (); - - do - { - if (buflen && a->d.len < a->d.size) - { - unsigned size = a->d.size - a->d.len; - if (size > buflen) - size = buflen; - memcpy (a->d.buf + a->d.len, buf, size); - buflen -= size; - buf += size; - a->d.len += size; - } - if (buflen) - { - rc = iobuf_flush (a); - if (rc) - return rc; - } - } - while (buflen); - return 0; -} - - -int -iobuf_writestr (iobuf_t a, const char *buf) -{ - int rc; - - for (; *buf; buf++) - if ((rc=iobuf_writebyte (a, *buf))) - return rc; - return 0; -} - - - -/**************** - * copy the contents of TEMP to A. - */ -int -iobuf_write_temp (iobuf_t a, iobuf_t temp) -{ - while (temp->chain) - pop_filter (temp, temp->filter, NULL); - return iobuf_write (a, temp->d.buf, temp->d.len); -} - -/**************** - * copy the contents of the temp io stream to BUFFER. - */ -size_t -iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen) -{ - size_t n = a->d.len; - - if (n > buflen) - n = buflen; - memcpy (buffer, a->d.buf, n); - return n; -} - - -/**************** - * Call this function to terminate processing of the temp stream - * without closing it. This removes all filters from the stream - * makes sure that iobuf_get_temp_{buffer,length}() returns correct - * values. - */ -void -iobuf_flush_temp (iobuf_t temp) -{ - while (temp->chain) - pop_filter (temp, temp->filter, NULL); -} - - -/**************** - * Set a limit on how many bytes may be read from the input stream A. - * Setting the limit to 0 disables this feature. - */ -void -iobuf_set_limit (iobuf_t a, off_t nlimit) -{ - if (nlimit) - a->nofast |= 1; - else - a->nofast &= ~1; - a->nlimit = nlimit; - a->ntotal += a->nbytes; - a->nbytes = 0; -} - - - -/**************** - * Return the length of an open file - */ -off_t -iobuf_get_filelength (iobuf_t a) -{ - struct stat st; - - if (a->directfp) - { - FILE *fp = a->directfp; - - if (!fstat (fileno (fp), &st)) - return st.st_size; - log_error ("fstat() failed: %s\n", strerror (errno)); - return 0; - } - - /* Hmmm: file_filter may have already been removed */ - for (; a; a = a->chain) - if (!a->chain && a->filter == file_filter) - { - file_filter_ctx_t *b = a->filter_ov; - FILEP_OR_FD fp = b->fp; - -#if defined(HAVE_DOSISH_SYSTEM) && !defined(FILE_FILTER_USES_STDIO) - ulong size; - - if ((size = GetFileSize (fp, NULL)) != 0xffffffff) - return size; - log_error ("GetFileSize for handle %p failed: ec=%d\n", - fp, (int) GetLastError ()); -#else - if (!fstat (my_fileno (fp), &st)) - return st.st_size; - log_error ("fstat() failed: %s\n", strerror (errno)); -#endif - break; - } - - return 0; -} - -/**************** - * Tell the file position, where the next read will take place - */ -off_t -iobuf_tell (iobuf_t a) -{ - return a->ntotal + a->nbytes; -} - - -#if !defined(HAVE_FSEEKO) && !defined(fseeko) - -#ifdef HAVE_LIMITS_H -# include -#endif -#ifndef LONG_MAX -# define LONG_MAX ((long) ((unsigned long) -1 >> 1)) -#endif -#ifndef LONG_MIN -# define LONG_MIN (-1 - LONG_MAX) -#endif - -/**************** - * A substitute for fseeko, for hosts that don't have it. - */ -static int -fseeko (FILE * stream, off_t newpos, int whence) -{ - while (newpos != (long) newpos) - { - long pos = newpos < 0 ? LONG_MIN : LONG_MAX; - if (fseek (stream, pos, whence) != 0) - return -1; - newpos -= pos; - whence = SEEK_CUR; - } - return fseek (stream, (long) newpos, whence); -} -#endif - -/**************** - * This is a very limited implementation. It simply discards all internal - * buffering and removes all filters but the first one. - */ -int -iobuf_seek (iobuf_t a, off_t newpos) -{ - file_filter_ctx_t *b = NULL; - - if (a->directfp) - { - FILE *fp = a->directfp; - if (fseeko (fp, newpos, SEEK_SET)) - { - log_error ("can't seek: %s\n", strerror (errno)); - return -1; - } - clearerr (fp); - } - else - { - for (; a; a = a->chain) - { - if (!a->chain && a->filter == file_filter) - { - b = a->filter_ov; - break; - } - } - if (!a) - return -1; -#ifdef FILE_FILTER_USES_STDIO - if (fseeko (b->fp, newpos, SEEK_SET)) - { - log_error ("can't fseek: %s\n", strerror (errno)); - return -1; - } -#else -#ifdef HAVE_DOSISH_SYSTEM - if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff) - { - log_error ("SetFilePointer failed on handle %p: ec=%d\n", - b->fp, (int) GetLastError ()); - return -1; - } -#else - if (lseek (b->fp, newpos, SEEK_SET) == (off_t) - 1) - { - log_error ("can't lseek: %s\n", strerror (errno)); - return -1; - } -#endif -#endif - } - a->d.len = 0; /* discard buffer */ - a->d.start = 0; - a->nbytes = 0; - a->nlimit = 0; - a->nofast &= ~1; - a->ntotal = newpos; - a->error = 0; - /* remove filters, but the last */ - if (a->chain) - log_debug ("pop_filter called in iobuf_seek - please report\n"); - while (a->chain) - pop_filter (a, a->filter, NULL); - - return 0; -} - - - - - - -/**************** - * Retrieve the real filename - */ -const char * -iobuf_get_real_fname (iobuf_t a) -{ - if (a->real_fname) - return a->real_fname; - - /* the old solution */ - for (; a; a = a->chain) - if (!a->chain && a->filter == file_filter) - { - file_filter_ctx_t *b = a->filter_ov; - return b->print_only_name ? NULL : b->fname; - } - - return NULL; -} - - -/**************** - * Retrieve the filename - */ -const char * -iobuf_get_fname (iobuf_t a) -{ - for (; a; a = a->chain) - if (!a->chain && a->filter == file_filter) - { - file_filter_ctx_t *b = a->filter_ov; - return b->fname; - } - - return NULL; -} - -/**************** - * Start the block write mode, see rfc1991.new for details. - * A value of 0 for N stops this mode (flushes and writes - * the end marker) - */ -void -iobuf_set_block_mode (iobuf_t a, size_t n) -{ - block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx); - - assert (a->use == 1 || a->use == 2); - ctx->use = a->use; - if (!n) - { - if (a->use == 1) - log_debug ("pop_filter called in set_block_mode - please report\n"); - pop_filter (a, block_filter, NULL); - } - else - { - ctx->size = n; /* only needed for use 2 */ - iobuf_push_filter (a, block_filter, ctx); - } -} - -/**************** - * enable partial block mode as described in the OpenPGP draft. - * LEN is the first length byte on read, but ignored on writes. - */ -void -iobuf_set_partial_block_mode (iobuf_t a, size_t len) -{ - block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx); - - assert (a->use == 1 || a->use == 2); - ctx->use = a->use; - if (!len) - { - if (a->use == 1) - log_debug ("pop_filter called in set_partial_block_mode" - " - please report\n"); - pop_filter (a, block_filter, NULL); - } - else - { - ctx->partial = 1; - ctx->size = 0; - ctx->first_c = len; - iobuf_push_filter (a, block_filter, ctx); - } -} - - -/**************** - * Checks whether the stream is in block mode - * Note: This does not work if other filters are pushed on the stream. - */ -int -iobuf_in_block_mode (iobuf_t a) -{ - if (a && a->filter == block_filter) - return 1; /* yes */ - return 0; /* no */ -} - - -/**************** - * Same as fgets() but if the buffer is too short a larger one will - * be allocated up to some limit *max_length. - * A line is considered a byte stream ending in a LF. - * Returns the length of the line. EOF is indicated by a line of - * length zero. The last LF may be missing due to an EOF. - * is max_length is zero on return, the line has been truncated. - * - * Note: The buffer is allocated with enough space to append a CR,LF,EOL - */ -unsigned int -iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, - unsigned *length_of_buffer, unsigned *max_length) -{ - int c; - char *buffer = *addr_of_buffer; - unsigned length = *length_of_buffer; - unsigned nbytes = 0; - unsigned maxlen = *max_length; - char *p; - - if (!buffer) - { /* must allocate a new buffer */ - length = 256; - buffer = xmalloc (length); - *addr_of_buffer = buffer; - *length_of_buffer = length; - } - - length -= 3; /* reserve 3 bytes (cr,lf,eol) */ - p = buffer; - while ((c = iobuf_get (a)) != -1) - { - if (nbytes == length) - { /* increase the buffer */ - if (length > maxlen) - { /* this is out limit */ - /* skip the rest of the line */ - while (c != '\n' && (c = iobuf_get (a)) != -1) - ; - *p++ = '\n'; /* always append a LF (we have reserved space) */ - nbytes++; - *max_length = 0; /* indicate truncation */ - break; - } - length += 3; /* correct for the reserved byte */ - length += length < 1024 ? 256 : 1024; - buffer = xrealloc (buffer, length); - *addr_of_buffer = buffer; - *length_of_buffer = length; - length -= 3; /* and reserve again */ - p = buffer + nbytes; - } - *p++ = c; - nbytes++; - if (c == '\n') - break; - } - *p = 0; /* make sure the line is a string */ - - return nbytes; -} - -/* This is the non iobuf specific function */ -int -iobuf_translate_file_handle (int fd, int for_write) -{ -#ifdef _WIN32 - { - int x; - - if (fd <= 2) - return fd; /* do not do this for error, stdin, stdout, stderr */ - - x = _open_osfhandle (fd, for_write ? 1 : 0); - if (x == -1) - log_error ("failed to translate osfhandle %p\n", (void *) fd); - else - { - /*log_info ("_open_osfhandle %p yields %d%s\n", - (void*)fd, x, for_write? " for writing":"" ); */ - fd = x; - } - } -#endif - return fd; -} - -static int -translate_file_handle (int fd, int for_write) -{ -#ifdef _WIN32 -#ifdef FILE_FILTER_USES_STDIO - fd = iobuf_translate_file_handle (fd, for_write); -#else - { - int x; - - if (fd == 0) - x = (int) GetStdHandle (STD_INPUT_HANDLE); - else if (fd == 1) - x = (int) GetStdHandle (STD_OUTPUT_HANDLE); - else if (fd == 2) - x = (int) GetStdHandle (STD_ERROR_HANDLE); - else - x = fd; - - if (x == -1) - log_debug ("GetStdHandle(%d) failed: ec=%d\n", - fd, (int) GetLastError ()); - - fd = x; - } -#endif -#endif - return fd; -} diff --git a/common/iobuf.h b/common/iobuf.h deleted file mode 100644 index 0af94e22d..000000000 --- a/common/iobuf.h +++ /dev/null @@ -1,170 +0,0 @@ -/* iobuf.h - I/O buffer - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_IOBUF_H -#define GNUPG_COMMON_IOBUF_H - -#include "../include/types.h" /* fixme: should be moved elsewhere. */ - - -#define DBG_IOBUF iobuf_debug_mode - - -#define IOBUFCTRL_INIT 1 -#define IOBUFCTRL_FREE 2 -#define IOBUFCTRL_UNDERFLOW 3 -#define IOBUFCTRL_FLUSH 4 -#define IOBUFCTRL_DESC 5 -#define IOBUFCTRL_CANCEL 6 -#define IOBUFCTRL_USER 16 - -typedef struct iobuf_struct *iobuf_t; - -/* fixme: we should hide most of this stuff */ -struct iobuf_struct -{ - int use; /* 1 input , 2 output, 3 temp */ - off_t nlimit; - off_t nbytes; /* used together with nlimit */ - off_t ntotal; /* total bytes read (position of stream) */ - int nofast; /* used by the iobuf_get() */ - void *directfp; - struct - { - size_t size; /* allocated size */ - size_t start; /* number of invalid bytes at the begin of the buffer */ - size_t len; /* currently filled to this size */ - byte *buf; - } - d; - int filter_eof; - int error; - int (*filter) (void *opaque, int control, - iobuf_t chain, byte * buf, size_t * len); - void *filter_ov; /* value for opaque */ - int filter_ov_owner; - char *real_fname; - iobuf_t chain; /* next iobuf used for i/o if any - (passed to filter) */ - int no, subno; - const char *desc; - void *opaque; /* can be used to hold any information - this value is copied to all - instances */ - struct - { - size_t size; /* allocated size */ - size_t start; /* number of invalid bytes at the - begin of the buffer */ - size_t len; /* currently filled to this size */ - byte *buf; - } - unget; -}; - -#ifndef EXTERN_UNLESS_MAIN_MODULE -#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE) -#define EXTERN_UNLESS_MAIN_MODULE extern -#else -#define EXTERN_UNLESS_MAIN_MODULE -#endif -#endif -EXTERN_UNLESS_MAIN_MODULE int iobuf_debug_mode; - -void iobuf_enable_special_filenames (int yes); -iobuf_t iobuf_alloc (int use, size_t bufsize); -iobuf_t iobuf_temp (void); -iobuf_t iobuf_temp_with_content (const char *buffer, size_t length); -iobuf_t iobuf_open (const char *fname); -iobuf_t iobuf_fdopen (int fd, const char *mode); -iobuf_t iobuf_sockopen (int fd, const char *mode); -iobuf_t iobuf_create (const char *fname); -iobuf_t iobuf_append (const char *fname); -iobuf_t iobuf_openrw (const char *fname); -int iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval); -int iobuf_close (iobuf_t iobuf); -int iobuf_cancel (iobuf_t iobuf); - -int iobuf_push_filter (iobuf_t a, int (*f) (void *opaque, int control, - iobuf_t chain, byte * buf, - size_t * len), void *ov); -int iobuf_push_filter2 (iobuf_t a, - int (*f) (void *opaque, int control, iobuf_t chain, - byte * buf, size_t * len), void *ov, - int rel_ov); -int iobuf_flush (iobuf_t a); -void iobuf_clear_eof (iobuf_t a); -#define iobuf_set_error(a) do { (a)->error = 1; } while(0) -#define iobuf_error(a) ((a)->error) - -void iobuf_set_limit (iobuf_t a, off_t nlimit); - -off_t iobuf_tell (iobuf_t a); -int iobuf_seek (iobuf_t a, off_t newpos); - -int iobuf_readbyte (iobuf_t a); -int iobuf_read (iobuf_t a, byte * buf, unsigned buflen); -unsigned iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, - unsigned *length_of_buffer, unsigned *max_length); -int iobuf_peek (iobuf_t a, byte * buf, unsigned buflen); -int iobuf_writebyte (iobuf_t a, unsigned c); -int iobuf_write (iobuf_t a, byte * buf, unsigned buflen); -int iobuf_writestr (iobuf_t a, const char *buf); - -void iobuf_flush_temp (iobuf_t temp); -int iobuf_write_temp (iobuf_t a, iobuf_t temp); -size_t iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen); -void iobuf_unget_and_close_temp (iobuf_t a, iobuf_t temp); - -off_t iobuf_get_filelength (iobuf_t a); -#define IOBUF_FILELENGTH_LIMIT 0xffffffff -const char *iobuf_get_real_fname (iobuf_t a); -const char *iobuf_get_fname (iobuf_t a); - -void iobuf_set_block_mode (iobuf_t a, size_t n); -void iobuf_set_partial_block_mode (iobuf_t a, size_t len); -int iobuf_in_block_mode (iobuf_t a); - -int iobuf_translate_file_handle (int fd, int for_write); - - -/* get a byte form the iobuf; must check for eof prior to this function - * this function returns values in the range 0 .. 255 or -1 to indicate EOF - * iobuf_get_noeof() does not return -1 to indicate EOF, but masks the - * returned value to be in the range 0 ..255. - */ -#define iobuf_get(a) \ - ( ((a)->nofast || (a)->d.start >= (a)->d.len )? \ - iobuf_readbyte((a)) : ( (a)->nbytes++, (a)->d.buf[(a)->d.start++] ) ) -#define iobuf_get_noeof(a) (iobuf_get((a))&0xff) - -/* write a byte to the iobuf and return true on write error - * This macro does only write the low order byte - */ -#define iobuf_put(a,c) iobuf_writebyte(a,c) - -#define iobuf_where(a) "[don't know]" -#define iobuf_id(a) ((a)->no) - -#define iobuf_get_temp_buffer(a) ( (a)->d.buf ) -#define iobuf_get_temp_length(a) ( (a)->d.len ) -#define iobuf_is_temp(a) ( (a)->use == 3 ) - -#endif /*GNUPG_COMMON_IOBUF_H*/ diff --git a/common/isascii.c b/common/isascii.c deleted file mode 100644 index 565c71664..000000000 --- a/common/isascii.c +++ /dev/null @@ -1,29 +0,0 @@ -/* isascii.c - Replacement for isascii. - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -int -isascii (int c) -{ - return (((c) & ~0x7f) == 0); -} diff --git a/common/maperror.c b/common/maperror.c deleted file mode 100644 index 2f6f1b159..000000000 --- a/common/maperror.c +++ /dev/null @@ -1,105 +0,0 @@ -/* maperror.c - Error mapping - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "util.h" -#include "errors.h" - - -/* Map Assuan error code ERR to an GPG_ERR_ code. We need to - distinguish between genuine (and legacy) Assuan error codes and - application error codes shared with all GnuPG modules. The rule is - simple: All errors with a gpg_err_source of UNKNOWN are genuine - Assuan codes all others are passed verbatim through. */ -gpg_error_t -map_assuan_err (int err) -{ - gpg_err_code_t ec; - - if (gpg_err_source (err)) - return err; - - switch (err) - { - case -1: ec = GPG_ERR_EOF; break; - case 0: ec = 0; break; - - case ASSUAN_Canceled: ec = GPG_ERR_CANCELED; break; - case ASSUAN_Invalid_Index: ec = GPG_ERR_INV_INDEX; break; - - case ASSUAN_Not_Implemented: ec = GPG_ERR_NOT_IMPLEMENTED; break; - case ASSUAN_Server_Fault: ec = GPG_ERR_ASSUAN_SERVER_FAULT; break; - case ASSUAN_No_Public_Key: ec = GPG_ERR_NO_PUBKEY; break; - case ASSUAN_No_Secret_Key: ec = GPG_ERR_NO_SECKEY; break; - - case ASSUAN_Cert_Revoked: ec = GPG_ERR_CERT_REVOKED; break; - case ASSUAN_No_CRL_For_Cert: ec = GPG_ERR_NO_CRL_KNOWN; break; - case ASSUAN_CRL_Too_Old: ec = GPG_ERR_CRL_TOO_OLD; break; - - case ASSUAN_Not_Trusted: ec = GPG_ERR_NOT_TRUSTED; break; - - case ASSUAN_Card_Error: ec = GPG_ERR_CARD; break; - case ASSUAN_Invalid_Card: ec = GPG_ERR_INV_CARD; break; - case ASSUAN_No_PKCS15_App: ec = GPG_ERR_NO_PKCS15_APP; break; - case ASSUAN_Card_Not_Present: ec= GPG_ERR_CARD_NOT_PRESENT; break; - case ASSUAN_Not_Confirmed: ec = GPG_ERR_NOT_CONFIRMED; break; - case ASSUAN_Invalid_Id: ec = GPG_ERR_INV_ID; break; - - case ASSUAN_Locale_Problem: ec = GPG_ERR_LOCALE_PROBLEM; break; - - default: - ec = err < 100? GPG_ERR_ASSUAN_SERVER_FAULT : GPG_ERR_ASSUAN; - break; - } - return gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, ec); -} - -/* Map GPG_xERR_xx error codes to Assuan status codes */ -int -map_to_assuan_status (int rc) -{ - gpg_err_code_t ec = gpg_err_code (rc); - gpg_err_source_t es = gpg_err_source (rc); - - if (!rc) - return 0; - if (!es) - { - es = GPG_ERR_SOURCE_USER_4; /* This should not happen, but we - need to make sure to pass a new - Assuan errorcode along. */ - log_debug ("map_to_assuan_status called with no error source\n"); - } - - if (ec == -1) - ec = GPG_ERR_NO_DATA; /* That used to be ASSUAN_No_Data_Available. */ - - return gpg_err_make (es, ec); -} diff --git a/common/membuf.c b/common/membuf.c deleted file mode 100644 index 69e4ab908..000000000 --- a/common/membuf.c +++ /dev/null @@ -1,89 +0,0 @@ -/* membuf.c - A simple implementation of a dynamic buffer - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include - -#include "membuf.h" - -#include "util.h" - - -/* A simple implementation of a dynamic buffer. Use init_membuf() to - create a buffer, put_membuf to append bytes and get_membuf to - release and return the buffer. Allocation errors are detected but - only returned at the final get_membuf(), this helps not to clutter - the code with out of core checks. */ - -void -init_membuf (membuf_t *mb, int initiallen) -{ - mb->len = 0; - mb->size = initiallen; - mb->out_of_core = 0; - mb->buf = xtrymalloc (initiallen); - if (!mb->buf) - mb->out_of_core = errno; -} - - -void -put_membuf (membuf_t *mb, const void *buf, size_t len) -{ - if (mb->out_of_core) - return; - - if (mb->len + len >= mb->size) - { - char *p; - - mb->size += len + 1024; - p = xtryrealloc (mb->buf, mb->size); - if (!p) - { - mb->out_of_core = errno; - return; - } - mb->buf = p; - } - memcpy (mb->buf + mb->len, buf, len); - mb->len += len; -} - - -void * -get_membuf (membuf_t *mb, size_t *len) -{ - char *p; - - if (mb->out_of_core) - { - xfree (mb->buf); - mb->buf = NULL; - return NULL; - } - - p = mb->buf; - *len = mb->len; - mb->buf = NULL; - mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */ - return p; -} diff --git a/common/membuf.h b/common/membuf.h deleted file mode 100644 index c199363cc..000000000 --- a/common/membuf.h +++ /dev/null @@ -1,41 +0,0 @@ -/* membuf.h - A simple implementation of a dynamic buffer - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_MEMBUF_H -#define GNUPG_COMMON_MEMBUF_H - -/* The definition of the structure is private, we only need it here, - so it can be allocated on the stack. */ -struct private_membuf_s { - size_t len; - size_t size; - char *buf; - int out_of_core; -}; - -typedef struct private_membuf_s membuf_t; - - -void init_membuf (membuf_t *mb, int initiallen); -void put_membuf (membuf_t *mb, const void *buf, size_t len); -void *get_membuf (membuf_t *mb, size_t *len); - - -#endif /*GNUPG_COMMON_MEMBUF_H*/ diff --git a/common/miscellaneous.c b/common/miscellaneous.c deleted file mode 100644 index 86b0fcb3a..000000000 --- a/common/miscellaneous.c +++ /dev/null @@ -1,127 +0,0 @@ -/* miscellaneous.c - Stuff not fitting elsewhere - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include - -#include "util.h" -#include "iobuf.h" - - -/* Decide whether the filename is stdout or a real filename and return - * an appropriate string. */ -const char * -print_fname_stdout (const char *s) -{ - if( !s || (*s == '-' && !s[1]) ) - return "[stdout]"; - return s; -} - - -/* Decide whether the filename is stdin or a real filename and return - * an appropriate string. */ -const char * -print_fname_stdin (const char *s) -{ - if( !s || (*s == '-' && !s[1]) ) - return "[stdin]"; - return s; -} - -void -print_string( FILE *fp, const byte *p, size_t n, int delim ) -{ - print_sanitized_buffer (fp, p, n, delim); -} - -void -print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim ) -{ - print_sanitized_utf8_buffer (fp, p, n, delim); -} - -void -print_utf8_string( FILE *fp, const byte *p, size_t n ) -{ - print_utf8_string2 (fp, p, n, 0); -} - -char * -make_printable_string( const byte *p, size_t n, int delim ) -{ - return sanitize_buffer (p, n, delim); -} - - -/* - * Check if the file is compressed. - */ -int -is_file_compressed (const char *s, int *ret_rc) -{ - iobuf_t a; - byte buf[4]; - int i, rc = 0; - - struct magic_compress_s { - size_t len; - byte magic[4]; - } magic[] = { - { 3, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */ - { 3, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */ - { 4, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */ - }; - - if ( !s || (*s == '-' && !s[1]) || !ret_rc ) - return 0; /* We can't check stdin or no file was given */ - - a = iobuf_open( s ); - if ( a == NULL ) { - *ret_rc = gpg_error_from_errno (errno); - return 0; - } - - if ( iobuf_get_filelength( a ) < 4 ) { - *ret_rc = 0; - goto leave; - } - - if ( iobuf_read( a, buf, 4 ) == -1 ) { - *ret_rc = a->error; - goto leave; - } - - for ( i = 0; i < DIM( magic ); i++ ) { - if ( !memcmp( buf, magic[i].magic, magic[i].len ) ) { - *ret_rc = 0; - rc = 1; - break; - } - } - -leave: - iobuf_close( a ); - return rc; -} - - - diff --git a/common/mkdtemp.c b/common/mkdtemp.c deleted file mode 100644 index abe731e0a..000000000 --- a/common/mkdtemp.c +++ /dev/null @@ -1,96 +0,0 @@ -/* mkdtemp.c - libc replacement function - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* This is a replacement function for mkdtemp in case the platform - we're building on (like mine!) doesn't have it. */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef MKDIR_TAKES_ONE_ARG -# undef mkdir -# define mkdir(a,b) mkdir(a) -#endif - -char *mkdtemp(char *template) -{ - int attempts,idx,count=0; - unsigned char *ch; - - idx=strlen(template); - - /* Walk backwards to count all the Xes */ - while(idx>0 && template[idx-1]=='X') - { - count++; - idx--; - } - - if(count==0) - { - errno=EINVAL; - return NULL; - } - - ch=&template[idx]; - - /* Try 4 times to make the temp directory */ - for(attempts=0;attempts<4;attempts++) - { - int remaining=count; - char *marker=ch; - unsigned char *randombits; - - idx=0; - - randombits = gcry_xmalloc (4*remaining); - gcry_create_nonce (randombits, 4*remaining); - - while(remaining>1) - { - sprintf(marker,"%02X",randombits[idx++]); - marker+=2; - remaining-=2; - } - - /* Any leftover Xes? get_random_bits rounds up to full bytes, - so this is safe. */ - if(remaining>0) - sprintf(marker,"%X",randombits[idx]&0xF); - - gcry_free (randombits); - - if(mkdir(template,0700)==0) - break; - } - - if(attempts==4) - return NULL; /* keeps the errno from mkdir, whatever it is */ - - return template; -} - - diff --git a/common/mkerrors b/common/mkerrors deleted file mode 100755 index 5a1ef33da..000000000 --- a/common/mkerrors +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh -# mkerrors - Extract error strings from errors.h -# and create C source for gnupg_strerror -# Copyright (C) 2001 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -cat < -#include -#include "errors.h" - -/** - * gnupg_strerror: - * @err: Error code - * - * This function returns a textual representaion of the given - * errorcode. If this is an unknown value, a string with the value - * is returned (Beware: it is hold in a static buffer). - * - * Return value: String with the error description. - **/ -const char * -gnupg_strerror (int err) -{ - const char *s; - static char buf[25]; - - switch (err) - { -EOF - -awk ' -/GNUPG_No_Error/ { okay=1 } -!okay {next} -/}/ { exit 0 } -/GNUPG_[A-Za-z_]*/ { print_code($1) } - - -function print_code( s ) -{ -printf " case %s: s=\"", s ; -gsub(/_/, " ", s ); -printf "%s\"; break;\n", tolower(substr(s,7)); -} -' - -cat < -#endif - -#include - -int -putc_unlocked (int c, FILE *stream) -{ - return putc (c, stream); -} diff --git a/common/sexp-parse.h b/common/sexp-parse.h deleted file mode 100644 index 89aa7210f..000000000 --- a/common/sexp-parse.h +++ /dev/null @@ -1,99 +0,0 @@ -/* sexp-parse.h - S-Exp helper functions - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef SEXP_PARSE_H -#define SEXP_PARSE_H - -#include - -/* Return the length of the next S-Exp part and update the pointer to - the first data byte. 0 is returned on error */ -static inline size_t -snext (unsigned char const **buf) -{ - const unsigned char *s; - int n; - - s = *buf; - for (n=0; *s && *s != ':' && (*s >= '0' && *s <= '9'); s++) - n = n*10 + (*s - '0'); - if (!n || *s != ':') - return 0; /* we don't allow empty lengths */ - *buf = s+1; - return n; -} - -/* Skip over the S-Expression BUF points to and update BUF to point to - the chacter right behind. DEPTH gives the initial number of open - lists and may be passed as a positive number to skip over the - remainder of an S-Expression if the current position is somewhere - in an S-Expression. The function may return an error code if it - encounters an impossible conditions */ -static inline gpg_error_t -sskip (unsigned char const **buf, int *depth) -{ - const unsigned char *s = *buf; - size_t n; - int d = *depth; - - while (d > 0) - { - if (*s == '(') - { - d++; - s++; - } - else if (*s == ')') - { - d--; - s++; - } - else - { - if (!d) - return gpg_error (GPG_ERR_INV_SEXP); - n = snext (&s); - if (!n) - return gpg_error (GPG_ERR_INV_SEXP); - s += n; - } - } - *buf = s; - *depth = d; - return 0; -} - - -/* Check whether the the string at the address BUF points to matches - the token. Return true on match and update BUF to point behind the - token. Return false and dont update tha buffer if it does not - match. */ -static inline int -smatch (unsigned char const **buf, size_t buflen, const char *token) -{ - size_t toklen = strlen (token); - - if (buflen != toklen || memcmp (*buf, token, toklen)) - return 0; - *buf += toklen; - return 1; -} - -#endif /*SEXP_PARSE_H*/ diff --git a/common/signal.c b/common/signal.c deleted file mode 100644 index dc026c10f..000000000 --- a/common/signal.c +++ /dev/null @@ -1,226 +0,0 @@ -/* signal.c - signal handling - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "util.h" - - -static volatile int caught_fatal_sig; -static volatile int caught_sigusr1; -static void (*cleanup_fnc)(void); - - -static void -init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign ) -{ -#ifndef HAVE_DOSISH_SYSTEM -# ifdef HAVE_SIGACTION - struct sigaction oact, nact; - - if (check_ign) - { - /* we don't want to change an IGN handler */ - sigaction (sig, NULL, &oact ); - if (oact.sa_handler == SIG_IGN ) - return; - } - - nact.sa_handler = handler; - sigemptyset (&nact.sa_mask); - nact.sa_flags = 0; - sigaction ( sig, &nact, NULL); -# else - RETSIGTYPE (*ohandler)(int); - - ohandler = signal (sig, handler); - if (check_ign && ohandler == SIG_IGN) - { - /* Change it back if it was already set to IGN */ - signal (sig, SIG_IGN); - } -# endif -#endif /*!HAVE_DOSISH_SYSTEM*/ -} - -static const char * -get_signal_name( int signum ) -{ -#if defined(SYS_SIGLIST_DECLARED) && defined(NSIG) - return (signum >= 0 && signum < NSIG) ? sys_siglist[signum] : "?"; -#else - return "some signal"; -#endif -} - -static RETSIGTYPE -got_fatal_signal (int sig) -{ - const char *s; - - if (caught_fatal_sig) - raise (sig); - caught_fatal_sig = 1; - - if (cleanup_fnc) - cleanup_fnc (); - /* better don't translate these messages */ - write (2, "\n", 1 ); - s = log_get_prefix (NULL); - if (s) - write(2, s, strlen (s)); - write (2, ": ", 2 ); - s = get_signal_name(sig); - write (2, s, strlen(s) ); - write (2, " caught ... exiting\n", 20); - - /* reset action to default action and raise signal again */ - init_one_signal (sig, SIG_DFL, 0); - /* fixme: remove_lockfiles ();*/ -#ifdef __riscos__ - close_fds (); -#endif /* __riscos__ */ - raise( sig ); -} - - -static RETSIGTYPE -got_usr_signal (int sig) -{ - caught_sigusr1 = 1; -} - - -void -gnupg_init_signals (int mode, void (*fast_cleanup)(void)) -{ - assert (!mode); - - cleanup_fnc = fast_cleanup; -#ifndef HAVE_DOSISH_SYSTEM - init_one_signal (SIGINT, got_fatal_signal, 1 ); - init_one_signal (SIGHUP, got_fatal_signal, 1 ); - init_one_signal (SIGTERM, got_fatal_signal, 1 ); - init_one_signal (SIGQUIT, got_fatal_signal, 1 ); - init_one_signal (SIGSEGV, got_fatal_signal, 1 ); - init_one_signal (SIGUSR1, got_usr_signal, 0 ); - init_one_signal (SIGPIPE, SIG_IGN, 0 ); -#endif -} - -void -gnupg_pause_on_sigusr (int which) -{ -#ifndef HAVE_DOSISH_SYSTEM -# ifdef HAVE_SIGPROCMASK - sigset_t mask, oldmask; - - assert (which == 1); - sigemptyset( &mask ); - sigaddset( &mask, SIGUSR1 ); - - sigprocmask( SIG_BLOCK, &mask, &oldmask ); - while (!caught_sigusr1) - sigsuspend (&oldmask); - caught_sigusr1 = 0; - sigprocmask (SIG_UNBLOCK, &mask, NULL); -# else - assert (which == 1); - sighold (SIGUSR1); - while (!caught_sigusr1) - sigpause(SIGUSR1); - caught_sigusr1 = 0; - sigrelease(SIGUSR1); -# endif /*!HAVE_SIGPROCMASK*/ -#endif -} - - -static void -do_block( int block ) -{ -#ifndef HAVE_DOSISH_SYSTEM - static int is_blocked; -#ifdef HAVE_SIGPROCMASK - static sigset_t oldmask; - - if (block) - { - sigset_t newmask; - - if (is_blocked) - log_bug ("signals are already blocked\n"); - sigfillset( &newmask ); - sigprocmask( SIG_BLOCK, &newmask, &oldmask ); - is_blocked = 1; - } - else - { - if (!is_blocked) - log_bug("signals are not blocked\n"); - sigprocmask (SIG_SETMASK, &oldmask, NULL); - is_blocked = 0; - } -#else /*!HAVE_SIGPROCMASK*/ - static void (*disposition[MAXSIG])(); - int sig; - - if (block) - { - if (is_blocked) - log_bug("signals are already blocked\n"); - for (sig=1; sig < MAXSIG; sig++) - { - disposition[sig] = sigset (sig, SIG_HOLD); - } - is_blocked = 1; - } - else - { - if (!is_blocked) - log_bug ("signals are not blocked\n"); - for (sig=1; sig < MAXSIG; sig++) { - sigset (sig, disposition[sig]); - } - is_blocked = 0; - } -#endif /*!HAVE_SIGPROCMASK*/ -#endif /*HAVE_DOSISH_SYSTEM*/ -} - - -void -gnupg_block_all_signals () -{ - do_block(1); -} - -void -gnupg_unblock_all_signals () -{ - do_block(0); -} diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c deleted file mode 100644 index 36244b120..000000000 --- a/common/simple-pwquery.c +++ /dev/null @@ -1,493 +0,0 @@ -/* simple-pwquery.c - A simple password query cleint for gpg-agent - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* This module is intended as a standalone client implementation to - gpg-agent's GET_PASSPHRASE command. In particular it does not use - the Assuan library and can only cope with an already running - gpg-agent. Some stuff is configurable in the header file. */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LOCALE_H -#include -#endif - -#define SIMPLE_PWQUERY_IMPLEMENTATION 1 -#include "simple-pwquery.h" - -#if defined(SPWQ_USE_LOGGING) && !defined(HAVE_JNLIB_LOGGING) -# undef SPWQ_USE_LOGGING -#endif - -#ifndef _ -#define _(a) (a) -#endif - -#if !defined (hexdigitp) && !defined (xtoi_2) -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) -#endif - - -/* Write NBYTES of BUF to file descriptor FD. */ -static int -writen (int fd, const void *buf, size_t nbytes) -{ - size_t nleft = nbytes; - int nwritten; - - while (nleft > 0) - { - nwritten = write( fd, buf, nleft ); - if (nwritten < 0) - { - if (errno == EINTR) - nwritten = 0; - else { -#ifdef SPWQ_USE_LOGGING - log_error ("write failed: %s\n", strerror (errno)); -#endif - return SPWQ_IO_ERROR; - } - } - nleft -= nwritten; - buf = (const char*)buf + nwritten; - } - - return 0; -} - - -/* Read an entire line and return number of bytes read. */ -static int -readline (int fd, char *buf, size_t buflen) -{ - size_t nleft = buflen; - char *p; - int nread = 0; - - while (nleft > 0) - { - int n = read (fd, buf, nleft); - if (n < 0) - { - if (errno == EINTR) - continue; - return -(SPWQ_IO_ERROR); - } - else if (!n) - { - return -(SPWQ_PROTOCOL_ERROR); /* incomplete line */ - } - p = buf; - nleft -= n; - buf += n; - nread += n; - - for (; n && *p != '\n'; n--, p++) - ; - if (n) - { - break; /* at least one full line available - that's enough. - This function is just a simple implementation, so - it is okay to forget about pending bytes */ - } - } - - return nread; -} - - -/* Send an option to the agent */ -static int -agent_send_option (int fd, const char *name, const char *value) -{ - char buf[200]; - int nread; - char *line; - int i; - - line = spwq_malloc (7 + strlen (name) + 1 + strlen (value) + 2); - if (!line) - return SPWQ_OUT_OF_CORE; - strcpy (stpcpy (stpcpy (stpcpy ( - stpcpy (line, "OPTION "), name), "="), value), "\n"); - i = writen (fd, line, strlen (line)); - spwq_free (line); - if (i) - return i; - - /* get response */ - nread = readline (fd, buf, DIM(buf)-1); - if (nread < 0) - return -nread; - if (nread < 3) - return SPWQ_PROTOCOL_ERROR; - - if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n')) - return 0; /* okay */ - - return SPWQ_ERR_RESPONSE; -} - - -/* Send all available options to the agent. */ -static int -agent_send_all_options (int fd) -{ - char *dft_display = NULL; - char *dft_ttyname = NULL; - char *dft_ttytype = NULL; - int rc = 0; - - dft_display = getenv ("DISPLAY"); - if (dft_display) - { - if ((rc = agent_send_option (fd, "display", dft_display))) - return rc; - } - - dft_ttyname = getenv ("GPG_TTY"); - if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) - dft_ttyname = ttyname (0); - if (dft_ttyname && *dft_ttyname) - { - if ((rc=agent_send_option (fd, "ttyname", dft_ttyname))) - return rc; - } - - dft_ttytype = getenv ("TERM"); - if (dft_ttyname && dft_ttytype) - { - if ((rc = agent_send_option (fd, "ttytype", dft_ttytype))) - return rc; - } - -#if defined(HAVE_SETLOCALE) - { - char *old_lc = NULL; - char *dft_lc = NULL; - -#if defined(LC_CTYPE) - old_lc = setlocale (LC_CTYPE, NULL); - if (old_lc) - { - char *p = spwq_malloc (strlen (old_lc)+1); - if (!p) - return SPWQ_OUT_OF_CORE; - strcpy (p, old_lc); - old_lc = p; - } - dft_lc = setlocale (LC_CTYPE, ""); - if (dft_ttyname && dft_lc) - rc = agent_send_option (fd, "lc-ctype", dft_lc); - if (old_lc) - { - setlocale (LC_CTYPE, old_lc); - spwq_free (old_lc); - } - if (rc) - return rc; -#endif - -#if defined(LC_MESSAGES) - old_lc = setlocale (LC_MESSAGES, NULL); - if (old_lc) - { - char *p = spwq_malloc (strlen (old_lc)+1); - if (!p) - return SPWQ_OUT_OF_CORE; - strcpy (p, old_lc); - old_lc = p; - } - dft_lc = setlocale (LC_MESSAGES, ""); - if (dft_ttyname && dft_lc) - rc = agent_send_option (fd, "lc-messages", dft_lc); - if (old_lc) - { - setlocale (LC_MESSAGES, old_lc); - spwq_free (old_lc); - } - if (rc) - return rc; -#endif - } -#endif /*HAVE_SETLOCALE*/ - - return 0; -} - - - -/* Try to open a connection to the agent, send all options and return - the file descriptor for the connection. Return -1 in case of - error. */ -static int -agent_open (int *rfd) -{ - int rc; - int fd; - char *infostr, *p; - struct sockaddr_un client_addr; - size_t len; - int prot; - char line[200]; - int nread; - - *rfd = -1; - infostr = getenv ( "GPG_AGENT_INFO" ); - if ( !infostr || !*infostr ) - { -#ifdef SPWQ_USE_LOGGING - log_error (_("gpg-agent is not available in this session\n")); -#endif - return SPWQ_NO_AGENT; - } - p = spwq_malloc (strlen (infostr)+1); - if (!p) - return SPWQ_OUT_OF_CORE; - strcpy (p, infostr); - infostr = p; - - if ( !(p = strchr ( infostr, ':')) || p == infostr - || (p-infostr)+1 >= sizeof client_addr.sun_path ) - { -#ifdef SPWQ_USE_LOGGING - log_error ( _("malformed GPG_AGENT_INFO environment variable\n")); -#endif - return SPWQ_NO_AGENT; - } - *p++ = 0; - - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if ( prot != 1) - { -#ifdef SPWQ_USE_LOGGING - log_error (_("gpg-agent protocol version %d is not supported\n"),prot); -#endif - return SPWQ_PROTOCOL_ERROR; - } - - if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ) - { -#ifdef SPWQ_USE_LOGGING - log_error ("can't create socket: %s\n", strerror(errno) ); -#endif - return SPWQ_SYS_ERROR; - } - - memset (&client_addr, 0, sizeof client_addr); - client_addr.sun_family = AF_UNIX; - strcpy (client_addr.sun_path, infostr); - len = (offsetof (struct sockaddr_un, sun_path) - + strlen(client_addr.sun_path) + 1); - - if (connect (fd, (struct sockaddr*)&client_addr, len ) == -1) - { -#ifdef SPWQ_USE_LOGGING - log_error ( _("can't connect to `%s': %s\n"), infostr, strerror (errno)); -#endif - close (fd ); - return SPWQ_IO_ERROR; - } - - nread = readline (fd, line, DIM(line)); - if (nread < 3 || !(line[0] == 'O' && line[1] == 'K' - && (line[2] == '\n' || line[2] == ' ')) ) - { -#ifdef SPWQ_USE_LOGGING - log_error ( _("communication problem with gpg-agent\n")); -#endif - close (fd ); - return SPWQ_PROTOCOL_ERROR; - } - - rc = agent_send_all_options (fd); - if (rc) - { -#ifdef SPWQ_USE_LOGGING - log_error (_("problem setting the gpg-agent options\n")); -#endif - close (fd); - return rc; - } - - *rfd = fd; - return 0; -} - - -/* Copy text to BUFFER and escape as required. Return a pointer to - the end of the new buffer. NOte that BUFFER must be large enough - to keep the entire text; allocataing it 3 times the size of TEXT - is sufficient. */ -static char * -copy_and_escape (char *buffer, const char *text) -{ - int i; - const unsigned char *s = text; - char *p = buffer; - - - for (i=0; s[i]; i++) - { - if (s[i] < ' ' || s[i] == '+') - { - sprintf (p, "%%%02X", s[i]); - p += 3; - } - else if (s[i] == ' ') - *p++ = '+'; - else - *p++ = s[i]; - } - return p; -} - - -/* Ask the gpg-agent for a passphrase and present the user with a - DESCRIPTION, a PROMPT and optiaonlly with a TRYAGAIN extra text. - If a CACHEID is not NULL it is used to locate the passphrase in in - the cache and store it under this ID. If ERRORCODE is not NULL it - should point a variable receiving an errorcode; thsi errocode might - be 0 if the user canceled the operation. The function returns NULL - to indicate an error. */ -char * -simple_pwquery (const char *cacheid, - const char *tryagain, - const char *prompt, - const char *description, - int *errorcode) -{ - int fd = -1; - int nread; - char *result = NULL; - char *pw = NULL; - char *p; - int rc, i; - - rc = agent_open (&fd); - if (rc) - goto leave; - - if (!cacheid) - cacheid = "X"; - if (!tryagain) - tryagain = "X"; - if (!prompt) - prompt = "X"; - if (!description) - description = "X"; - - { - char *line; - /* We allocate 3 times the needed space so that there is enough - space for escaping. */ - line = spwq_malloc (15 - + 3*strlen (cacheid) + 1 - + 3*strlen (tryagain) + 1 - + 3*strlen (prompt) + 1 - + 3*strlen (description) + 1 - + 2); - if (!line) - { - rc = SPWQ_OUT_OF_CORE; - goto leave; - } - strcpy (line, "GET_PASSPHRASE "); - p = line+15; - p = copy_and_escape (p, cacheid); - *p++ = ' '; - p = copy_and_escape (p, tryagain); - *p++ = ' '; - p = copy_and_escape (p, prompt); - *p++ = ' '; - p = copy_and_escape (p, description); - *p++ = '\n'; - rc = writen (fd, line, p - line); - spwq_free (line); - if (rc) - goto leave; - } - - /* get response */ - pw = spwq_secure_malloc (500); - nread = readline (fd, pw, 499); - if (nread < 0) - { - rc = -nread; - goto leave; - } - if (nread < 3) - { - rc = SPWQ_PROTOCOL_ERROR; - goto leave; - } - - if (pw[0] == 'O' && pw[1] == 'K' && pw[2] == ' ') - { /* we got a passphrase - convert it back from hex */ - size_t pwlen = 0; - - for (i=3; i < nread && hexdigitp (pw+i); i+=2) - pw[pwlen++] = xtoi_2 (pw+i); - pw[pwlen] = 0; /* make a C String */ - result = pw; - pw = NULL; - } - else if (nread > 7 && !memcmp (pw, "ERR 111", 7) - && (pw[7] == ' ' || pw[7] == '\n') ) - { -#ifdef SPWQ_USE_LOGGING - log_info (_("canceled by user\n") ); -#endif - *errorcode = 0; /* canceled */ - } - else - { -#ifdef SPWQ_USE_LOGGING - log_error (_("problem with the agent\n")); -#endif - rc = SPWQ_ERR_RESPONSE; - } - - leave: - if (errorcode) - *errorcode = rc; - if (fd != -1) - close (fd); - if (pw) - spwq_free (pw); - return result; -} diff --git a/common/simple-pwquery.h b/common/simple-pwquery.h deleted file mode 100644 index 5947c42b5..000000000 --- a/common/simple-pwquery.h +++ /dev/null @@ -1,69 +0,0 @@ -/* simple-pwquery.c - A simple password query cleint for gpg-agent - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef SIMPLE_PWQUERY_H -#define SIMPLE_PWQUERY_H - -#ifdef SIMPLE_PWQUERY_IMPLEMENTATION /* Begin configuration stuff. */ - -/* Include whatever files you need. */ -#include -#include "../jnlib/logging.h" - -/* Try to write error message using the standard log mechanism. The - current implementation requires that the HAVE_JNLIB_LOGGING is also - defined. */ -#define SPWQ_USE_LOGGING 1 - -/* Memory allocation functions used by the implementation. Note, that - the returned value is expected to be freed with - spwq_secure_free. */ -#define spwq_malloc(a) gcry_malloc (a) -#define spwq_free(a) gcry_free (a) -#define spwq_secure_malloc(a) gcry_malloc_secure (a) -#define spwq_secure_free(a) gcry_free (a) - - -#endif /*SIMPLE_PWQUERY_IMPLEMENTATION*/ /* End configuration stuff. */ - - -/* Ask the gpg-agent for a passphrase and present the user with a - DESCRIPTION, a PROMPT and optiaonlly with a TRYAGAIN extra text. - If a CACHEID is not NULL it is used to locate the passphrase in in - the cache and store it under this ID. If ERRORCODE is not NULL it - should point a variable receiving an errorcode; this errocode might - be 0 if the user canceled the operation. The function returns NULL - to indicate an error. */ -char *simple_pwquery (const char *cacheid, - const char *tryagain, - const char *prompt, - const char *description, - int *errorcode); - - -#define SPWQ_OUT_OF_CORE 1 -#define SPWQ_IO_ERROR 2 -#define SPWQ_PROTOCOL_ERROR 3 -#define SPWQ_ERR_RESPONSE 4 -#define SPWQ_NO_AGENT 5 -#define SPWQ_SYS_ERROR 6 -#define SPWQ_GENERAL_ERROR 7 - -#endif /*SIMPLE_PWQUERY_H*/ diff --git a/common/sysutils.c b/common/sysutils.c deleted file mode 100644 index 97fa23d95..000000000 --- a/common/sysutils.c +++ /dev/null @@ -1,230 +0,0 @@ -/* sysutils.c - system helpers - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_STAT -#include -#endif -#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 - #include - #include -#endif -#ifdef HAVE_SETRLIMIT - #include - #include - #include -#endif -#include "util.h" -#include "i18n.h" - -#include "sysutils.h" - -#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 -#warning using trap_unaligned -static int -setsysinfo(unsigned long op, void *buffer, unsigned long size, - int *start, void *arg, unsigned long flag) -{ - return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag); -} - -void -trap_unaligned(void) -{ - unsigned int buf[2]; - - buf[0] = SSIN_UACPROC; - buf[1] = UAC_SIGBUS | UAC_NOPRINT; - setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0); -} -#else -void -trap_unaligned(void) -{ /* dummy */ -} -#endif - - -int -disable_core_dumps (void) -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else -# ifdef HAVE_SETRLIMIT - struct rlimit limit; - - /* We only set the current limit unless we were not able to - retrieve the old value. */ - if (getrlimit (RLIMIT_CORE, &limit)) - limit.rlim_max = 0; - limit.rlim_cur = 0; - if( !setrlimit (RLIMIT_CORE, &limit) ) - return 0; - if( errno != EINVAL && errno != ENOSYS ) - log_fatal (_("can't disable core dumps: %s\n"), strerror(errno) ); -#endif - return 1; -#endif -} - -int -enable_core_dumps (void) -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else -# ifdef HAVE_SETRLIMIT - struct rlimit limit; - - if (getrlimit (RLIMIT_CORE, &limit)) - return 1; - limit.rlim_cur = limit.rlim_max; - setrlimit (RLIMIT_CORE, &limit); - return 1; /* We always return true because trhis function is - merely a debugging aid. */ -#endif - return 1; -#endif -} - - - -/* Return a string which is used as a kind of process ID */ -const byte * -get_session_marker( size_t *rlen ) -{ - static byte marker[SIZEOF_UNSIGNED_LONG*2]; - static int initialized; - - if ( !initialized ) { - volatile ulong aa, bb; /* we really want the uninitialized value */ - ulong a, b; - - initialized = 1; - /* also this marker is guessable it is not easy to use this - * for a faked control packet because an attacker does not - * have enough control about the time the verification does - * take place. Of course, we can add just more random but - * than we need the random generator even for verification - * tasks - which does not make sense. */ - a = aa ^ (ulong)getpid(); - b = bb ^ (ulong)time(NULL); - memcpy( marker, &a, SIZEOF_UNSIGNED_LONG ); - memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG ); - } - *rlen = sizeof(marker); - return marker; -} - - -#if 0 /* not yet needed - Note that this will require inclusion of - cmacros.am in Makefile.am */ -int -check_permissions(const char *path,int extension,int checkonly) -{ -#if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM) - char *tmppath; - struct stat statbuf; - int ret=1; - int isdir=0; - - if(opt.no_perm_warn) - return 0; - - if(extension && path[0]!=DIRSEP_C) - { - if(strchr(path,DIRSEP_C)) - tmppath=make_filename(path,NULL); - else - tmppath=make_filename(GNUPG_LIBDIR,path,NULL); - } - else - tmppath=m_strdup(path); - - /* It's okay if the file doesn't exist */ - if(stat(tmppath,&statbuf)!=0) - { - ret=0; - goto end; - } - - isdir=S_ISDIR(statbuf.st_mode); - - /* Per-user files must be owned by the user. Extensions must be - owned by the user or root. */ - if((!extension && statbuf.st_uid != getuid()) || - (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid())) - { - if(!checkonly) - log_info(_("Warning: unsafe ownership on %s \"%s\"\n"), - isdir?"directory":extension?"extension":"file",path); - goto end; - } - - /* This works for both directories and files - basically, we don't - care what the owner permissions are, so long as the group and - other permissions are 0 for per-user files, and non-writable for - extensions. */ - if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) || - (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0)) - { - char *dir; - - /* However, if the directory the directory/file is in is owned - by the user and is 700, then this is not a problem. - Theoretically, we could walk this test up to the root - directory /, but for the sake of sanity, I'm stopping at one - level down. */ - - dir= make_dirname (tmppath); - if(stat(dir,&statbuf)==0 && statbuf.st_uid==getuid() && - S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0) - { - xfree (dir); - ret=0; - goto end; - } - - m_free(dir); - - if(!checkonly) - log_info(_("Warning: unsafe permissions on %s \"%s\"\n"), - isdir?"directory":extension?"extension":"file",path); - goto end; - } - - ret=0; - - end: - m_free(tmppath); - - return ret; - -#endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */ - - return 0; -} -#endif diff --git a/common/sysutils.h b/common/sysutils.h deleted file mode 100644 index 66f714acd..000000000 --- a/common/sysutils.h +++ /dev/null @@ -1,31 +0,0 @@ -/* sysutils.h - System utility functions for Gnupg - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_SYSUTILS_H -#define GNUPG_COMMON_SYSUTILS_H - -void trap_unaligned (void); -int disable_core_dumps (void); -int enable_core_dumps (void); -const unsigned char *get_session_marker (size_t *rlen); -int check_permissions (const char *path,int extension,int checkonly); - - -#endif /*GNUPG_COMMON_SYSUTILS_H*/ diff --git a/common/ttyio.c b/common/ttyio.c deleted file mode 100644 index eab805e20..000000000 --- a/common/ttyio.c +++ /dev/null @@ -1,555 +0,0 @@ -/* ttyio.c - tty i/O functions - * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_TCGETATTR -#include -#else -#ifdef HAVE_TERMIO_H -/* simulate termios with termio */ -#include -#define termios termio -#define tcsetattr ioctl -#define TCSAFLUSH TCSETAF -#define tcgetattr(A,B) ioctl(A,TCGETA,B) -#define HAVE_TCGETATTR -#endif -#endif -#ifdef _WIN32 /* use the odd Win32 functions */ -#include -#ifdef HAVE_TCGETATTR -#error mingw32 and termios -#endif -#endif -#include -#include -#include "util.h" -#include "memory.h" -#include "ttyio.h" - -#define CONTROL_D ('D' - 'A' + 1) - -#ifdef _WIN32 /* use the odd Win32 functions */ -static struct { - HANDLE in, out; -} con; -#define DEF_INPMODE (ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT \ - |ENABLE_PROCESSED_INPUT ) -#define HID_INPMODE (ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT ) -#define DEF_OUTMODE (ENABLE_WRAP_AT_EOL_OUTPUT|ENABLE_PROCESSED_OUTPUT) - -#else /* yeah, we have a real OS */ -static FILE *ttyfp = NULL; -#endif - -static int initialized; -static int last_prompt_len; -static int batchmode; -static int no_terminal; - -#ifdef HAVE_TCGETATTR - static struct termios termsave; - static int restore_termios; -#endif - - - -/* This is a wrapper around ttyname so that we can use it even when - the standard streams are redirected. It figures the name out the - first time and returns it in a statically allocated buffer. */ -const char * -tty_get_ttyname (void) -{ - static char *name; - - /* On a GNU system ctermid() always return /dev/tty, so this does - not make much sense - however if it is ever changed we do the - Right Thing now. */ -#ifdef HAVE_CTERMID - static int got_name; - - if (!got_name) - { - const char *s; - s = ctermid (NULL); - if (s) - name = strdup (s); - got_name = 1; - } -#endif - /* Assume the staandrd tty on memory error or when tehre is no - certmid. */ - return name? name : "/dev/tty"; -} - - - -#ifdef HAVE_TCGETATTR -static void -cleanup(void) -{ - if( restore_termios ) { - restore_termios = 0; /* do it prios in case it is interrupted again */ - if( tcsetattr(fileno(ttyfp), TCSAFLUSH, &termsave) ) - log_error("tcsetattr() failed: %s\n", strerror(errno) ); - } -} -#endif - -static void -init_ttyfp(void) -{ - if( initialized ) - return; - -#if defined(_WIN32) - { - SECURITY_ATTRIBUTES sa; - - memset(&sa, 0, sizeof(sa)); - sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - con.out = CreateFileA( "CONOUT$", GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, - &sa, OPEN_EXISTING, 0, 0 ); - if( con.out == INVALID_HANDLE_VALUE ) - log_fatal("open(CONOUT$) failed: rc=%d", (int)GetLastError() ); - memset(&sa, 0, sizeof(sa)); - sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - con.in = CreateFileA( "CONIN$", GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, - &sa, OPEN_EXISTING, 0, 0 ); - if( con.in == INVALID_HANDLE_VALUE ) - log_fatal("open(CONIN$) failed: rc=%d", (int)GetLastError() ); - } - SetConsoleMode(con.in, DEF_INPMODE ); - SetConsoleMode(con.out, DEF_OUTMODE ); - -#elif defined(__EMX__) - ttyfp = stdout; /* Fixme: replace by the real functions: see wklib */ -#else - ttyfp = batchmode? stderr : fopen (tty_get_ttyname (), "r+"); - if( !ttyfp ) { - log_error("cannot open `%s': %s\n", tty_get_ttyname (), - strerror(errno) ); - exit(2); - } -#endif -#ifdef HAVE_TCGETATTR - atexit( cleanup ); -#endif - initialized = 1; -} - - -int -tty_batchmode( int onoff ) -{ - int old = batchmode; - if( onoff != -1 ) - batchmode = onoff; - return old; -} - -int -tty_no_terminal(int onoff) -{ - int old = no_terminal; - no_terminal = onoff ? 1 : 0; - return old; -} - -void -tty_printf( const char *fmt, ... ) -{ - va_list arg_ptr; - - if (no_terminal) - return; - - if( !initialized ) - init_ttyfp(); - - va_start( arg_ptr, fmt ) ; -#ifdef _WIN32 - { - char *buf = NULL; - int n; - DWORD nwritten; - - n = vasprintf(&buf, fmt, arg_ptr); - if( !buf ) - log_bug("vasprintf() failed\n"); - - if( !WriteConsoleA( con.out, buf, n, &nwritten, NULL ) ) - log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() ); - if( n != nwritten ) - log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten ); - last_prompt_len += n; - xfree (buf); - } -#else - last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ; - fflush(ttyfp); -#endif - va_end(arg_ptr); -} - - -/* Same as tty_printf but if FP is not NULL, behave like a regualr - fprintf. */ -void -tty_fprintf (FILE *fp, const char *fmt, ... ) -{ - va_list arg_ptr; - - if (fp) - { - va_start (arg_ptr, fmt) ; - vfprintf (fp, fmt, arg_ptr ); - va_end (arg_ptr); - return; - } - - if (no_terminal) - return; - - if( !initialized ) - init_ttyfp(); - - va_start( arg_ptr, fmt ) ; -#ifdef _WIN32 - { - char *buf = NULL; - int n; - DWORD nwritten; - - n = vasprintf(&buf, fmt, arg_ptr); - if( !buf ) - log_bug("vasprintf() failed\n"); - - if( !WriteConsoleA( con.out, buf, n, &nwritten, NULL ) ) - log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() ); - if( n != nwritten ) - log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten ); - last_prompt_len += n; - xfree (buf); - } -#else - last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ; - fflush(ttyfp); -#endif - va_end(arg_ptr); -} - - -/**************** - * Print a string, but filter all control characters out. - */ -void -tty_print_string ( const byte *p, size_t n ) -{ - if (no_terminal) - return; - - if( !initialized ) - init_ttyfp(); - -#ifdef _WIN32 - /* not so effective, change it if you want */ - for( ; n; n--, p++ ) - if( iscntrl( *p ) ) { - if( *p == '\n' ) - tty_printf("\\n"); - else if( !*p ) - tty_printf("\\0"); - else - tty_printf("\\x%02x", *p); - } - else - tty_printf("%c", *p); -#else - for( ; n; n--, p++ ) - if( iscntrl( *p ) ) { - putc('\\', ttyfp); - if( *p == '\n' ) - putc('n', ttyfp); - else if( !*p ) - putc('0', ttyfp); - else - fprintf(ttyfp, "x%02x", *p ); - } - else - putc(*p, ttyfp); -#endif -} - -void -tty_print_utf8_string2( const byte *p, size_t n, size_t max_n ) -{ - size_t i; - char *buf; - - if (no_terminal) - return; - - /* we can handle plain ascii simpler, so check for it first */ - for(i=0; i < n; i++ ) { - if( p[i] & 0x80 ) - break; - } - if( i < n ) { - buf = utf8_to_native( p, n, 0 ); - if( max_n && (strlen( buf ) > max_n )) { - buf[max_n] = 0; - } - /*(utf8 conversion already does the control character quoting)*/ - tty_printf("%s", buf ); - xfree( buf ); - } - else { - if( max_n && (n > max_n) ) { - n = max_n; - } - tty_print_string( p, n ); - } -} - -void -tty_print_utf8_string( const byte *p, size_t n ) -{ - tty_print_utf8_string2( p, n, 0 ); -} - - -static char * -do_get( const char *prompt, int hidden ) -{ - char *buf; -#ifndef __riscos__ - byte cbuf[1]; -#endif - int c, n, i; - - if( batchmode ) { - log_error("Sorry, we are in batchmode - can't get input\n"); - exit(2); - } - - if (no_terminal) { - log_error("Sorry, no terminal at all requested - can't get input\n"); - exit(2); - } - - if( !initialized ) - init_ttyfp(); - - last_prompt_len = 0; - tty_printf( "%s", prompt ); - buf = xmalloc((n=50)); - i = 0; - -#ifdef _WIN32 /* windoze version */ - if( hidden ) - SetConsoleMode(con.in, HID_INPMODE ); - - for(;;) { - DWORD nread; - - if( !ReadConsoleA( con.in, cbuf, 1, &nread, NULL ) ) - log_fatal("ReadConsole failed: rc=%d", (int)GetLastError() ); - if( !nread ) - continue; - if( *cbuf == '\n' ) - break; - - if( !hidden ) - last_prompt_len++; - c = *cbuf; - if( c == '\t' ) - c = ' '; - else if( c > 0xa0 ) - ; /* we don't allow 0xa0, as this is a protected blank which may - * confuse the user */ - else if( iscntrl(c) ) - continue; - if( !(i < n-1) ) { - n += 50; - buf = xrealloc (buf, n); - } - buf[i++] = c; - } - - if( hidden ) - SetConsoleMode(con.in, DEF_INPMODE ); - -#elif defined(__riscos__) - do { - c = riscos_getchar(); - if (c == 0xa || c == 0xd) { /* Return || Enter */ - c = (int) '\n'; - } else if (c == 0x8 || c == 0x7f) { /* Backspace || Delete */ - if (i>0) { - i--; - if (!hidden) { - last_prompt_len--; - fputc(8, ttyfp); - fputc(32, ttyfp); - fputc(8, ttyfp); - fflush(ttyfp); - } - } else { - fputc(7, ttyfp); - fflush(ttyfp); - } - continue; - } else if (c == (int) '\t') { /* Tab */ - c = ' '; - } else if (c > 0xa0) { - ; /* we don't allow 0xa0, as this is a protected blank which may - * confuse the user */ - } else if (iscntrl(c)) { - continue; - } - if(!(i < n-1)) { - n += 50; - buf = xrealloc (buf, n); - } - buf[i++] = c; - if (!hidden) { - last_prompt_len++; - fputc(c, ttyfp); - fflush(ttyfp); - } - } while (c != '\n'); - i = (i>0) ? i-1 : 0; -#else /* unix version */ - if( hidden ) { -#ifdef HAVE_TCGETATTR - struct termios term; - - if( tcgetattr(fileno(ttyfp), &termsave) ) - log_fatal("tcgetattr() failed: %s\n", strerror(errno) ); - restore_termios = 1; - term = termsave; - term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); - if( tcsetattr( fileno(ttyfp), TCSAFLUSH, &term ) ) - log_fatal("tcsetattr() failed: %s\n", strerror(errno) ); -#endif - } - - /* fixme: How can we avoid that the \n is echoed w/o disabling - * canonical mode - w/o this kill_prompt can't work */ - while( read(fileno(ttyfp), cbuf, 1) == 1 && *cbuf != '\n' ) { - if( !hidden ) - last_prompt_len++; - c = *cbuf; - if( c == CONTROL_D ) - log_info("control d found\n"); - if( c == '\t' ) - c = ' '; - else if( c > 0xa0 ) - ; /* we don't allow 0xa0, as this is a protected blank which may - * confuse the user */ - else if( iscntrl(c) ) - continue; - if( !(i < n-1) ) { - n += 50; - buf = xrealloc (buf, n ); - } - buf[i++] = c; - } - if( *cbuf != '\n' ) { - buf[0] = CONTROL_D; - i = 1; - } - - - if( hidden ) { -#ifdef HAVE_TCGETATTR - if( tcsetattr(fileno(ttyfp), TCSAFLUSH, &termsave) ) - log_error("tcsetattr() failed: %s\n", strerror(errno) ); - restore_termios = 0; -#endif - } -#endif /* end unix version */ - buf[i] = 0; - return buf; -} - - -char * -tty_get( const char *prompt ) -{ - return do_get( prompt, 0 ); -} - -char * -tty_get_hidden( const char *prompt ) -{ - return do_get( prompt, 1 ); -} - - -void -tty_kill_prompt() -{ - if ( no_terminal ) - return; - - if( !initialized ) - init_ttyfp(); - - if( batchmode ) - last_prompt_len = 0; - if( !last_prompt_len ) - return; -#ifdef _WIN32 - tty_printf("\r%*s\r", last_prompt_len, ""); -#else - { - int i; - putc('\r', ttyfp); - for(i=0; i < last_prompt_len; i ++ ) - putc(' ', ttyfp); - putc('\r', ttyfp); - fflush(ttyfp); - } -#endif - last_prompt_len = 0; -} - - -int -tty_get_answer_is_yes( const char *prompt ) -{ - int yes; - char *p = tty_get( prompt ); - tty_kill_prompt(); - yes = answer_is_yes(p); - xfree(p); - return yes; -} diff --git a/common/ttyio.h b/common/ttyio.h deleted file mode 100644 index 6fa7400a9..000000000 --- a/common/ttyio.h +++ /dev/null @@ -1,44 +0,0 @@ -/* ttyio.h - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef GNUPG_COMMON_TTYIO_H -#define GNUPG_COMMON_TTYIO_H - -const char *tty_get_ttyname (void); -int tty_batchmode (int onoff); -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) -void tty_printf (const char *fmt, ... ) - __attribute__ ((format (printf,1,2))); -void tty_fprintf (FILE *fp, const char *fmt, ... ) - __attribute__ ((format (printf,2,3))); -#else -void tty_printf (const char *fmt, ... ); -void tty_fprintf (FILE *fp, const char *fmt, ... ); -#endif -void tty_print_string (const unsigned char *p, size_t n); -void tty_print_utf8_string (const unsigned char *p, size_t n); -void tty_print_utf8_string2 (const unsigned char *p, size_t n, size_t max_n); -char *tty_get (const char *prompt); -char *tty_get_hidden (const char *prompt); -void tty_kill_prompt (void); -int tty_get_answer_is_yes (const char *prompt); -int tty_no_terminal (int onoff); - - -#endif /*GNUPG_COMMON_TTYIO_H*/ diff --git a/common/util.h b/common/util.h deleted file mode 100644 index b9ffe6562..000000000 --- a/common/util.h +++ /dev/null @@ -1,171 +0,0 @@ -/* util.h - Utility functions for GnuPG - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_UTIL_H -#define GNUPG_COMMON_UTIL_H - -#include /* We need this for the memory function protos. */ -#include /* We need time_t. */ -#include /* we need gpg-error_t. */ - -/* to pass hash functions to libksba we need to cast it */ -#define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write) - -/* get all the stuff from jnlib */ -#include "../jnlib/logging.h" -#include "../jnlib/argparse.h" -#include "../jnlib/stringhelp.h" -#include "../jnlib/mischelp.h" -#include "../jnlib/strlist.h" -#include "../jnlib/dotlock.h" -#include "../jnlib/utf8conv.h" - -/* Handy malloc macros - please use only them. */ -#define xtrymalloc(a) gcry_malloc ((a)) -#define xtrymalloc_secure(a) gcry_malloc_secure ((a)) -#define xtrycalloc(a,b) gcry_calloc ((a),(b)) -#define xtrycalloc_secure(a,b) gcry_calloc_secure ((a),(b)) -#define xtryrealloc(a,b) gcry_realloc ((a),(b)) -#define xtrystrdup(a) gcry_strdup ((a)) -#define xfree(a) gcry_free ((a)) - -#define xmalloc(a) gcry_xmalloc ((a)) -#define xmalloc_secure(a) gcry_xmalloc_secure ((a)) -#define xcalloc(a,b) gcry_xcalloc ((a),(b)) -#define xcalloc_secure(a,b) gcry_xcalloc_secure ((a),(b)) -#define xrealloc(a,b) gcry_xrealloc ((a),(b)) -#define xstrdup(a) gcry_xstrdup ((a)) - - -/* A type to hold the ISO time. Note that this this is the same as - the the KSBA type ksba_isotime_t. */ -typedef char gnupg_isotime_t[16]; - - -/*-- maperror.c --*/ -int map_kbx_err (int err); -gpg_error_t map_assuan_err (int err); -int map_to_assuan_status (int rc); - -/*-- gettime.c --*/ -time_t gnupg_get_time (void); -void gnupg_get_isotime (gnupg_isotime_t timebuf); -void gnupg_set_time (time_t newtime, int freeze); -int gnupg_faked_time_p (void); -u32 make_timestamp (void); -u32 scan_isodatestr (const char *string); -u32 add_days_to_timestamp (u32 stamp, u16 days); -const char *strtimevalue (u32 stamp); -const char *strtimestamp (u32 stamp); /* GMT */ -const char *asctimestamp (u32 stamp); /* localized */ - - -/* Copy one iso ddate to another, this is inline so that we can do a - sanity check. */ -static inline void -gnupg_copy_time (gnupg_isotime_t d, const gnupg_isotime_t s) -{ - if (*s && (strlen (s) != 15 || s[8] != 'T')) - BUG(); - strcpy (d, s); -} - - -/*-- signal.c --*/ -void gnupg_init_signals (int mode, void (*fast_cleanup)(void)); -void gnupg_pause_on_sigusr (int which); -void gnupg_block_all_signals (void); -void gnupg_unblock_all_signals (void); - -/*-- yesno.c --*/ -int answer_is_yes (const char *s); -int answer_is_yes_no_default (const char *s, int def_answer); -int answer_is_yes_no_quit (const char *s); - -/*-- xreadline.c --*/ -ssize_t read_line (FILE *fp, - char **addr_of_buffer, size_t *length_of_buffer, - size_t *max_length); - - -/*-- b64enc.c --*/ -struct b64state -{ - unsigned int flags; - int idx; - int quad_count; - FILE *fp; - char *title; - unsigned char radbuf[4]; -}; -gpg_error_t b64enc_start (struct b64state *state, FILE *fp, const char *title); -gpg_error_t b64enc_write (struct b64state *state, - const void *buffer, size_t nbytes); -gpg_error_t b64enc_finish (struct b64state *state); - - -/*-- miscellaneous.c --*/ - -/* Same as asprintf but return an allocated buffer suitable to be - freed using xfree. This function simply dies on memory failure, - thus no extra check is required. */ -char *xasprintf (const char *fmt, ...) JNLIB_GCC_A_PRINTF(1,2); - -const char *print_fname_stdout (const char *s); -const char *print_fname_stdin (const char *s); -void print_string (FILE *fp, const byte *p, size_t n, int delim); -void print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim); -void print_utf8_string (FILE *fp, const byte *p, size_t n); -char *make_printable_string (const byte *p, size_t n, int delim); - -int is_file_compressed (const char *s, int *ret_rc); - - -/*-- replacement functions from funcname.c --*/ -#if !HAVE_VASPRINTF -#include -int vasprintf (char **result, const char *format, va_list args); -int asprintf (char **result, const char *format, ...) JNLIB_GCC_A_PRINTF(2,3); -#endif - - - -/*-- some macros to replace ctype ones and avoid locale problems --*/ -#define spacep(p) (*(p) == ' ' || *(p) == '\t') -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) - /* Note this isn't identical to a C locale isspace() without \f and - \v, but works for the purposes used here. */ -#define ascii_isspace(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t') - -/* The atoi macros assume that the buffer has only valid digits. */ -#define atoi_1(p) (*(p) - '0' ) -#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) -#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) -#define xtoi_4(p) ((xtoi_2(p) * 256) + xtoi_2((p)+2)) - - - -#endif /*GNUPG_COMMON_UTIL_H*/ diff --git a/common/vasprintf.c b/common/vasprintf.c deleted file mode 100644 index 9efea33f2..000000000 --- a/common/vasprintf.c +++ /dev/null @@ -1,169 +0,0 @@ -/* Like vsprintf but provides a pointer to malloc'd storage, which must - be freed by the caller. - Copyright (C) 1994, 2002 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -#ifdef TEST -int global_total_width; -#endif - -int -vasprintf (char **result, const char *format, va_list args) -{ - const char *p = format; - /* Add one to make sure that it is never zero, which might cause malloc - to return NULL. */ - int total_width = strlen (format) + 1; - va_list ap; - -#ifdef va_copy - va_copy (ap, args); -#else -#ifdef __va_copy - __va_copy (ap, args); -#else - memcpy (&ap, args, sizeof (va_list)); -#endif /* __va_copy */ -#endif /* va_copy */ - - while (*p != '\0') - { - if (*p++ == '%') - { - while (strchr ("-+ #0", *p)) - ++p; - if (*p == '*') - { - ++p; - total_width += abs (va_arg (ap, int)); - } - else - total_width += strtoul (p, (char**)&p, 10); - if (*p == '.') - { - ++p; - if (*p == '*') - { - ++p; - total_width += abs (va_arg (ap, int)); - } - else - total_width += strtoul (p, (char**)&p, 10); - } - while (strchr ("hlL", *p)) - ++p; - /* Should be big enough for any format specifier except %s - and floats. */ - total_width += 30; - switch (*p) - { - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - case 'c': - (void) va_arg (ap, int); - break; - case 'f': - case 'e': - case 'E': - case 'g': - case 'G': - (void) va_arg (ap, double); - /* Since an ieee double can have an exponent of 307, we'll - make the buffer wide enough to cover the gross case. */ - total_width += 307; - break; - case 's': - { - char *tmp = va_arg (ap, char *); - if (tmp) - total_width += strlen (tmp); - else /* in case the vsprintf does prints a text */ - total_width += 25; /* e.g. "(null pointer reference)" */ - } - break; - case 'p': - case 'n': - (void) va_arg (ap, char *); - break; - } - } - } -#ifdef TEST - global_total_width = total_width; -#endif - *result = malloc (total_width); - if (*result != NULL) - return vsprintf (*result, format, args); - else - return 0; -} - - -int -asprintf (char **buf, const char *fmt, ...) -{ - int status; - va_list ap; - - va_start (ap, fmt); - status = vasprintf (buf, fmt, ap); - va_end (ap); - return status; -} - - -#ifdef TEST -void -checkit (const char* format, ...) -{ - va_list args; - char *result; - - va_start (args, format); - vasprintf (&result, format, args); - if (strlen (result) < global_total_width) - printf ("PASS: "); - else - printf ("FAIL: "); - printf ("%d %s\n", global_total_width, result); -} - -int -main (void) -{ - checkit ("%d", 0x12345678); - checkit ("%200d", 5); - checkit ("%.300d", 6); - checkit ("%100.150d", 7); - checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\ -777777777777777777333333333333366666666666622222222222777777777777733333"); - checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx"); -} -#endif /* TEST */ diff --git a/common/xasprintf.c b/common/xasprintf.c deleted file mode 100644 index 2c8fafc06..000000000 --- a/common/xasprintf.c +++ /dev/null @@ -1,44 +0,0 @@ -/* xasprintf.c - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include - -#include "util.h" -#include "iobuf.h" - -/* Same as asprintf but return an allocated buffer suitable to be - freed using xfree. This function simply dies on memory failure, - thus no extra check is required. */ -char * -xasprintf (const char *fmt, ...) -{ - va_list ap; - char *buf, *p; - - va_start (ap, fmt); - if (vasprintf (&buf, fmt, ap) < 0) - log_fatal ("asprintf failed: %s\n", strerror (errno)); - va_end (ap); - p = xstrdup (buf); - free (buf); - return p; -} diff --git a/common/xreadline.c b/common/xreadline.c deleted file mode 100644 index 85f0af02e..000000000 --- a/common/xreadline.c +++ /dev/null @@ -1,116 +0,0 @@ -/* xreadline.c - fgets replacement function - * Copyright (C) 1999, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include - -#include "util.h" - - -/* Same as fgets() but if the provided buffer is too short a larger - one will be allocated. This is similar to getline. A line is - considered a byte stream ending in a LF. - - If MAX_LENGTH is not NULL, it shall point to a value with the - maximum allowed allocation. - - Returns the length of the line. EOF is indicated by a line of - length zero. A truncated line is indicated my setting the value at - MAX_LENGTH to 0. If the returned value is less then 0 not enough - memory was enable and ERRNO is set accordingly. - - If a line has been truncated, the file pointer is moved forward to - the end of the line so that the next read start with tghe next - line. Note that MAX_LENGTH must be re-initialzied in this case.. - - Note: The returned buffer is allocated with enough extra space to - append a CR,LF,Nul - */ -ssize_t -read_line (FILE *fp, - char **addr_of_buffer, size_t *length_of_buffer, - size_t *max_length) -{ - int c; - char *buffer = *addr_of_buffer; - size_t length = *length_of_buffer; - size_t nbytes = 0; - size_t maxlen = max_length? *max_length : 0; - char *p; - - if (!buffer) - { /* No buffer given - allocate a new one. */ - length = 256; - buffer = xtrymalloc (length); - *addr_of_buffer = buffer; - if (!buffer) - { - *length_of_buffer = 0; - if (max_length) - *max_length = 0; - return -1; - } - *length_of_buffer = length; - } - - length -= 3; /* Reserve 3 bytes for CR,LF,EOL. */ - p = buffer; - while ((c = getc (fp)) != EOF) - { - if (nbytes == length) - { /* Enlarge the buffer. */ - if (maxlen && length > maxlen) /* But not beyond our limit. */ - { - /* Skip the rest of the line. */ - while (c != '\n' && (c=getc (fp)) != EOF) - ; - *p++ = '\n'; /* Always append a LF (we reserved some space). */ - nbytes++; - if (max_length) - *max_length = 0; /* Indicate truncation. */ - break; /* the while loop. */ - } - length += 3; /* Adjust for the reserved bytes. */ - length += length < 1024? 256 : 1024; - *addr_of_buffer = xtryrealloc (buffer, length); - if (!*addr_of_buffer) - { - int save_errno = errno; - xfree (buffer); - *length_of_buffer = *max_length = 0; - errno = save_errno; - return -1; - } - buffer = *addr_of_buffer; - *length_of_buffer = length; - length -= 3; - p = buffer + nbytes; - } - *p++ = c; - nbytes++; - if (c == '\n') - break; - } - *p = 0; /* Make sure the line is a string. */ - - return nbytes; -} diff --git a/common/yesno.c b/common/yesno.c deleted file mode 100644 index 2a96b4e5d..000000000 --- a/common/yesno.c +++ /dev/null @@ -1,96 +0,0 @@ -/* yesno.c - Yes/No questions - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include - -#include "i18n.h" -#include "util.h" - -int -answer_is_yes_no_default( const char *s, int def_answer ) -{ - const char *long_yes = _("yes"); - const char *short_yes = _("yY"); - const char *long_no = _("no"); - const char *short_no = _("nN"); - - /* Note: we have to use the local dependent strcasecmp here */ - if( !strcasecmp(s, long_yes ) ) - return 1; - if( *s && strchr( short_yes, *s ) && !s[1] ) - return 1; - /* test for no strings to catch ambiguities for the next test */ - if( !strcasecmp(s, long_no ) ) - return 0; - if( *s && strchr( short_no, *s ) && !s[1] ) - return 0; - /* test for the english version (for those who are used to type yes) */ - if( !ascii_strcasecmp(s, "yes" ) ) - return 1; - if( *s && strchr( "yY", *s ) && !s[1] ) - return 1; - return def_answer; -} - -int -answer_is_yes( const char *s ) -{ - return answer_is_yes_no_default(s,0); -} - -/**************** - * Return 1 for yes, -1 for quit, or 0 for no - */ -int -answer_is_yes_no_quit( const char *s ) -{ - const char *long_yes = _("yes"); - const char *long_no = _("no"); - const char *long_quit = _("quit"); - const char *short_yes = _("yY"); - const char *short_no = _("nN"); - const char *short_quit = _("qQ"); - - /* Note: We have to use the locale dependent strcasecmp */ - if( !strcasecmp(s, long_no ) ) - return 0; - if( !strcasecmp(s, long_yes ) ) - return 1; - if( !strcasecmp(s, long_quit ) ) - return -1; - if( *s && strchr( short_no, *s ) && !s[1] ) - return 0; - if( *s && strchr( short_yes, *s ) && !s[1] ) - return 1; - if( *s && strchr( short_quit, *s ) && !s[1] ) - return -1; - /* but not here */ - if( !ascii_strcasecmp(s, "yes" ) ) - return 1; - if( !ascii_strcasecmp(s, "quit" ) ) - return -1; - if( *s && strchr( "yY", *s ) && !s[1] ) - return 1; - if( *s && strchr( "qQ", *s ) && !s[1] ) - return -1; - return 0; -} diff --git a/configure.ac b/configure.ac deleted file mode 100644 index 4e611651e..000000000 --- a/configure.ac +++ /dev/null @@ -1,1123 +0,0 @@ -# configure.ac - for GnuPG 1.9 -# Copyright (C) 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -# Process this file with autoconf to produce a configure script. -AC_PREREQ(2.52) -min_automake_version="1.7.6" - -# Version number: Remember to change it immediately *after* a release. -# Add a "-cvs" prefix for non-released code. -AC_INIT(gnupg, 1.9.10-cvs, gnupg-devel@gnupg.org) -# Set development_version to yes if the minor number is odd or you -# feel that the default check for a development version is not -# sufficient. -development_version=yes -NEED_GPG_ERROR_VERSION=0.7 - -NEED_LIBGCRYPT_API=1 -NEED_LIBGCRYPT_VERSION=1.1.94 - -NEED_LIBASSUAN_VERSION=0.6.6 - -NEED_KSBA_VERSION=0.9.7 - -NEED_OPENSC_VERSION=0.8.0 - - - -PACKAGE=$PACKAGE_NAME -PACKAGE_GT=${PACKAGE_NAME}2 -VERSION=$PACKAGE_VERSION - -AC_CONFIG_AUX_DIR(scripts) -AC_CONFIG_SRCDIR(sm/gpgsm.c) -AM_CONFIG_HEADER(config.h) -AC_CANONICAL_TARGET() -AM_INIT_AUTOMAKE($PACKAGE, $VERSION) - -AC_GNU_SOURCE - -# Some status variables to give feedback at the end of a configure run -have_gpg_error=no -have_libgcrypt=no -have_libassuan=no -have_ksba=no -have_opensc=no -have_pth=no - -GNUPG_BUILD_PROGRAM(gpg, yes) -GNUPG_BUILD_PROGRAM(gpgsm, yes) -GNUPG_BUILD_PROGRAM(agent, yes) -GNUPG_BUILD_PROGRAM(scdaemon, yes) - - -AC_SUBST(PACKAGE) -AC_SUBST(PACKAGE_GT) -AC_SUBST(VERSION) -AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package]) -AC_DEFINE_UNQUOTED(PACKAGE_GT, "$PACKAGE_GT", - [Name of this package for gettext]) -AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package]) -AC_DEFINE_UNQUOTED(PACKAGE_BUGREPORT, "$PACKAGE_BUGREPORT", - [Bug report address]) -AC_DEFINE_UNQUOTED(NEED_LIBGCRYPT_VERSION, "$NEED_LIBGCRYPT_VERSION", - [Required version of Libgcrypt]) -AC_DEFINE_UNQUOTED(NEED_KSBA_VERSION, "$NEED_KSBA_VERSION", - [Required version of Libksba]) - - - -# The default is to use the modules from this package and the few -# other packages in a standard place; i.e where this package gets -# installed. With these options it is possible to override these -# ${prefix} depended values with fixed paths, which can't be replaced -# at make time. See also am/cmacros.am and the defaults in AH_BOTTOM. -AC_ARG_WITH(agent-pgm, - [ --with-agent-pgm=PATH Use PATH as the default for the agent)], - GNUPG_AGENT_PGM="$withval", GNUPG_AGENT_PGM="" ) -AC_SUBST(GNUPG_AGENT_PGM) -AM_CONDITIONAL(GNUPG_AGENT_PGM, test -n "$GNUPG_AGENT_PGM") -show_gnupg_agent_pgm="(default)" -test -n "$GNUPG_AGENT_PGM" && show_gnupg_agent_pgm="$GNUPG_AGENT_PGM" - -AC_ARG_WITH(pinentry-pgm, - [ --with-pinentry-pgm=PATH Use PATH as the default for the pinentry)], - GNUPG_PINENTRY_PGM="$withval", GNUPG_PINENTRY_PGM="" ) -AC_SUBST(GNUPG_PINENTRY_PGM) -AM_CONDITIONAL(GNUPG_PINENTRY_PGM, test -n "$GNUPG_PINENTRY_PGM") -show_gnupg_pinentry_pgm="(default)" -test -n "$GNUPG_PINENTRY_PGM" && show_gnupg_pinentry_pgm="$GNUPG_PINENTRY_PGM" - - -AC_ARG_WITH(scdaemon-pgm, - [ --with-scdaemon-pgm=PATH Use PATH as the default for the scdaemon)], - GNUPG_SCDAEMON_PGM="$withval", GNUPG_SCDAEMON_PGM="" ) -AC_SUBST(GNUPG_SCDAEMON_PGM) -AM_CONDITIONAL(GNUPG_SCDAEMON_PGM, test -n "$GNUPG_SCDAEMON_PGM") -show_gnupg_scdaemon_pgm="(default)" -test -n "$GNUPG_SCDAEMON_PGM" && show_gnupg_scdaemon_pgm="$GNUPG_SCDAEMON_PGM" - - -AC_ARG_WITH(dirmngr-pgm, - [ --with-dirmngr-pgm=PATH Use PATH as the default for the dirmngr)], - GNUPG_DIRMNGR_PGM="$withval", GNUPG_DIRMNGR_PGM="" ) -AC_SUBST(GNUPG_DIRMNGR_PGM) -AM_CONDITIONAL(GNUPG_DIRMNGR_PGM, test -n "$GNUPG_DIRMNGR_PGM") -show_gnupg_dirmngr_pgm="(default)" -test -n "$GNUPG_DIRMNGR_PGM" && show_gnupg_dirmngr_pgm="$GNUPG_DIRMNGR_PGM" - -AC_ARG_WITH(protect-tool-pgm, - [ --with-protect-tool-pgm=PATH Use PATH as the default for the protect-tool)], - GNUPG_PROTECT_TOOL_PGM="$withval", GNUPG_PROTECT_TOOL_PGM="" ) -AC_SUBST(GNUPG_PROTECT_TOOL_PGM) -AM_CONDITIONAL(GNUPG_PROTECT_TOOL_PGM, test -n "$GNUPG_PROTECT_TOOL_PGM") -show_gnupg_protect_tool_pgm="(default)" -test -n "$GNUPG_PROTECT_TOOL_PGM" \ - && show_gnupg_protect_tool_pgm="$GNUPG_PROTECT_TOOL_PGM" - - - -# Configure option to allow ot disallow execution of external -# programs, like a photo viewer. -AC_MSG_CHECKING([whether to enable external program execution]) -AC_ARG_ENABLE(exec, - AC_HELP_STRING([--disable-exec],[disable all external program execution]), - use_exec=$enableval) -AC_MSG_RESULT($use_exec) -if test "$use_exec" = no ; then - AC_DEFINE(NO_EXEC,1,[Define to disable all external program execution]) -fi - -if test "$use_exec" = yes ; then - AC_MSG_CHECKING([whether to enable photo ID viewing]) - AC_ARG_ENABLE(photo-viewers, - [ --disable-photo-viewers disable photo ID viewers], - [if test "$enableval" = no ; then - AC_DEFINE(DISABLE_PHOTO_VIEWER,1,[define to disable photo viewing]) - fi],enableval=yes) - gnupg_cv_enable_photo_viewers=$enableval - AC_MSG_RESULT($enableval) - - if test "$gnupg_cv_enable_photo_viewers" = yes ; then - AC_MSG_CHECKING([whether to use a fixed photo ID viewer]) - AC_ARG_WITH(photo-viewer, - [ --with-photo-viewer=FIXED_VIEWER set a fixed photo ID viewer], - [if test "$withval" = yes ; then - withval=no - elif test "$withval" != no ; then - AC_DEFINE_UNQUOTED(FIXED_PHOTO_VIEWER,"$withval", - [if set, restrict photo-viewer to this]) - fi],withval=no) - AC_MSG_RESULT($withval) - fi - - AC_MSG_CHECKING([whether to enable external keyserver helpers]) - AC_ARG_ENABLE(keyserver-helpers, - [ --disable-keyserver-helpers disable all external keyserver support], - [if test "$enableval" = no ; then - AC_DEFINE(DISABLE_KEYSERVER_HELPERS,1, - [define to disable keyserver helpers]) - fi],enableval=yes) - gnupg_cv_enable_keyserver_helpers=$enableval - AC_MSG_RESULT($enableval) - - if test "$gnupg_cv_enable_keyserver_helpers" = yes ; then - AC_MSG_CHECKING([whether LDAP keyserver support is requested]) - AC_ARG_ENABLE(ldap, - [ --disable-ldap disable LDAP keyserver interface], - try_ldap=$enableval, try_ldap=yes) - AC_MSG_RESULT($try_ldap) - - AC_MSG_CHECKING([whether HKP keyserver support is requested]) - AC_ARG_ENABLE(hkp, - [ --disable-hkp disable HKP keyserver interface], - try_hkp=$enableval, try_hkp=yes) - AC_MSG_RESULT($try_hkp) - - if test "$try_hkp" = yes ; then - AC_SUBST(GPGKEYS_HKP,"gpgkeys_hkp$EXEEXT") - fi - - AC_MSG_CHECKING([whether email keyserver support is requested]) - AC_ARG_ENABLE(mailto, - [ --disable-mailto disable email keyserver interface], - try_mailto=$enableval, try_mailto=yes) - AC_MSG_RESULT($try_mailto) - fi - - AC_MSG_CHECKING([whether keyserver exec-path is enabled]) - AC_ARG_ENABLE(keyserver-path, - [ --disable-keyserver-path disable the exec-path option for keyserver helpers], - [if test "$enableval" = no ; then - AC_DEFINE(DISABLE_KEYSERVER_PATH,1,[define to disable exec-path for keyserver helpers]) - fi],enableval=yes) - AC_MSG_RESULT($enableval) - fi - -AC_MSG_CHECKING([whether the included zlib is requested]) -AC_ARG_WITH(included-zlib, - [ --with-included-zlib use the zlib code included here], -[g10_force_zlib=yes], [g10_force_zlib=no] ) -AC_MSG_RESULT($g10_force_zlib) - -dnl -dnl Check whether we want to use Linux capabilities -dnl -AC_MSG_CHECKING([whether use of capabilities is requested]) -AC_ARG_WITH(capabilities, - [ --with-capabilities use linux capabilities [default=no]], -[use_capabilities="$withval"],[use_capabilities=no]) -AC_MSG_RESULT($use_capabilities) - - -AH_BOTTOM([ -/* Some global constants. */ -#ifdef HAVE_DRIVE_LETTERS -#define GNUPG_DEFAULT_HOMEDIR "c:/gnupg" -#elif defined(__VMS) -#define GNUPG_DEFAULT_HOMEDIR "/SYS\$LOGIN/gnupg" -#else -#define GNUPG_DEFAULT_HOMEDIR "~/.gnupg" -#endif -#define GNUPG_PRIVATE_KEYS_DIR "private-keys-v1.d" - -/* Tell libgcrypt not to use its own libgpg-error implementation. */ -#define USE_LIBGPG_ERROR 1 - -/* This is the major version number of GnuPG so that - source included files can test for this. Note, that\ - we use 2 here even for GnuPG 1.9.x. */ -#define GNUPG_MAJOR_VERSION 2 - -/* Now to separate file name parts. - Please note that the string version must not contain more - than one character because the code assumes strlen()==1 */ -#ifdef HAVE_DOSISH_SYSTEM -#define DIRSEP_C '\\' -#define EXTSEP_C '.' -#define DIRSEP_S "\\" -#define EXTSEP_S "." -#else -#define DIRSEP_C '/' -#define EXTSEP_C '.' -#define DIRSEP_S "/" -#define EXTSEP_S "." -#endif - -/* This is the same as VERSION, but should be overridden if the - platform cannot handle things like dots '.' in filenames. Set - SAFE_VERSION_DOT and SAFE_VERSION_DASH to whatever SAFE_VERSION - uses for dots and dashes. */ -#define SAFE_VERSION VERSION -#define SAFE_VERSION_DOT '.' -#define SAFE_VERSION_DASH '-' - -/* For some systems (DOS currently), we hardcode the path here. For - POSIX systems the values are constructed by the Makefiles, so that - the values may be overridden by the make invocations; this is to - comply with the GNU coding standards. */ -#ifdef HAVE_DRIVE_LETTERS -#define GNUPG_BINDIR "c:\\gnupg" -#define GNUPG_LIBEXECDIR "c:\\lib\\gnupg" -#define GNUPG_LIBDIR "c:\\lib\\gnupg" -#define GNUPG_DATADIR "c:\\lib\\gnupg" -#endif - -/* Setup the hardwired names of modules. */ -#ifndef GNUPG_DEFAULT_AGENT -#define GNUPG_DEFAULT_AGENT ( GNUPG_BINDIR DIRSEP_S "gpg-agent" ) -#endif -#ifndef GNUPG_DEFAULT_PINENTRY -#define GNUPG_DEFAULT_PINENTRY ( GNUPG_BINDIR DIRSEP_S "pinentry" ) -#endif -#ifndef GNUPG_DEFAULT_SCDAEMON -#define GNUPG_DEFAULT_SCDAEMON ( GNUPG_BINDIR DIRSEP_S "scdaemon" ) -#endif -#ifndef GNUPG_DEFAULT_DIRMNGR -#define GNUPG_DEFAULT_DIRMNGR ( GNUPG_BINDIR DIRSEP_S "dirmngr" ) -#endif -#ifndef GNUPG_DEFAULT_PROTECT_TOOL -#define GNUPG_DEFAULT_PROTECT_TOOL \ - ( GNUPG_LIBEXECDIR DIRSEP_S "gpg-protect-tool" ) -#endif - - -/* Derive some other constants. */ -#if !(defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID)) -#define EXEC_TEMPFILE_ONLY -#endif - -]) - -AM_MAINTAINER_MODE - -# Checks for programs. -AC_PROG_MAKE_SET -AM_SANITY_CHECK -missing_dir=`cd $ac_aux_dir && pwd` -AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) -AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) -AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) -AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) -AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) -AC_PROG_AWK -AC_PROG_CC -AC_PROG_CPP -AC_PROG_INSTALL -AC_PROG_LN_S -AC_PROG_MAKE_SET -AC_PROG_RANLIB -AC_CHECK_TOOL(AR, ar, :) -AC_PATH_PROG(PERL,"perl") -AC_ISC_POSIX -AC_SYS_LARGEFILE -AC_CHECK_PROG(DOCBOOK_TO_MAN, docbook-to-man, yes, no) -AM_CONDITIONAL(HAVE_DOCBOOK_TO_MAN, test "$ac_cv_prog_DOCBOOK_TO_MAN" = yes) -GNUPG_CHECK_FAQPROG -GNUPG_CHECK_DOCBOOK_TO_TEXI - - -try_gettext=yes -have_dosish_system=no -case "${target}" in - *-*-mingw32*) - # special stuff for Windoze NT - ac_cv_have_dev_random=no - AC_DEFINE(USE_ONLY_8DOT3,1, - [set this to limit filenames to the 8.3 format]) - AC_DEFINE(HAVE_DRIVE_LETTERS,1, - [defined if we must run on a stupid file system]) - AC_DEFINE(USE_SIMPLE_GETTEXT,1, - [because the Unix gettext has too much overhead on - MingW32 systems and these systems lack Posix functions, - we use a simplified version of gettext]) - have_dosish_system=yes - try_gettext="no" - ;; - i?86-emx-os2 | i?86-*-os2*emx ) - # OS/2 with the EMX environment - ac_cv_have_dev_random=no - AC_DEFINE(HAVE_DRIVE_LETTERS) - have_dosish_system=yes - try_gettext="no" - ;; - - i?86-*-msdosdjgpp*) - # DOS with the DJGPP environment - ac_cv_have_dev_random=no - AC_DEFINE(HAVE_DRIVE_LETTERS) - have_dosish_system=yes - try_gettext="no" - ;; - - *-*-freebsd*) - # FreeBSD - CPPFLAGS="$CPPFLAGS -I/usr/local/include" - LDFLAGS="$LDFLAGS -L/usr/local/lib" - ;; - - *-*-hpux*) - if test -z "$GCC" ; then - CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE" - fi - ;; - *-dec-osf4*) - if test -z "$GCC" ; then - # Suppress all warnings - # to get rid of the unsigned/signed char mismatch warnings. - CFLAGS="$CFLAGS -w" - fi - ;; - *-dec-osf5*) - if test -z "$GCC" ; then - # Use the newer compiler `-msg_disable ptrmismatch' to - # get rid of the unsigned/signed char mismatch warnings. - # Using this may hide other pointer mismatch warnings, but - # it at least lets other warning classes through - CFLAGS="$CFLAGS -msg_disable ptrmismatch" - fi - ;; - m68k-atari-mint) - ;; - *) - ;; -esac - -if test "$have_dosish_system" = yes; then - AC_DEFINE(HAVE_DOSISH_SYSTEM,1, - [defined if we run on some of the PCDOS like systems - (DOS, Windoze. OS/2) with special properties like - no file modes]) -fi -AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = yes) - - -# -# Checks for libraries. -# - - -# -# libgpg-error is a library with error codes shared between GnuPG -# related projects. -# -AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION", - have_gpg_error=yes,have_gpg_error=no) - - -# -# Libgcrypt is our generic crypto library -# -AM_PATH_LIBGCRYPT("$NEED_LIBGCRYPT_API:$NEED_LIBGCRYPT_VERSION", - have_libgcrypt=yes,have_libgcrypt=no) - - -# -# libassuan is used for IPC -# -AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_VERSION", - have_libassuan=yes,have_libassuan=no) - - -# -# libksba is our X.509 support library -# -AM_PATH_KSBA("$NEED_KSBA_VERSION",have_ksba=yes,have_ksba=no) - -# -# libusb allows us to use the integrated CCID smartcard reader driver. -# -# Note, that we need the CVS version. FIXME: libusb should have a -# regular check as the other libraries do. -# -AC_CHECK_LIB(usb, usb_find_device, - [ LIBUSB_LIBS="$LIBUSB_LIBS -lusb" - AC_DEFINE(HAVE_LIBUSB,1, - [defined if libusb is available]) - ]) -AC_SUBST(LIBUSB_LIBS) - - -# -# OpenSC is needed by the SCdaemon - if it is not availbale we can only -# build a limited SCdaemon -# -AM_PATH_OPENSC("$NEED_OPENSC_VERSION",have_opensc=yes,have_opensc=no) -if test $have_opensc = yes; then - AC_DEFINE(HAVE_OPENSC,1, - [defined if the OpenSC library is available]) -fi - -# -# Check whether the (highly desirable) GNU Pth library is available -# -AC_ARG_WITH(pth-prefix, - AC_HELP_STRING([--with-pth-prefix=PFX], - [prefix where GNU Pth is installed (optional)]), - pth_config_prefix="$withval", pth_config_prefix="") -if test x$pth_config_prefix != x ; then - PTH_CONFIG="$pth_config_prefix/bin/pth-config" -fi -AC_PATH_PROG(PTH_CONFIG, pth-config, no) -if test "$PTH_CONFIG" = "no"; then - AC_MSG_WARN([[ -*** -*** To support concurrent access to the gpg-agent and the SCdaemon -*** we need the support of the GNU Portable Threads Library. -*** Download it from ftp://ftp.gnu.org/gnu/pth/ -*** On a Debian GNU/Linux system you might want to try -*** apt-get install libpth-dev -***]]) -else - GNUPG_PTH_VERSION_CHECK(1.3.7) - if test $have_pth = yes; then - PTH_CFLAGS=`$PTH_CONFIG --cflags` - PTH_LIBS=`$PTH_CONFIG --ldflags` - PTH_LIBS="$PTH_LIBS `$PTH_CONFIG --libs`" - AC_DEFINE(USE_GNU_PTH, 1, - [Defined if the GNU Portable Thread Library should be used]) - fi -fi -AC_SUBST(PTH_CFLAGS) -AC_SUBST(PTH_LIBS) - -AC_ARG_ENABLE(threads, - AC_HELP_STRING([--disable-threads],[allow building without Pth support]); - -) - - -dnl Must check for network library requirements before doing link tests -dnl for ldap, for example. If ldap libs are static (or dynamic and without -dnl ELF runtime link paths), then link will fail and LDAP support won't -dnl be detected. - -AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname, - [NETLIBS="-lnsl $NETLIBS"])) -AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt, - [NETLIBS="-lsocket $NETLIBS"])) - -dnl Now try for the resolver functions so we can use DNS SRV - -AC_ARG_ENABLE(dns-srv, - AC_HELP_STRING([--disable-dns-srv],[disable the use of DNS SRV in HKP]), - use_dns_srv=$enableval,use_dns_srv=yes) - -if test x"$try_hkp" = xyes && test x"$use_dns_srv" = xyes ; then - _srv_save_libs=$LIBS - LIBS="" - # the double underscore thing is a glibc-ism? - AC_SEARCH_LIBS(res_query,resolv bind,, - AC_SEARCH_LIBS(__res_query,resolv bind,,use_dns_srv=no)) - AC_SEARCH_LIBS(dn_expand,resolv bind,, - AC_SEARCH_LIBS(__dn_expand,resolv bind,,use_dns_srv=no)) - AC_SEARCH_LIBS(dn_skipname,resolv bind,, - AC_SEARCH_LIBS(__dn_skipname,resolv bind,,use_dns_srv=no)) - - if test x"$use_dns_srv" = xyes ; then - AC_DEFINE(USE_DNS_SRV,1,[define to use DNS SRV]) - SRVLIBS=$LIBS - else - AC_MSG_WARN([Resolver functions not found. Disabling DNS SRV.]) - fi - LIBS=$_srv_save_libs -fi - -AC_SUBST(SRVLIBS) - -# Try and link a LDAP test program to weed out unusable LDAP -# libraries. -lldap [-llber [-lresolv]] is for OpenLDAP. OpenLDAP in -# general is terrible with creating weird dependencies. If all else -# fails, the user can play guess-the-dependency by using something -# like ./configure LDAPLIBS="-Lfoo -lbar" - -if test "$try_ldap" = yes ; then - for MY_LDAPLIBS in ${LDAPLIBS+"$LDAPLIBS"} "-lldap" "-lldap -llber" "-lldap -llber -lresolv"; do - _ldap_save_libs=$LIBS - LIBS="$MY_LDAPLIBS $NETLIBS $LIBS" - - AC_MSG_CHECKING([whether LDAP via \"$MY_LDAPLIBS\" is present and sane]) - AC_TRY_LINK([#include ],[ldap_open("foobar",1234);], - [gnupg_cv_func_ldap_init=yes],[gnupg_cv_func_ldap_init=no]) - AC_MSG_RESULT([$gnupg_cv_func_ldap_init]) - - if test $gnupg_cv_func_ldap_init = no; then - AC_MSG_CHECKING([whether I can make LDAP be sane with lber.h]) - AC_TRY_LINK([#include -#include ],[ldap_open("foobar",1234);], - [gnupg_cv_func_ldaplber_init=yes],[gnupg_cv_func_ldaplber_init=no]) - AC_MSG_RESULT([$gnupg_cv_func_ldaplber_init]) - fi - - if test "$gnupg_cv_func_ldaplber_init" = yes ; then - AC_DEFINE(NEED_LBER_H,1,[Define if the LDAP library requires including lber.h before ldap.h]) - fi - - if test "$gnupg_cv_func_ldap_init" = yes || \ - test "$gnupg_cv_func_ldaplber_init" = yes ; then - LDAPLIBS=$MY_LDAPLIBS - GPGKEYS_LDAP="gpgkeys_ldap$EXEEXT" - - AC_MSG_CHECKING([whether LDAP supports ldap_get_option]) - - if test "$gnupg_cv_func_ldap_init" = yes ; then - AC_TRY_LINK([#include ], - [ldap_get_option((void *)0,0,(void *)0);], - [gnupg_cv_func_ldap_get_option=yes], - [gnupg_cv_func_ldap_get_option=no]) - else - AC_TRY_LINK([#include -#include ],[ldap_get_option((void *)0,0,(void *)0);], - [gnupg_cv_func_ldap_get_option=yes], - [gnupg_cv_func_ldap_get_option=no]) - fi - - AC_MSG_RESULT([$gnupg_cv_func_ldap_get_option]) - - if test "$gnupg_cv_func_ldap_get_option" = yes ; then - AC_DEFINE(HAVE_LDAP_GET_OPTION,1,[Define if the LDAP library has ldap_get_option]) - else - AC_MSG_CHECKING([whether LDAP supports ld_errno]) - - if test "$gnupg_cv_func_ldap_init" = yes ; then - AC_TRY_COMPILE([#include ], - [LDAP *ldap; ldap->ld_errno;], - [gnupg_cv_func_ldap_ld_errno=yes], - [gnupg_cv_func_ldap_ld_errno=no]) - else - AC_TRY_LINK([#include -#include ],[LDAP *ldap; ldap->ld_errno;], - [gnupg_cv_func_ldap_ld_errno=yes], - [gnupg_cv_func_ldap_ld_errno=no]) - fi - - AC_MSG_RESULT([$gnupg_cv_func_ldap_ld_errno]) - - if test "$gnupg_cv_func_ldap_ld_errno" = yes ; then - AC_DEFINE(HAVE_LDAP_LD_ERRNO,1,[Define if the LDAP library supports ld_errno]) - fi - fi - fi - - LIBS=$_ldap_save_libs - - if test "$GPGKEYS_LDAP" != "" ; then break; fi - done -fi - -AC_SUBST(GPGKEYS_LDAP) -AC_SUBST(LDAPLIBS) - -dnl This isn't necessarily sendmail itself, but anything that gives a -dnl sendmail-ish interface to the outside world. That includes qmail, -dnl postfix, etc. Basically, anything that can handle "sendmail -t". - -if test "$try_mailto" = yes ; then - AC_ARG_WITH(mailprog,[ --with-mailprog=NAME use "NAME -t" for mail transport],,with_mailprog=yes) - - if test "$with_mailprog" = yes ; then - AC_PATH_PROG(SENDMAIL,sendmail,,$PATH:/usr/sbin:/usr/libexec:/usr/lib) - if test "$ac_cv_path_SENDMAIL" ; then - GPGKEYS_MAILTO="gpgkeys_mailto" - fi - elif test "$with_mailprog" != no ; then - AC_MSG_CHECKING([for a mail transport program]) - AC_SUBST(SENDMAIL,$with_mailprog) - AC_MSG_RESULT($with_mailprog) - GPGKEYS_MAILTO="gpgkeys_mailto" - fi -fi - -AC_SUBST(GPGKEYS_MAILTO) - -case "${target}" in - *-*-mingw32*) - PRINTABLE_OS_NAME="MingW32" - ;; - *-*-cygwin*) - PRINTABLE_OS_NAME="Cygwin" - ;; - i?86-emx-os2 | i?86-*-os2*emx ) - PRINTABLE_OS_NAME="OS/2" - ;; - i?86-*-msdosdjgpp*) - PRINTABLE_OS_NAME="MSDOS/DJGPP" - try_dynload=no - ;; - *-linux*) - PRINTABLE_OS_NAME="GNU/Linux" - ;; - *) - PRINTABLE_OS_NAME=`uname -s || echo "Unknown"` - ;; -esac -AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME", - [A human readable text with the name of the OS]) - - -AM_GNU_GETTEXT_VERSION(0.12.1) -if test "$try_gettext" = yes; then - AM_GNU_GETTEXT(,[need-ngettext]) - - # gettext requires some extra checks. These really should be part of - # the basic AM_GNU_GETTEXT macro. TODO: move other gettext-specific - # function checks to here. - - AC_CHECK_FUNCS(strchr) -else - USE_NLS=no - USE_INCLUDED_LIBINTL=no - BUILD_INCLUDED_LIBINTL=no - AC_SUBST(USE_NLS) - AC_SUBST(USE_INCLUDED_LIBINTL) - AC_SUBST(BUILD_INCLUDED_LIBINTL) -fi - -# Checks for header files. -AC_HEADER_STDC -AC_CHECK_HEADERS(string.h unistd.h langinfo.h termio.h locale.h) - -# Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_C_INLINE -AC_TYPE_SIZE_T -AC_TYPE_SIGNAL -AC_DECL_SYS_SIGLIST - -GNUPG_CHECK_ENDIAN - -GNUPG_CHECK_TYPEDEF(byte, HAVE_BYTE_TYPEDEF) -GNUPG_CHECK_TYPEDEF(ushort, HAVE_USHORT_TYPEDEF) -GNUPG_CHECK_TYPEDEF(ulong, HAVE_ULONG_TYPEDEF) -GNUPG_CHECK_TYPEDEF(u16, HAVE_U16_TYPEDEF) -GNUPG_CHECK_TYPEDEF(u32, HAVE_U32_TYPEDEF) - -AC_CHECK_SIZEOF(unsigned short) -AC_CHECK_SIZEOF(unsigned int) -AC_CHECK_SIZEOF(unsigned long) -AC_CHECK_SIZEOF(unsigned long long) -# Ensure that we have UINT64_C before we bother to check for uint64_t -# fixme: really needed in gnupg? I think it is only useful in libcgrypt. -AC_CACHE_CHECK([for UINT64_C],[gnupg_cv_uint64_c_works], - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([#include -uint64_t foo=UINT64_C(42);]),gnupg_cv_uint64_c_works=yes,gnupg_cv_uint64_c_works=no)) -if test "$gnupg_cv_uint64_c_works" = "yes" ; then - AC_CHECK_SIZEOF(uint64_t) -fi - - - - -if test "$ac_cv_sizeof_unsigned_short" = "0" \ - || test "$ac_cv_sizeof_unsigned_int" = "0" \ - || test "$ac_cv_sizeof_unsigned_long" = "0"; then - AC_MSG_WARN([Hmmm, something is wrong with the sizes - using defaults]); -fi - -dnl Do we have any 64-bit data types? -if test "$ac_cv_sizeof_unsigned_int" != "8" \ - && test "$ac_cv_sizeof_unsigned_long" != "8" \ - && test "$ac_cv_sizeof_unsigned_long_long" != "8" \ - && test "$ac_cv_sizeof_uint64_t" != "8"; then - AC_MSG_WARN([No 64-bit types. Disabling SHA-384, and SHA-512]) -else - if test x"$use_sha512" = xyes ; then - AC_SUBST(SHA512_O,sha512.o) - AC_DEFINE(USE_SHA512,1,[Define to include the SHA-384 and SHA-512 digests]) - fi -fi - -GNUPG_SYS_SO_PEERCRED - -# Checks for library functions. -AC_FUNC_FSEEKO -AC_FUNC_VPRINTF -AC_FUNC_FORK -AC_CHECK_FUNCS(strerror stpcpy strsep strlwr tcgetattr strtoul mmap) -AC_CHECK_FUNCS(strcasecmp strncasecmp ctermid times gmtime_r) -AC_CHECK_FUNCS(memmove gettimeofday getrusage setrlimit clock_gettime) -AC_CHECK_FUNCS(atexit raise getpagesize strftime nl_langinfo setlocale) -AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask rand pipe stat getaddrinfo) - -AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include ]) - -# These are needed by libjnlib - fixme: we should have macros for them -AC_CHECK_FUNCS(memicmp stpcpy strlwr strtoul memmove stricmp strtol) -AC_CHECK_FUNCS(getrusage setrlimit stat setlocale) -AC_CHECK_FUNCS(flockfile funlockfile fopencookie funopen) - -AC_REPLACE_FUNCS(vasprintf) -AC_REPLACE_FUNCS(mkdtemp) -AC_REPLACE_FUNCS(fseeko ftello) -AC_REPLACE_FUNCS(isascii) -AC_REPLACE_FUNCS(putc_unlocked) - - - - -# -# check for gethrtime and run a testprogram to see whether -# it is broken. It has been reported that some Solaris and HP UX systems -# raise an SIGILL -# -AC_CACHE_CHECK([for gethrtime], - [gnupg_cv_func_gethrtime], - [AC_TRY_LINK([#include ],[ - hrtime_t tv; - tv = gethrtime(); - ], - [gnupg_cv_func_gethrtime=yes], - [gnupg_cv_func_gethrtime=no]) - ]) -if test $gnupg_cv_func_gethrtime = yes; then - AC_DEFINE([HAVE_GETHRTIME], 1, - [Define if you have the `gethrtime(2)' function.]) - AC_CACHE_CHECK([whether gethrtime is broken], - [gnupg_cv_func_broken_gethrtime], - [AC_TRY_RUN([ - #include - int main () { - hrtime_t tv; - tv = gethrtime(); - } - ], - [gnupg_cv_func_broken_gethrtime=no], - [gnupg_cv_func_broken_gethrtime=yes], - [gnupg_cv_func_broken_gethrtime=assume-no]) - ]) - if test $gnupg_cv_func_broken_gethrtime = yes; then - AC_DEFINE([HAVE_BROKEN_GETHRTIME], 1, - [Define if `gethrtime(2)' does not work correctly i.e. issues a SIGILL.]) - fi -fi - - -GNUPG_CHECK_MLOCK -GNUPG_FUNC_MKDIR_TAKES_ONE_ARG - -dnl -dnl Check whether we can use Linux capabilities as requested -dnl -if test "$use_capabilities" = "yes" ; then -use_capabilities=no -AC_CHECK_HEADERS(sys/capability.h) -if test "$ac_cv_header_sys_capability_h" = "yes" ; then - AC_CHECK_LIB(cap, cap_init, ac_need_libcap=1) - if test "$ac_cv_lib_cap_cap_init" = "yes"; then - AC_DEFINE(USE_CAPABILITIES,1, - [define if capabilities should be used]) - AC_SUBST(CAPLIBS,"-lcap") - use_capabilities=yes - fi -fi -if test "$use_capabilities" = "no" ; then - AC_MSG_WARN([[ -*** -*** The use of capabilities on this system is not possible. -*** You need a recent Linux kernel and some patches: -*** fcaps-2.2.9-990610.patch (kernel patch for 2.2.9) -*** fcap-module-990613.tar.gz (kernel module) -*** libcap-1.92.tar.gz (user mode library and utilities) -*** And you have to configure the kernel with CONFIG_VFS_CAP_PLUGIN -*** set (filesystems menu). Be warned: This code is *really* ALPHA. -***]]) -fi -fi - - -# Sanity check regex. Tests adapted from mutt. - -AC_MSG_CHECKING([whether regular expression support is requested]) -AC_ARG_ENABLE(regex, -[ --disable-regex do not handle regular expressions in trust sigs], - use_regex=$enableval, use_regex=yes) -AC_MSG_RESULT($use_regex) - -if test "$use_regex" = yes ; then - AC_MSG_CHECKING([whether the included regex lib is requested]) - AC_ARG_WITH(included-regex, - [ --with-included-regex use the included GNU regex library], - [gnupg_cv_included_regex=yes],[gnupg_cv_included_regex=no]) - AC_MSG_RESULT($gnupg_cv_included_regex) - - if test $gnupg_cv_included_regex = no ; then - # Does the system have regex functions at all? - AC_CHECK_FUNC(regcomp,gnupg_cv_included_regex=no, - gnupg_cv_included_regex=yes) - fi - - if test $gnupg_cv_included_regex = no ; then - AC_CACHE_CHECK([whether your system's regexp library is broken], - [gnupg_cv_regex_broken], - AC_TRY_RUN([ -#include -#include -main() { regex_t blah ; regmatch_t p; p.rm_eo = p.rm_eo; return regcomp(&blah, "foo.*bar", REG_NOSUB) || regexec (&blah, "foobar", 0, NULL, 0); }], - gnupg_cv_regex_broken=no, gnupg_cv_regex_broken=yes, gnupg_cv_regex_broken=yes)) - - if test $gnupg_cv_regex_broken = yes ; then - AC_MSG_WARN(your regex is broken - using the included GNU regex instead.) - gnupg_cv_included_regex=yes - fi - fi - - if test $gnupg_cv_included_regex = yes; then - AC_DEFINE(USE_GNU_REGEX,1,[ Define if you want to use the included regex lib ]) - AC_SUBST(REGEX_O,regex.o) - fi -else - - AC_DEFINE(DISABLE_REGEX,1,[ Define to disable regular expression support ]) -fi - -dnl Do we have zlib? Must do it here because Solaris failed -dnl when compiling a conftest (due to the "-lz" from LIBS). -use_local_zlib=yes -if test "$g10_force_zlib" = "yes"; then - : -else - _cppflags="${CPPFLAGS}" - _ldflags="${LDFLAGS}" - - AC_ARG_WITH(zlib, - [ --with-zlib=DIR use libz in DIR],[ - if test -d "$withval"; then - CPPFLAGS="${CPPFLAGS} -I$withval/include" - LDFLAGS="${LDFLAGS} -L$withval/lib" - fi - ]) - - AC_CHECK_HEADER(zlib.h, - AC_CHECK_LIB(z, deflateInit2_, - use_local_zlib=no - LIBS="$LIBS -lz", - CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}), - CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}) -fi - -if test "$use_local_zlib" = yes ; then - AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, true) - AC_CONFIG_LINKS(zlib.h:zlib/zlib.h zconf.h:zlib/zconf.h ) - ZLIBS="../zlib/libzlib.a" -else - AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, false) - ZLIBS= -fi -AC_SUBST(ZLIBS) - -# Allow users to append something to the version string without -# flagging it as development version. The user version parts is -# considered everything after a dash. -if test "$development_version" != yes; then - changequote(,)dnl - tmp_pat='[a-zA-Z]' - changequote([,])dnl - if echo "$VERSION" | sed 's/-.*//' | grep "$tmp_pat" >/dev/null ; then - development_version=yes - fi -fi -if test "$development_version" = yes; then - AC_DEFINE(IS_DEVELOPMENT_VERSION,1, - [Defined if this is not a regular release]) -fi - -AM_CONDITIONAL(CROSS_COMPILING, test x$cross_compiling = xyes) - -GNUPG_CHECK_GNUMAKE - -# add some extra libs here so that previous tests don't fail for -# mysterious reasons - the final link step should bail out. -case "${target}" in - *-*-mingw32*) - W32LIBS="-lwsock32" - ;; - *) - ;; -esac - - -if test "$GCC" = yes; then - if test "$USE_MAINTAINER_MODE" = "yes"; then - CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" - CFLAGS="$CFLAGS -Wformat-nonliteral" - else - CFLAGS="$CFLAGS -Wall" - fi -fi - -AC_SUBST(NETLIBS) -AC_SUBST(W32LIBS) - - -# We use jnlib, so tell other modules about it -AC_DEFINE(HAVE_JNLIB_LOGGING, 1, - [Defined if jnlib style logging fucntions are available]) - - - -# -# Decide what to build -# -missing_pth=no -if test $have_ksba = no; then - build_gpgsm=no - build_scdaemon=no -fi - -build_agent_threaded="" -if test "$build_agent" = "yes"; then - if test $have_pth = no; then - build_agent_threaded="(not multi-threaded)" - missing_pth=yes - fi -fi - -build_scdaemon_extra="" -if test "$build_scdaemon" = "yes"; then - tmp="" - if test $have_pth = no; then - build_scdaemon_extra="not multi-threaded" - tmp=", " - missing_pth=yes - fi - if test $have_opensc = no; then - build_scdaemon_extra="${build_scdaemon_extra}${tmp}no pkcs#15" - tmp=", " - fi - if test -n "$build_scdaemon_extra"; then - build_scdaemon_extra="(${build_scdaemon_extra})" - fi -fi - -AM_CONDITIONAL(BUILD_GPG, test "$build_gpg" = "yes") -AM_CONDITIONAL(BUILD_GPGSM, test "$build_gpgsm" = "yes") -AM_CONDITIONAL(BUILD_AGENT, test "$build_agent" = "yes") -AM_CONDITIONAL(BUILD_SCDAEMON, test "$build_scdaemon" = "yes") - - - -# -# Print errors here so that they are visible all -# together and the user can acquire them all together. -# -die=no -if test "$have_gpg_error" = "no"; then - die=yes - AC_MSG_NOTICE([[ -*** -*** You need libgpg-error to build this program. -** This library is for example available at -*** ftp://ftp.gnupg.org/gcrypt/alpha/libgpg-error -*** (at least version $NEED_GPG_ERROR_VERSION is required.) -***]]) -fi -if test "$have_libgcrypt" = "no"; then - die=yes - AC_MSG_NOTICE([[ -*** -*** You need libgcrypt to build this program. -** This library is for example available at -*** ftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/ -*** (at least version $NEED_LIBGCRYPT_VERSION using API $NEED_LIBGCRYPT_API) is required.) -***]]) -fi -if test "$have_libassuan" = "no"; then - die=yes - AC_MSG_NOTICE([[ -*** -*** You need libassuan to build this program. -*** This library is for example available at -*** ftp://ftp.gnupg.org/gcrypt/alpha/libassuan/ -*** (at least version $NEED_LIBASSUAN_VERSION is required). -***]]) -fi -if test "$have_ksba" = "no"; then - die=yes - AC_MSG_NOTICE([[ -*** -*** You need libksba to build this program. -*** This library is for example available at -*** ftp://ftp.gnupg.org/gcrypt/alpha/libksba/ -*** (at least version $NEED_KSBA_VERSION is required). -***]]) -fi -if test "$missing_pth" = "yes"; then - AC_MSG_NOTICE([[ -*** -*** It is strongly suggested to build with support for the -*** GNU Portable Threads Library (Pth). Please install this -*** library first or use --disable-threads to allow building -*** anyway. The library is for example available at -*** ftp://ftp.gnu.org/gnu/pth/ -*** On a Debian GNU/Linux system you can install it using -*** apt-get install libpth-dev -***]]) - if test "$enable_threads" != "no"; then - die=yes - fi -fi - -if test "$die" = "yes"; then - AC_MSG_ERROR([[ -*** -*** Required libraries not found. Please consult the above messages -*** and install them before running configure again. -***]]) -fi - - - -AC_CONFIG_FILES([ m4/Makefile -Makefile -po/Makefile.in -intl/Makefile -jnlib/Makefile -common/Makefile -kbx/Makefile -g10/Makefile -sm/Makefile -agent/Makefile -scd/Makefile -tools/Makefile -doc/Makefile -tests/Makefile -]) -AC_OUTPUT - - - - -echo " - GnuPG v${VERSION} has been configured as follows: - - Platform: $PRINTABLE_OS_NAME ($target) - - OpenPGP: $build_gpg - S/MIME: $build_gpgsm - Agent: $build_agent $build_agent_threaded - Smartcard: $build_scdaemon $build_scdaemon_extra - - Protect tool: $show_gnupg_protect_tool_pgm - Default agent: $show_gnupg_agent_pgm - Default pinentry: $show_gnupg_pinentry_pgm - Default scdaemon: $show_gnupg_scdaemon_pgm - Default dirmngr: $show_gnupg_dirmngr_pgm -" - diff --git a/doc/ChangeLog b/doc/ChangeLog deleted file mode 100644 index bcc288125..000000000 --- a/doc/ChangeLog +++ /dev/null @@ -1,102 +0,0 @@ -2004-06-18 Werner Koch - - * debugging.texi: New. - * gnupg.texi: Include it. - -2004-05-11 Werner Koch - - * gpgsm.texi (Esoteric Options): Add --debug-allow-core-dump. - -2004-05-03 Werner Koch - - * gpg-agent.texi (Agent Options): Add --allow-mark-trusted. - -2004-02-03 Werner Koch - - * contrib.texi (Contributors): Updated from the gpg 1.2.3 thanks - list. - * gpgsm.texi, gpg-agent.texi, scdaemon.texi: Language cleanups. - -2003-12-01 Werner Koch - - * gpgsm.texi (Certificate Options): Add --{enable,disable}-ocsp. - -2003-11-17 Werner Koch - - * scdaemon.texi (Scdaemon Options): Added --allow-admin and - --deny-admin. - -2003-10-27 Werner Koch - - * gpg-agent.texi (Agent GET_CONFIRMATION): New. - -2002-12-04 Werner Koch - - * gpg-agent.texi (Agent Signals): New. - -2002-12-03 Werner Koch - - * gpgsm.texi (Operational Commands): Add --passwd and - --call-protect-tool. - * gpg-agent.texi (Agent PASSWD): New - -2002-11-13 Werner Koch - - * gpg-agent.texi (Invoking GPG-AGENT): Tell about GPG_TTY. - -2002-11-12 Werner Koch - - * gpgsm.texi (Operational Commands): Add --call-dirmngr. - -2002-09-25 Werner Koch - - * gpg-agent.texi (Agent Options): Add --keep-tty and --keep-display. - -2002-09-12 Werner Koch - - * gpg-agent.texi (Invoking GPG-AGENT): Explained how to start only - one instance. - -2002-08-28 Werner Koch - - * gpg-agent.texi (Agent Options): Explained more options. - * scdaemon.texi (Scdaemon Options): Ditto. - -2002-08-09 Werner Koch - - * Makefile.am (gnupg_TEXINFOS): Include contrib.texi. - -2002-08-06 Werner Koch - - * gpgsm.texi: Added more options. - -2002-07-26 Werner Koch - - * assuan.texi: New. - * gpgsm.texi, scdaemon.texi, gpg-agent.texi: Documented the Assuan - protocol used. - -2002-07-22 Werner Koch - - * gnupg.texi, scdaemon.texi, gpg-agent.texi: New. - * contrib.texi, gpl.texi, fdl.texi: New. - * gpgsm.texi: Made this an include file for gnupg.texi. - * Makefile.am: Build gnupg.info instead of gpgsm.info. - -2002-06-04 Werner Koch - - * gpgsm.texi (Invocation): Described the various debug flags. - -2002-05-14 Werner Koch - - * Makefile.am, gpgsm.texi: New. - - Copyright 2002 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. diff --git a/doc/Makefile.am b/doc/Makefile.am deleted file mode 100644 index d1d72e834..000000000 --- a/doc/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) 2002 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -info_TEXINFOS = gnupg.texi - -gnupg_TEXINFOS = \ - gpgsm.texi gpg-agent.texi scdaemon.texi assuan.texi\ - debugging.texi contrib.texi gpl.texi fdl.texi - -DISTCLEANFILES = gnupg.tmp gnupg.ops - diff --git a/doc/assuan.texi b/doc/assuan.texi deleted file mode 100644 index 2e2219263..000000000 --- a/doc/assuan.texi +++ /dev/null @@ -1,189 +0,0 @@ -@c Copyright (C) 2002 Free Software Foundation, Inc. -@c This is part of the GnuPG manual. -@c For copying conditions, see the file gnupg.texi. - -@node Assuan -@chapter Description of the Assuan protocol. - -The architecture of the modular GnuPG system is based on a couple of -highly specialized modules which make up a network of client server -communication. A common framework for intermodule communication is -therefore needed and should be implemented in a library. - -Goals: - -@itemize @bullet -@item Common framework for module communication -@item Easy debugging -@item Easy module testing -@item Extendible -@item Optional authentication and encryption facility -@item Usable to access external hardware -@end itemize - - -Design criteria: - -@itemize @bullet -@item Client Server with back channel -@item Use a mainly text based protocol -@item Escape certain control characters -@item Allow indefinite data length -@item Request confidentiality for parts of the communication -@item Dummy module should allow direct linking of client and server. -@item Inline data or descriptor passing for bulk data -@item No protection against DoS needed -@item Subliminal channels are not an issue -@end itemize - -Implementation: - -The implementation is line based with a maximum line size of 1000 -octects. The default IPC mechanism are Unix Domain Sockets. - -On a connect request the server responds either with an okay or an error -status. For authentication check the server may send an Inquiry -Response prior to the first Okay, it may also issue Status messages. -The server must check that the client is allowed to connect, this is -done by requesting the credentials for the peer and comparing them to -those of the server. This avoids attacks based on wrong socket -permissions. - -It may choose to delay the first response in case of an error. The -server never closes the connection - however the lower protocol may do -so after some time of inactivity or when the connection is in an error -state. - -All textual messages are assumed to be in UTF-8 unless otherwise noted. - - -Server responses: - -@table @code -@item OK [] -Request was successful. - -@item ERR @var{errorcode} [] -Request could not be fulfilled. The error codes are mostly application -specific except for a few common ones. - -@item S @var{keyword} -Informational output by the server, still processing the request. - -@item # -Comment line issued only for debugging purposes. Totally ignored. - -@item D -Raw data returned to client. There must be exactly one space after the -'D'. The values for '%', CR and LF must be percent escaped; this is -encoded as %25, %0D and %0A. Only uppercase letters should be used in -the hexadecimal representation. Other characters may be percent escaped -for easier debugging. All these Data lines are considered one data -stream up to the OK or ERR response. Status and Inquiry Responses -may be mixed with the Data lines. - -@item INQUIRE @var{keyword}> -Server needs further information from the client. The client should -answer with a command which is allowed after an inquiry. Note that the -server does not confirm that client command but either continues -processing or ends processing with an error status. Not all commands -are allowed. -@end table - - -A client should only check the first letter of each line and then skip -over to the next token (except for data lines where the raw data starts -exactly after 2 bytes). Lines larger than 1000 bytes should be -treated as a communication error. (The rationale for having a line -length limit is to allow for easier multiplexing of multiple channels). - - -Client requests: - -The server waits for client requests after he sent an Okay or Error. -The client should not issue a request in other cases with the -exception of the CANCEL command. - -@example -@var{command} -@end example - -@var{command} is a one word string without preceding white space. -Parameters are command specific, CR, LF and the percent signs should be -percent escaped as described above. To send a backslash as the last -character it should also be percent escaped. Percent escaping is -allowed anywhere in the parameters but not in the command. The line -ends with a CR, LF or just a LF. - -Not yet implemented feature: If there is a need for a parameter list -longer than the line length limit (1000 characters including command and -CR, LF), the last character of the line (right before the CR/LF or LF) -must be a non-escape encoded backslash. The following line is then -expected to be a continuation of the line with the backslash replaced by -a blank and the line ending removed. - -@example -D -@end example - -Raw data to the server. There must be exactly one space after the 'D'. -The values for '%', CR and LF must be percent escaped; this is encoded -as %25, %0D and %0A. Only uppercase letters should be used in the -hexadecimal representation. Other characters may be percent escaped for -easier debugging. All these Data lines are considered one data stream -up to the OKAY or ERROR response. Status and Inquiry Responses may be -mixed with the Data lines. - -@example -END -@end example - - - -Lines beginning with a @code{#} or empty lines are ignored. This is -useful to comment test scripts. - - -Although the commands are application specific, some of them are used by -all protocols and partly directly supported by the Assuan library: - -@table @code -@item CANCEL -his is the one special command which aborts the current request. it can -be sent at any time and the server will stop its operation right before -it would send the next response line (of any type). - -@item BYE -Close the connect, the server will reply with an @code{OK}. - -@item AUTH -Not yet specified as we don't implement it in the first phase. See my -mail to gpa-dev on 2001-10-25 about the rationale for measurements -against local attacks. - -@item RESET -Reset the connection but not any existing authentication. The server -should release all resources associated with the connection. - -@item END -Used by a client to mark the end of raw data. The server may send END -to indicate a partial end of data. -@end table - - -Error Codes: - -Here we keep a list of error codes used in any Assuan based -protocol. The format is the string @code{ERR}, white space, the error -number, white space, a textual description of the error. - -@table @code - -@item 100 Unknown Command -@item 101 Not Implemented - -@item 301 certificate has been revoked [DirMngr] -@item 302 no CRL known for this certificate [DirMngr] -@item 303 CRL is too old and a new one could not be retrieved [DirMngr] - -@end table diff --git a/doc/contrib.texi b/doc/contrib.texi deleted file mode 100644 index 035b6c251..000000000 --- a/doc/contrib.texi +++ /dev/null @@ -1,124 +0,0 @@ -@c Copyright (C) 2002 Free Software Foundation, Inc. -@c This is part of the GnuPG manual. -@c For copying conditions, see the file gnupg.texi. - -@node Contributors -@unnumbered Contributors to GnuPG -@cindex contributors - -The GnuPG project would like to thank its many contributors. Without -them the project would not have been nearly as successful as it has -been. Any omissions in this list are accidental. Feel free to contact -the maintainer if you have been left out or some of your contributions -are not listed. Please keep this list in alphabetical order. - -@itemize @bullet - -@item -Bernhard Herzog did extensive testing and tracked down a lot of bugs - -@item -Bernhard Reiter made sure that we met the specifications and the -deadlines. He did extensive testing and came up with a lot of suggestions. - -@item -Jan-Oliver Wagner made sure that we met the specifications and the -deadlines. He did extensive testing and came up with a lot of suggestions. - -@item -Karl-Heinz Zimmer had to struggle with all the bugs and misconceptions -while working on Kmail integration. - -@item -Marcus Brinkman cleaned up the Assuan code and fixed bugs all over the place. - -@item -Steffen Hansen had a hard time to write the dirmngr due to -underspecified interfaces. - -@item -Thomas Koester did extensive testing and tracked down a lot of bugs - -@item -Werner Koch designed the system and wrote most of the original code. - -@end itemize - -We'd also like to thank these folks who have contributed a lot of time -and energy working on GnuPG over the years: - -David Shaw, Matthew Skala, Michael Roth, Niklas Hernaeus, Nils -Ellmenreich, Rémi Guyomarch, Stefan Bellon, Timo Schulz and Werner -Koch wrote the code. Birger Langkjer, Daniel Resare, Dokianakis -Theofanis, Edmund GRIMLEY EVANS, Gaël Quéri, Gregory Steuck, Nagy -Ferenc László, Ivo Timmermans, Jacobo Tarri'o Barreiro, Janusz -Aleksander Urbanowicz, Jedi Lin, Jouni Hiltunen, Laurentiu Buzdugan, -Magda Procha'zkova', Michael Anckaert, Michal Majer, Marco d'Itri, -Nilgun Belma Buguner, Pedro Morais, Tedi Heriyanto, Thiago Jung -Bauermann, Rafael Caetano dos Santos, Toomas Soome, Urko Lusa, Walter -Koch, Yosiaki IIDA did the official translations. Mike Ashley wrote -and maintains the GNU Privacy Handbook. David Scribner is the current -FAQ editor. Lorenzo Cappelletti maintains the web site. - -The following people helped greatly by suggesting improvements, -testing, fixing bugs, providing resources and doing other important -tasks: Adam Mitchell, Albert Chin, Alec Habig, Allan Clark, Anand -Kumria, Andreas Haumer, Anthony Mulcahy, Ariel T Glenn, Bob Mathews, -Bodo Moeller, Brendan O'Dea, Brenno de Winter, Brian M. Carlson, Brian -Moore, Brian Warner, Bryan Fullerton, Caskey L. Dickson, Cees van de -Griend, Charles Levert, Chip Salzenberg, Chris Adams, Christian Biere, -Christian Kurz, Christian von Roques, Christopher Oliver, Christian -Recktenwald, Dan Winship, Daniel Eisenbud, Daniel Koening, Dave -Dykstra, David C Niemi, David Champion, David Ellement, David -Hallinan, David Hollenberg, David Mathog, David R. Bergstein, Detlef -Lannert, Dimitri, Dirk Lattermann, Dirk Meyer, Disastry, Douglas -Calvert, Ed Boraas, Edmund GRIMLEY EVANS, Edwin Woudt, Enzo -Michelangeli, Ernst Molitor, Fabio Coatti, Felix von Leitner, fish -stiqz, Florian Weimer, Francesco Potorti, Frank Donahoe, Frank -Heckenbach, Frank Stajano, Frank Tobin, Gabriel Rosenkoetter, Gaël -Quéri, Gene Carter, Geoff Keating, Georg Schwarz, Giampaolo Tomassoni, -Gilbert Fernandes, Greg Louis, Greg Troxel, Gregory Steuck, Gregery -Barton, Harald Denker, Holger Baust, Hendrik Buschkamp, Holger -Schurig, Holger Smolinski, Holger Trapp, Hugh Daniel, Huy Le, Ian -McKellar, Ivo Timmermans, Jan Krueger, Jan Niehusmann, Janusz -A. Urbanowicz, James Troup, Jean-loup Gailly, Jeff Long, Jeffery Von -Ronne, Jens Bachem, Jeroen C. van Gelderen, J Horacio MG, J. Michael -Ashley, Jim Bauer, Jim Small, Joachim Backes, Joe Rhett, John -A. Martin, Johnny Teveßen, Jörg Schilling, Jos Backus, Joseph Walton, -Juan F. Codagnone, Jun Kuriyama, Kahil D. Jallad, Karl Fogel, Karsten -Thygesen, Katsuhiro Kondou, Kazu Yamamoto, Keith Clayton, Kevin Ryde, -Klaus Singvogel, Kurt Garloff, Lars Kellogg-Stedman, L. Sassaman, M -Taylor, Marcel Waldvogel, Marco d'Itri, Marco Parrone, Marcus -Brinkmann, Mark Adler, Mark Elbrecht, Mark Pettit, Markus Friedl, -Martin Kahlert, Martin Hamilton, Martin Schulte, Matt Kraai, Matthew -Skala, Matthew Wilcox, Matthias Urlichs, Max Valianskiy, Michael -Engels, Michael Fischer v. Mollard, Michael Roth, Michael Sobolev, -Michael Tokarev, Nicolas Graner, Mike McEwan, Neal H Walfield, Nelson -H. F. Beebe, NIIBE Yutaka, Niklas Hernaeus, Nimrod Zimerman, N J Doye, -Oliver Haakert, Oskari Jääskeläinen, Pascal Scheffers, Paul D. Smith, -Per Cederqvist, Phil Blundell, Philippe Laliberte, Peter Fales, Peter -Gutmann, Peter Marschall, Peter Valchev, Piotr Krukowiecki, QingLong, -Ralph Gillen, Rat, Reinhard Wobst, Rémi Guyomarch, Reuben Sumner, -Richard Outerbridge, Robert Joop, Roddy Strachan, Roger Sondermann, -Roland Rosenfeld, Roman Pavlik, Ross Golder, Ryan Malayter, Sam -Roberts, Sami Tolvanen, Sean MacLennan, Sebastian Klemke, Serge -Munhoven, SL Baur, Stefan Bellon, Dr.Stefan.Dalibor, Stefan Karrmann, -Stefan Keller, Steffen Ullrich, Steffen Zahn, Steven Bakker, Steven -Murdoch, Susanne Schultz, Ted Cabeen, Thiago Jung Bauermann, Thijmen -Klok, Thomas Roessler, Tim Mooney, Timo Schulz, Todd Vierling, TOGAWA -Satoshi, Tom Spindler, Tom Zerucha, Tomas Fasth, Tommi Komulainen, -Thomas Klausner, Tomasz Kozlowski, Thomas Mikkelsen, Ulf Möller, Urko -Lusa, Vincent P. Broman, Volker Quetschke, W Lewis, Walter Hofmann, -Walter Koch, Wayne Chapeskie, Wim Vandeputte, Winona Brown, Yosiaki -IIDA, Yoshihiro Kajiki and Gerlinde Klaes. - -This software has been made possible by the previous work of Chris -Wedgwood, Jean-loup Gailly, Jon Callas, Mark Adler, Martin Hellmann -Paul Kendall, Philip R. Zimmermann, Peter Gutmann, Philip A. Nelson, -Taher ElGamal, Torbjorn Granlund, Whitfield Diffie, some unknown NSA -mathematicians and all the folks who have worked hard to create -complete and free operating systems. - -And finally we'd like to thank everyone who uses these tools, submits -bug reports and generally reminds us why we're doing this work in the -first place. diff --git a/doc/debugging.texi b/doc/debugging.texi deleted file mode 100644 index e5e3e43fd..000000000 --- a/doc/debugging.texi +++ /dev/null @@ -1,82 +0,0 @@ -@c Copyright (C) 2004 Free Software Foundation, Inc. -@c This is part of the GnuPG manual. -@c For copying conditions, see the file gnupg.texi. - -@node Debugging -@chapter How to solve problems - -Everone knows that software often does not do what it should do and thus -there is a need to track down problems. We call this debugging in a -reminiscent to the moth jamming a relay in a Mark II box back in 1947. - -Most of the probelsm a merely configuration and user problems but -nevertheless there are the most annoying ones and reposnible for may -gray hairs. We try to give some guidelines here on how to identify and -solve the problem at hand. - - -@menu -* Debugging Tools:: Description of some useful tools - -@end menu - - -@node Debugging Tools -@section Debugging Tools - -The GnuPG distribution comes with a couple of tools, useful to help find -and solving problems. - -@menu -* kbxutil:: Scrutinizing a keybox file. -@end menu - -@node kbxutil -@subsection Scrutinizing a keybox file - -A keybox is a file fomat used to store public keys along with meta -information and indices. The commonly used one is the file -@file{pubring.kbx} in the @file{.gnupg} directory. It contains all -X.509 certificates as well as OpenPGP keys@footnote{Well, OpenPGP keys -are not implemented, @command{gpg} still used the keyring file -@file{pubring.gpg}} . - -@noindent -When called the standard way, e.g.: - -@samp{kbxutil ~/.gnupg/pubring.kbx} - -@noindent -it lists all records (called @acronym{blobs}) with there meta-information -in a human readable format. - -@noindent -To see statistics on the keybox in question, run it using - -@samp{kbxutil --stats ~/.gnupg/pubring.kbx} - -@noindent -and you get an output like: - -@example -Total number of blobs: 99 - header: 1 - empty: 0 - openpgp: 0 - x509: 98 - non flagged: 81 - secret flagged: 0 - ephemeral flagged: 17 -@end example - -In this example you see that the keybox does not have any OpenPGP keys -but contains 98 X.509 cerificates and a total of 17 keys or certificates -are flagges as ephemeral, meaning that they are only temporary stored -(cached) in the keybox and won't get listed using the usual commands -provided by @command{gpgsm} or @command{gpg}. 81 certifcates are stored -in a standard way and directly available from @command{gpgsm}. - - - - - diff --git a/doc/fdl.texi b/doc/fdl.texi deleted file mode 100644 index 6e40e6df9..000000000 --- a/doc/fdl.texi +++ /dev/null @@ -1,401 +0,0 @@ -@node GNU Free Documentation License -@appendix GNU Free Documentation License - -@cindex FDL, GNU Free Documentation License -@center Version 1.1, March 2000 - -@display -Copyright @copyright{} 2000 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307, USA - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@enumerate 0 -@item -PREAMBLE - -The purpose of this License is to make a manual, textbook, or other -written document @dfn{free} in the sense of freedom: to assure everyone -the effective freedom to copy and redistribute it, with or without -modifying it, either commercially or noncommercially. Secondarily, -this License preserves for the author and publisher a way to get -credit for their work, while not being considered responsible for -modifications made by others. - -This License is a kind of ``copyleft'', which means that derivative -works of the document must themselves be free in the same sense. It -complements the GNU General Public License, which is a copyleft -license designed for free software. - -We have designed this License in order to use it for manuals for free -software, because free software needs free documentation: a free -program should come with manuals providing the same freedoms that the -software does. But this License is not limited to software manuals; -it can be used for any textual work, regardless of subject matter or -whether it is published as a printed book. We recommend this License -principally for works whose purpose is instruction or reference. - -@item -APPLICABILITY AND DEFINITIONS - -This License applies to any manual or other work that contains a -notice placed by the copyright holder saying it can be distributed -under the terms of this License. The ``Document'', below, refers to any -such manual or work. Any member of the public is a licensee, and is -addressed as ``you''. - -A ``Modified Version'' of the Document means any work containing the -Document or a portion of it, either copied verbatim, or with -modifications and/or translated into another language. - -A ``Secondary Section'' is a named appendix or a front-matter section of -the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document's overall subject -(or to related matters) and contains nothing that could fall directly -within that overall subject. (For example, if the Document is in part a -textbook of mathematics, a Secondary Section may not explain any -mathematics.) The relationship could be a matter of historical -connection with the subject or with related matters, or of legal, -commercial, philosophical, ethical or political position regarding -them. - -The ``Invariant Sections'' are certain Secondary Sections whose titles -are designated, as being those of Invariant Sections, in the notice -that says that the Document is released under this License. - -The ``Cover Texts'' are certain short passages of text that are listed, -as Front-Cover Texts or Back-Cover Texts, in the notice that says that -the Document is released under this License. - -A ``Transparent'' copy of the Document means a machine-readable copy, -represented in a format whose specification is available to the -general public, whose contents can be viewed and edited directly and -straightforwardly with generic text editors or (for images composed of -pixels) generic paint programs or (for drawings) some widely available -drawing editor, and that is suitable for input to text formatters or -for automatic translation to a variety of formats suitable for input -to text formatters. A copy made in an otherwise Transparent file -format whose markup has been designed to thwart or discourage -subsequent modification by readers is not Transparent. A copy that is -not ``Transparent'' is called ``Opaque''. - -Examples of suitable formats for Transparent copies include plain -@sc{ascii} without markup, Texinfo input format, La@TeX{} input format, -@acronym{SGML} or @acronym{XML} using a publicly available -@acronym{DTD}, and standard-conforming simple @acronym{HTML} designed -for human modification. Opaque formats include PostScript, -@acronym{PDF}, proprietary formats that can be read and edited only by -proprietary word processors, @acronym{SGML} or @acronym{XML} for which -the @acronym{DTD} and/or processing tools are not generally available, -and the machine-generated @acronym{HTML} produced by some word -processors for output purposes only. - -The ``Title Page'' means, for a printed book, the title page itself, -plus such following pages as are needed to hold, legibly, the material -this License requires to appear in the title page. For works in -formats which do not have any title page as such, ``Title Page'' means -the text near the most prominent appearance of the work's title, -preceding the beginning of the body of the text. - -@item -VERBATIM COPYING - -You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License applies -to the Document are reproduced in all copies, and that you add no other -conditions whatsoever to those of this License. You may not use -technical measures to obstruct or control the reading or further -copying of the copies you make or distribute. However, you may accept -compensation in exchange for copies. If you distribute a large enough -number of copies you must also follow the conditions in section 3. - -You may also lend copies, under the same conditions stated above, and -you may publicly display copies. - -@item -COPYING IN QUANTITY - -If you publish printed copies of the Document numbering more than 100, -and the Document's license notice requires Cover Texts, you must enclose -the copies in covers that carry, clearly and legibly, all these Cover -Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on -the back cover. Both covers must also clearly and legibly identify -you as the publisher of these copies. The front cover must present -the full title with all words of the title equally prominent and -visible. You may add other material on the covers in addition. -Copying with changes limited to the covers, as long as they preserve -the title of the Document and satisfy these conditions, can be treated -as verbatim copying in other respects. - -If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto adjacent -pages. - -If you publish or distribute Opaque copies of the Document numbering -more than 100, you must either include a machine-readable Transparent -copy along with each Opaque copy, or state in or with each Opaque copy -a publicly-accessible computer-network location containing a complete -Transparent copy of the Document, free of added material, which the -general network-using public has access to download anonymously at no -charge using public-standard network protocols. If you use the latter -option, you must take reasonably prudent steps, when you begin -distribution of Opaque copies in quantity, to ensure that this -Transparent copy will remain thus accessible at the stated location -until at least one year after the last time you distribute an Opaque -copy (directly or through your agents or retailers) of that edition to -the public. - -It is requested, but not required, that you contact the authors of the -Document well before redistributing any large number of copies, to give -them a chance to provide you with an updated version of the Document. - -@item -MODIFICATIONS - -You may copy and distribute a Modified Version of the Document under -the conditions of sections 2 and 3 above, provided that you release -the Modified Version under precisely this License, with the Modified -Version filling the role of the Document, thus licensing distribution -and modification of the Modified Version to whoever possesses a copy -of it. In addition, you must do these things in the Modified Version: - -@enumerate A -@item -Use in the Title Page (and on the covers, if any) a title distinct -from that of the Document, and from those of previous versions -(which should, if there were any, be listed in the History section -of the Document). You may use the same title as a previous version -if the original publisher of that version gives permission. - -@item -List on the Title Page, as authors, one or more persons or entities -responsible for authorship of the modifications in the Modified -Version, together with at least five of the principal authors of the -Document (all of its principal authors, if it has less than five). - -@item -State on the Title page the name of the publisher of the -Modified Version, as the publisher. - -@item -Preserve all the copyright notices of the Document. - -@item -Add an appropriate copyright notice for your modifications -adjacent to the other copyright notices. - -@item -Include, immediately after the copyright notices, a license notice -giving the public permission to use the Modified Version under the -terms of this License, in the form shown in the Addendum below. - -@item -Preserve in that license notice the full lists of Invariant Sections -and required Cover Texts given in the Document's license notice. - -@item -Include an unaltered copy of this License. - -@item -Preserve the section entitled ``History'', and its title, and add to -it an item stating at least the title, year, new authors, and -publisher of the Modified Version as given on the Title Page. If -there is no section entitled ``History'' in the Document, create one -stating the title, year, authors, and publisher of the Document as -given on its Title Page, then add an item describing the Modified -Version as stated in the previous sentence. - -@item -Preserve the network location, if any, given in the Document for -public access to a Transparent copy of the Document, and likewise -the network locations given in the Document for previous versions -it was based on. These may be placed in the ``History'' section. -You may omit a network location for a work that was published at -least four years before the Document itself, or if the original -publisher of the version it refers to gives permission. - -@item -In any section entitled ``Acknowledgments'' or ``Dedications'', -preserve the section's title, and preserve in the section all the -substance and tone of each of the contributor acknowledgments -and/or dedications given therein. - -@item -Preserve all the Invariant Sections of the Document, -unaltered in their text and in their titles. Section numbers -or the equivalent are not considered part of the section titles. - -@item -Delete any section entitled ``Endorsements''. Such a section -may not be included in the Modified Version. - -@item -Do not retitle any existing section as ``Endorsements'' -or to conflict in title with any Invariant Section. -@end enumerate - -If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version's license notice. -These titles must be distinct from any other section titles. - -You may add a section entitled ``Endorsements'', provided it contains -nothing but endorsements of your Modified Version by various -parties---for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard. - -You may add a passage of up to five words as a Front-Cover Text, and a -passage of up to 25 words as a Back-Cover Text, to the end of the list -of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or -through arrangements made by) any one entity. If the Document already -includes a cover text for the same cover, previously added by you or -by arrangement made by the same entity you are acting on behalf of, -you may not add another; but you may replace the old one, on explicit -permission from the previous publisher that added the old one. - -The author(s) and publisher(s) of the Document do not by this License -give permission to use their names for publicity for or to assert or -imply endorsement of any Modified Version. - -@item -COMBINING DOCUMENTS - -You may combine the Document with other documents released under this -License, under the terms defined in section 4 above for modified -versions, provided that you include in the combination all of the -Invariant Sections of all of the original documents, unmodified, and -list them all as Invariant Sections of your combined work in its -license notice. - -The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name but -different contents, make the title of each such section unique by -adding at the end of it, in parentheses, the name of the original -author or publisher of that section if known, or else a unique number. -Make the same adjustment to the section titles in the list of -Invariant Sections in the license notice of the combined work. - -In the combination, you must combine any sections entitled ``History'' -in the various original documents, forming one section entitled -``History''; likewise combine any sections entitled ``Acknowledgments'', -and any sections entitled ``Dedications''. You must delete all sections -entitled ``Endorsements.'' - -@item -COLLECTIONS OF DOCUMENTS - -You may make a collection consisting of the Document and other documents -released under this License, and replace the individual copies of this -License in the various documents with a single copy that is included in -the collection, provided that you follow the rules of this License for -verbatim copying of each of the documents in all other respects. - -You may extract a single document from such a collection, and distribute -it individually under this License, provided you insert a copy of this -License into the extracted document, and follow this License in all -other respects regarding verbatim copying of that document. - -@item -AGGREGATION WITH INDEPENDENT WORKS - -A compilation of the Document or its derivatives with other separate -and independent documents or works, in or on a volume of a storage or -distribution medium, does not as a whole count as a Modified Version -of the Document, provided no compilation copyright is claimed for the -compilation. Such a compilation is called an ``aggregate'', and this -License does not apply to the other self-contained works thus compiled -with the Document, on account of their being thus compiled, if they -are not themselves derivative works of the Document. - -If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one quarter -of the entire aggregate, the Document's Cover Texts may be placed on -covers that surround only the Document within the aggregate. -Otherwise they must appear on covers around the whole aggregate. - -@item -TRANSLATION - -Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of section 4. -Replacing Invariant Sections with translations requires special -permission from their copyright holders, but you may include -translations of some or all Invariant Sections in addition to the -original versions of these Invariant Sections. You may include a -translation of this License provided that you also include the -original English version of this License. In case of a disagreement -between the translation and the original English version of this -License, the original English version will prevail. - -@item -TERMINATION - -You may not copy, modify, sublicense, or distribute the Document except -as expressly provided for under this License. Any other attempt to -copy, modify, sublicense or distribute the Document is void, and will -automatically terminate your rights under this License. However, -parties who have received copies, or rights, from you under this -License will not have their licenses terminated so long as such -parties remain in full compliance. - -@item -FUTURE REVISIONS OF THIS LICENSE - -The Free Software Foundation may publish new, revised versions -of the GNU Free Documentation License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. See -@uref{http://www.gnu.org/copyleft/}. - -Each version of the License is given a distinguishing version number. -If the Document specifies that a particular numbered version of this -License ``or any later version'' applies to it, you have the option of -following the terms and conditions either of that specified version or -of any later version that has been published (not as a draft) by the -Free Software Foundation. If the Document does not specify a version -number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation. -@end enumerate - -@page -@appendixsubsec ADDENDUM: How to use this License for your documents - -To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and -license notices just after the title page: - -@smallexample -@group - Copyright (C) @var{year} @var{your name}. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.1 - or any later version published by the Free Software Foundation; - with the Invariant Sections being @var{list their titles}, with the - Front-Cover Texts being @var{list}, and with the Back-Cover Texts being @var{list}. - A copy of the license is included in the section entitled ``GNU - Free Documentation License''. -@end group -@end smallexample - -If you have no Invariant Sections, write ``with no Invariant Sections'' -instead of saying which ones are invariant. If you have no -Front-Cover Texts, write ``no Front-Cover Texts'' instead of -``Front-Cover Texts being @var{list}''; likewise for Back-Cover Texts. - -If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, -to permit their use in free software. - -@c Local Variables: -@c ispell-local-pdict: "ispell-dict" -@c End: diff --git a/doc/gnupg.texi b/doc/gnupg.texi deleted file mode 100644 index 58c995b38..000000000 --- a/doc/gnupg.texi +++ /dev/null @@ -1,174 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename gnupg.info - -@include version.texi - -@macro copyrightnotice -Copyright @copyright{} 2002 Free Software Foundation, Inc. -@end macro -@macro permissionnotice -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.1 or -any later version published by the Free Software Foundation; with the -Invariant Sections being ``GNU General Public License'', the Front-Cover -texts being (a) (see below), and with the Back-Cover Texts being (b) -(see below). A copy of the license is included in the section entitled -``GNU Free Documentation License''. - -(a) The FSF's Front-Cover Text is: - - A GNU Manual - -(b) The FSF's Back-Cover Text is: - - You have freedom to copy and modify this GNU Manual, like GNU - software. Copies published by the Free Software Foundation raise - funds for GNU development. -@end macro - - -@settitle Using the GNU Privacy Guard - -@c Create a separate index for command line options. -@defcodeindex op -@c Merge the standard indexes into a single one. -@syncodeindex fn cp -@syncodeindex vr cp -@syncodeindex ky cp -@syncodeindex pg cp -@syncodeindex tp cp - -@c printing stuff taken from gcc. -@macro gnupgtabopt{body} -@code{\body\} -@end macro -@macro gnupgoptlist{body} -@smallexample -\body\ -@end smallexample -@end macro -@c Makeinfo handles the above macro OK, TeX needs manual line breaks; -@c they get lost at some point in handling the macro. But if @macro is -@c used here rather than @alias, it produces double line breaks. -@iftex -@alias gol = * -@end iftex -@ifnottex -@macro gol -@end macro -@end ifnottex - - -@c Change the font used for @def... commands, since the default -@c proportional one used is bad for names starting __. -@tex -\global\setfont\defbf\ttbshape{10}{\magstep1} -@end tex - -@c %**end of header - -@ifnottex -@dircategory GNU Utilities -@direntry -* gpg: (gnupg). OpenPGP encryption and signing tool. -* gpgsm: (gnupg). S/MIME encryption and signing tool. -@end direntry -This file documents the use and the internals of the GNU Privacy Guard. - -This is Edition @value{EDITION}, last updated @value{UPDATED}, of -@cite{The `GNU Privacy Guard' Manual}, for Version @value{VERSION}. -@sp 1 -Published by the Free Software Foundation@* -59 Temple Place - Suite 330@* -Boston, MA 02111-1307 USA -@sp 1 -@copyrightnotice{} -@sp 1 -@permissionnotice{} -@end ifnottex - -@setchapternewpage odd - -@titlepage -@title Using the GNU Privacy Guard -@subtitle Version @value{VERSION} -@subtitle @value{UPDATED} -@author Werner Koch @code{(wk@@gnupg.org)} - -@page -@vskip 0pt plus 1filll -@copyrightnotice{} -@sp 2 -@permissionnotice{} -@end titlepage -@summarycontents -@contents -@page - - -@node Top -@top Introduction -@cindex introduction - -This manual documents how to use the GNU Privay Guard system as well as -the administration and the architecture. - -@c * Gpg:: Using the OpenPGP protocol. -@menu -* Invoking GPGSM:: Using the S/MIME protocol. -* Invoking GPG-AGENT:: How to launch the secret key daemon. -* Invoking SCDAEMON:: How to handle Smartcards. - -Developer information - -* Assuan:: Description of the Assuan protocol. - -Miscellaneous - -* Debugging:: How to solve problems -* Copying:: GNU General Public License says - how you can copy and share GnuPG -* GNU Free Documentation License:: How you can copy and share this manual. -* Contributors:: People who have contributed to GnuPG. - -Indices - -* Option Index:: Index to command line options. -* Index:: Index of concepts and symbol names. -@end menu - -@include gpgsm.texi -@include gpg-agent.texi -@include scdaemon.texi - -@include assuan.texi - -@include debugging.texi - -@include gpl.texi -@include fdl.texi - -@include contrib.texi - -@c --------------------------------------------------------------------- -@c Indexes -@c --------------------------------------------------------------------- - -@node Option Index -@unnumbered Option Index - -@printindex op - -@node Index -@unnumbered Index - -@printindex cp - -@c --------------------------------------------------------------------- -@c Epilogue -@c --------------------------------------------------------------------- - -@bye - - diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi deleted file mode 100644 index aad0fbb68..000000000 --- a/doc/gpg-agent.texi +++ /dev/null @@ -1,791 +0,0 @@ -@c Copyright (C) 2002 Free Software Foundation, Inc. -@c This is part of the GnuPG manual. -@c For copying conditions, see the file gnupg.texi. - -@node Invoking GPG-AGENT -@chapter Invoking GPG-AGENT -@cindex GPG-AGENT command options -@cindex command options -@cindex options, GPG-AGENT command - -@c man begin DESCRIPTION - -@sc{gpg-agent} is a daemon to manage secret (private) keys independelty -from any protocol. It is used as a backend for @sc{gpg} and @sc{gpgsm} -as well as for a couple of other utilities. - -@noindent -The usual way to run the agent is from the @code{~/.xsession} file: - -@example -eval `gpg-agent --daemon` -@end example - -@noindent -If you don't use an X server, you can also put this into your regular -startup file @code{~/.profile} or @code{.bash_profile}. It is best not -to run multiple instance of the gpg-agent, so you should make sure that -only is running: @sc{gpg-agent} uses an environment variable to inform -clients about the communication parameters. You can write the -content of this environment variable to a file so that you can test for -a running agent. This short script may do the job: - -@smallexample -if test -f $HOME/.gpg-agent-info && \ - kill -0 `cut -d: -f 2 $HOME/.gpg-agent-info` 2>/dev/null; then - GPG_AGENT_INFO=`cat $HOME/.gpg-agent-info` - export GPG_AGENT_INFO -else - eval `gpg-agent --daemon` - echo $GPG_AGENT_INFO >$HOME/.gpg-agent-info -fi -@end smallexample - -@noindent -If you want to use a curses based pinentry (which is usually also the -fallback mode for a GUI based pinentry), you should add these lines to -your @code{.bashrc} or whatever initialization file is used for all shell -invocations: - -@smallexample -GPG_TTY=`tty` -export GPG_TTY -@end smallexample - -It is important that this environment variable always reflects the -output of the @code{tty} command. - -@c man end - -@noindent -@xref{Option Index}, for an index to GPG-AGENTS's commands and options. - -@menu -* Agent Commands:: List of all commands. -* Agent Options:: List of all options. -* Agent Signals:: Use of some signals. -* Agent Examples:: Some usage examples. -* Agent Protocol:: The protocol the agent uses. -@end menu - -@c man begin COMMANDS - -@node Agent Commands -@section Commands - -Commands are not distinguished from options execpt for the fact that -only one one command is allowed. - -@table @gnupgtabopt -@item --version -@opindex version -Print the program version and licensing information. Not that you can -abbreviate this command. - -@item --help, -h -@opindex help -Print a usage message summarizing the most usefule command-line options. -Not that you can abbreviate this command. - -@item --dump-options -@opindex dump-options -Print a list of all available options and commands. Not that you can -abbreviate this command. - -@item --server -@opindex server -Run in server mode and wait for commands on the @code{stdin}. The -default mode is to create a socket and listen for commands there. - -@item --daemon -@opindex daemon -Run the program in the background. This option is required to prevent -it from being accidently running in the background. A common way to do -this is: -@example -@end example -$ eval `gpg-agent --daemon` -@end table - - -@c man begin OPTIONS - -@node Agent Options -@section Option Summary - -@table @gnupgtabopt - -@item --options @var{file} -@opindex options -Reads configuration from @var{file} instead of from the default -per-user configuration file. The default configuration file is named -@file{gpg-agent.conf} and expected in the @file{.gnupg} directory directly -below the home directory of the user. - -@item -v -@item --verbose -@opindex v -@opindex verbose -Outputs additional information while running. -You can increase the verbosity by giving several -verbose commands to @sc{gpgsm}, such as @samp{-vv}. - -@item -q -@item --quiet -@opindex q -@opindex quiet -Try to be as quiet as possible. - -@item --batch -@opindex batch -Don't invoke a pinentry or do any other thing requiring human interaction. - -@item --faked-system-time @var{epoch} -@opindex faked-system-time -This option is only useful for testing; it sets the system time back or -forth to @var{epoch} which is the number of seconds elapsed since the year -1970. - -@item --debug-level @var{level} -@opindex debug-level -Select the debug level for investigating problems. @var{level} may be -one of: - - @table @code - @item none - no debugging at all. - @item basic - some basic debug messages - @item advanced - more verbose debug messages - @item expert - even more detailed messages - @item guru - all of the debug messages you can get - @end table - -How these messages are mapped to the actual debugging flags is not -specified and may change with newer releaes of this program. They are -however carefully selected to best aid in debugging. - -@item --debug @var{flags} -@opindex debug -This option is only useful for debugging and the behaviour may change at -any time without notice. FLAGS are bit encoded and may be given in -usual C-Syntax. The currently defined bits are: - - @table @code - @item 0 (1) - X.509 or OpenPGP protocol related data - @item 1 (2) - values of big number integers - @item 2 (4) - low level crypto operations - @item 5 (32) - memory allocation - @item 6 (64) - caching - @item 7 (128) - show memory statistics. - @item 9 (512) - write hashed data to files named @code{dbgmd-000*} - @item 10 (1024) - trace Assuan protocol - @item 12 (4096) - bypass all certificate validation - @end table - -@item --debug-all -@opindex debug-all -Same as @code{--debug=0xffffffff} - -@item --debug-wait @var{n} -@opindex debug-wait -When running in server mode, wait @var{n} seconds before entering the -actual processing loop and print the pid. This gives time to attach a -debugger. - -@item --no-detach -@opindex no-detach -Don't detach the process from the console. This is manly usefule for -debugging. - -@item -s -@itemx --sh -@itemx -c -@itemx --csh -@opindex s -@opindex sh -@opindex c -@opindex csh -Format the info output in daemon mode for use with the standard Bourne -shell respective the C-shell . The default ist to guess it based on the -environment variable @code{SHELL} which is in almost all cases -sufficient. - -@item --no-grab -@opindex no-grab -Tell the pinentryo not to grab the keyboard and mouse. This option -should in general not be used to avaoid X-sniffing attacks. - -@item --log-file @var{file} -@opindex log-file -Append all logging output to @var{file}. This is very helpful in -seeing what the agent actually does. - -@item --disable-pth -@opindex disable-pth -Don't allow multiple connections. This option is in general not very -useful. - -@item --allow-mark-trusted -@opindex allow-mark-trusted -Allow clients to mark keys as trusted, i.e. put them into the -@code{trustlist.txt} file. This is by default not allowed to make it -harder for users to inadvertly accept Root-CA keys. - -@item --ignore-cache-for-signing -@opindex ignore-cache-for-signing -This option will let gpg-agent bypass the passphrase cache for all -signing operation. Note that there is also a per-session option to -control this behaviour but this command line option takes precedence. - -@item --default-cache-ttl @var{n} -@opindex default-cache-ttl -Set the time a cache entry is valid to @var{n} seconds. The default are -600 seconds. - -@item --pinentry-program @var{filename} -@opindex pinentry-program -Use program @var{filename} as the PIN entry. The default is installation -dependend and can be shown with the @code{--version} command. - -@item --scdaemon-program @var{filename} -@opindex scdaemon-program -Use program @var{filename} as the Smartcard daemon. The default is -installation dependend and can be shown with the @code{--version} -command. - - -@item --display @var{string} -@itemx --ttyname @var{string} -@itemx --ttytype @var{string} -@itemx --lc-type @var{string} -@itemx --lc-messages @var{string} -@opindex display -@opindex ttyname -@opindex ttytype -@opindex lc-type -@opindex lc-messa -These options are used with the server mode to pass localization -information. - -@item --keep-tty -@itemx --keep-display -@opindex keep-tty -@opindex keep-display -Ignore requests to change change the current @sc{tty} respective the X -window system's @code{DISPLAY} variable. This is useful to lock the -pinentry to pop up at the @sc{tty} or display you started the agent. - - -@end table - -All the long options may also be given in the configuration file after -stripping off the two leading dashes. - -@c -@c Agent Signals -@c -@node Agent Signals -@section Use of some signals. -A running @command{gpg-agent} may be controlled by signals, i.e. using -the @command{kill} command to send a signal to the process. - -Here is a list of supported signals: - -@table @gnupgtabopt - -@item SIGHUP -@cpindex SIGHUP -This signals flushes all chached passphrases and when the program was -started with a configuration file, the configuration file is read again. -Only certain options are honored: @code{quiet}, @code{verbose}, -@code{debug}, @code{debug-all}, @code{no-grab}, @code{pinentry-program}, -@code{default-cache-ttl} and @code{ignore-cache-for-signing}. -@code{scdaemon-program} is also supported but due to the current -implementation, which calls the scdaemon only once, it is not of much -use. - - -@item SIGTERM -@cpindex SIGTERM -Shuts down the process but waits until all current requests are -fulfilled. If the process has received 3 of these signals and requests -are still pending, a shutdown is forced. - -@item SIGINT -@cpindex SIGINT -Shuts down the process immediately. - - -@item SIGUSR1 -@itemx SIGUSR2 -@cpindex SIGUSR1 -@cpindex SIGUSR2 -These signals are used for internal purposes. - -@end table - -@c -@c Examples -@c -@node Agent Examples -@section Examples - -@c man begin EXAMPLES - -@example -$ eval `gpg-agent --daemon` -@end example - -@c man end - - -@c -@c Assuan Protocol -@c -@node Agent Protocol -@section Agent's Assuan Protocol - -The gpg-agent should be started by the login shell and set an -environment variable to tell clients about the socket to be used. -Clients should deny to access an agent with a socket name which does -not match its own configuration. An application may choose to start -an instance of the gpgagent if it does not figure that any has been -started; it should not do this if a gpgagent is running but not -usable. Because gpg-agent can only be used in background mode, no -special command line option is required to activate the use of the -protocol. - -To identify a key we use a thing called keygrip which is the SHA-1 hash -of an canoncical encoded S-Expression of the the public key as used in -Libgcrypt. For the purpose of this interface the keygrip is given as a -hex string. The advantage of using this and not the hash of a -certificate is that it will be possible to use the same keypair for -different protocols, thereby saving space on the token used to keep the -secret keys. - -@menu -* Agent PKDECRYPT:: Decrypting a session key -* Agent PKSIGN:: Signing a Hash -* Agent GENKEY:: Generating a Key -* Agent IMPORT:: Importing a Secret Key -* Agent EXPORT:: Exporting a Secret Key -* Agent ISTRUSTED:: Importing a Root Certificate -* Agent GET_PASSPHRASE:: Ask for a passphrase -* Agent GET_CONFIRMATION:: Ask for confirmation -* Agent HAVEKEY:: Check whether a key is available -* Agent LEARN:: Register a smartcard -* Agent PASSWD:: Change a Passphrase -@end menu - -@node Agent PKDECRYPT -@subsection Decrypting a session key - -The client asks the server to decrypt a session key. The encrypted -session key should have all information needed to select the -appropriate secret key or to delegate it to a smartcard. - -@example - SETKEY -@end example - -Tell the server about the key to be used for decryption. If this is -not used, gpg-agent may try to figure out the key by trying to -decrypt the message with each key available. - -@example - PKDECRYPT -@end example - -The agent checks whether this command is allowed and then does an -INQUIRY to get the ciphertext the client should then send the cipher -text. - -@example - S: INQUIRE CIPHERTEXT - C: D (xxxxxx - C: D xxxx) - C: END -@end example - -Please note that the server may send status info lines while reading the -data lines from the client. The data send is a SPKI like S-Exp with -this structure: - -@example - (enc-val - ( - ( ) - ... - ( ))) -@end example - -Where algo is a string with the name of the algorithm; see the libgcrypt -documentation for a list of valid algorithms. The number and names of -the parameters depend on the algorithm. The agent does return an error -if there is an inconsistency. - -If the decryption was successful the decrypted data is returned by -means of "D" lines. - -Here is an example session: - -@example - C: PKDECRYPT - S: INQUIRE CIPHERTEXT - C: D (enc-val elg (a 349324324) - C: D (b 3F444677CA))) - C: END - S: # session key follows - S: D 1234567890ABCDEF0 - S: OK descryption successful -@end example - - -@node Agent PKSIGN -@subsection Signing a Hash - -The client ask the agent to sign a given hash value. A default key -will be chosen if no key has been set. To set a key a client first -uses: - -@example - SIGKEY -@end example - -This can be used multiple times to create multiple signature, the list -of keys is reset with the next PKSIGN command or a RESET. The server -test whether the key is a valid key to sign something and responds with -okay. - -@example - SETHASH -@end example - -The client can use this command to tell the server about the data -(which usually is a hash) to be signed. - -The actual signing is done using - -@example - PKSIGN -@end example - -Options are not yet defined, but my later be used to choosen among -different algorithms (e.g. pkcs 1.5) - -The agent does then some checks, asks for the passphrase and -if SETHASH has not been used asks the client for the data to sign: - -@example - S: INQUIRE HASHVAL - C: D ABCDEF012345678901234 - C: END -@end example - -As a result the server returns the signature as an SPKI like S-Exp -in "D" lines: - -@example - (sig-val - ( - ( ) - ... - ( ))) -@end example - - -The operation is affected by the option - -@example - OPTION use-cache-for-signing=0|1 -@end example - -The default of @code{1} uses the cache. Setting this option to @code{0} -will lead gpg-agent to ignore the passphrase cache. Note, that there is -also a global command line option for gpg-agent to globally disable the -caching. - - -Here is an example session: - -@example - C: SIGKEY - S: OK key available - C: SIGKEY - S: OK key available - C: PKSIGN - S: # I did ask the user whether he really wants to sign - S: # I did ask the user for the passphrase - S: INQUIRE HASHVAL - C: D ABCDEF012345678901234 - C: END - S: # signature follows - S: D (sig-val rsa (s 45435453654612121212)) - S: OK -@end example - - -@node Agent GENKEY -@subsection Generating a Key - -This is used to create a new keypair and store the secret key inside the -active PSE -w which is in most cases a Soft-PSE. An not yet defined -option allows to choose the storage location. To get the secret key out -of the PSE, a special export tool has to be used. - -@example - GENKEY -@end example - -Invokes the key generation process and the server will then inquire -on the generation parameters, like: - -@example - S: INQUIRE KEYPARM - C: D (genkey (rsa (nbits 1024))) - C: END -@end example - -The format of the key parameters which depends on the algorithm is of -the form: - -@example - (genkey - (algo - (parameter_name_1 ....) - .... - (parameter_name_n ....))) -@end example - -If everything succeeds, the server returns the *public key* in a SPKI -like S-Expression like this: - -@example - (public-key - (rsa - (n ) - (e ))) -@end example - -Here is an example session: - -@example - C: GENKEY - S: INQUIRE KEYPARM - C: D (genkey (rsa (nbits 1024))) - C: END - S: D (public-key - S: D (rsa (n 326487324683264) (e 10001))) - S OK key created -@end example - -@node Agent IMPORT -@subsection Importing a Secret Key - -This operation is not yet supportted by GpgAgent. Specialized tools -are to be used for this. - -There is no actual need because we can expect that secret keys -created by a 3rd party are stored on a smartcard. If we have -generated the key ourself, we do not need to import it. - -@node Agent EXPORT -@subsection Export a Secret Key - -Not implemented. - -Should be done by an extra tool. - -@node Agent ISTRUSTED -@subsection Importing a Root Certificate - -Actually we do not import a Root Cert but provide a way to validate -any piece of data by storing its Hash along with a description and -an identifier in the PSE. Here is the interface desription: - -@example - ISTRUSTED -@end example - -Check whether the OpenPGP primary key or the X.509 certificate with the -given fingerprint is an ultimately trusted key or a trusted Root CA -certificate. The fingerprint should be given as a hexstring (without -any blanks or colons or whatever in between) and may be left padded with -00 in case of an MD5 fingerprint. GPGAgent will answer with: - -@example - OK -@end example - -The key is in the table of trusted keys. - -@example - ERR 304 (Not Trusted) -@end example - -The key is not in this table. - -Gpg needs the entire list of trusted keys to maintain the web of -trust; the following command is therefore quite helpful: - -@example - LISTTRUSTED -@end example - -GpgAgent returns a list of trusted keys line by line: - -@example - S: D 000000001234454556565656677878AF2F1ECCFF P - S: D 340387563485634856435645634856438576457A P - S: D FEDC6532453745367FD83474357495743757435D S - S: OK -@end example - -The first item on a line is the hexified fingerprint where MD5 -ingerprints are @code{00} padded to the left and the second item is a -flag to indicate the type of key (so that gpg is able to only take care -of PGP keys). P = OpenPGP, S = S/MIME. A client should ignore the rest -of the line, so that we can extend the format in the future. - -Finally a client should be able to mark a key as trusted: - -@example - MARKTRUSTED @var{fingerprint} "P"|"S" -@end example - -The server will then pop up a window to ask the user whether she -really trusts this key. For this it will probably ask for a text to -be displayed like this: - -@example - S: INQUIRE TRUSTDESC - C: D Do you trust the key with the fingerprint @@FPR@@ - C: D bla fasel blurb. - C: END - S: OK -@end example - -Known sequences with the pattern @@foo@@ are replaced according to this -table: - -@table @code -@item @@FPR16@@ -Format the fingerprint according to gpg rules for a v3 keys. -@item @@FPR20@@ -Format the fingerprint according to gpg rules for a v4 keys. -@item @@FPR@@ -Choose an appropriate format to format the fingerprint. -@item @@@@ -Replaced by a single @code{@@} -@end table - -@node Agent GET_PASSPHRASE -@subsection Ask for a passphrase - -This function is usually used to ask for a passphrase to be used for -conventional encryption, but may also be used by programs which need -special handling of passphrases. This command uses a syntax which helps -clients to use the agent with minimum effort. - -@example - GET_PASSPHRASE @var{cache_id} [@var{error_message} @var{prompt} @var{description}] -@end example - -@var{cache_id} is expected to be a hex string used for caching a -passphrase. Use a @code{X} to bypass the cache. With no other -arguments the agent returns a cached passphrase or an error. - -@var{error_message} is either a single @code{X} for no error message or -a string to be shown as an error message like (e.g. "invalid -passphrase"). Blanks must be percent escaped or replaced by @code{+}'. - -@var{prompt} is either a single @code{X} for a default prompt or the -text to be shown as the prompt. Blanks must be percent escaped or -replaced by @code{+}. - -@var{description} is a text shown above the entry field. Blanks must be -percent escaped or replaced by @code{+}. - -The agent either returns with an error or with a OK followed by the -hex encoded passphrase. Note that the length of the strings is -implicitly limited by the maximum length of a command. - -@example - CLEAR_PASSPHRASE @var{cache_id} -@end example - -may be used to invalidate the cache entry for a passphrase. The -function returns with OK even when there is no cached passphrase. - - -@node Agent GET_CONFIRMATION -@subsection Ask for confirmation - -This command may be used to ask for a simple confirmation by -presenting a text and 2 bottonts: Okay and Cancel. - -@example - GET_CONFIRMATION @var{description} -@end example - -@var{description}is displayed along with a Okay and Cancel -button. Blanks must be percent escaped or replaced by @code{+}. A -@code{X} may be used to display confirmation dialog with a default -text. - -The agent either returns with an error or with a OK. Note, that the -length of @var{description} is implicitly limited by the maximum -length of a command. - - - -@node Agent HAVEKEY -@subsection Check whether a key is available - -This can be used to see whether a secret key is available. It does -not return any information on whether the key is somehow protected. - -@example - HAVEKEY @var{keygrip} -@end example - -The Agent answers either with OK or @code{No_Secret_Key} (208). The -caller may want to check for other error codes as well. - - -@node Agent LEARN -@subsection Register a smartcard - -@example - LEARN [--send] -@end example - -This command is used to register a smartcard. With the --send -option given the certificates are send back. - - -@node Agent PASSWD -@subsection Change a Passphrase - -@example - PASSWD @var{keygrip} -@end example - -This command is used to interactively change the passphrase of the key -indentified by the hex string @var{keygrip}. - - - diff --git a/doc/gpg.texi b/doc/gpg.texi deleted file mode 100644 index 4ed4f1f76..000000000 --- a/doc/gpg.texi +++ /dev/null @@ -1,1806 +0,0 @@ -\input texinfo -@c This Texinfo document has been automatically generated by -@c docbook2texi from a DocBook documentation. The tool used -@c can be found at: -@c -@c Please send any bug reports, improvements, comments, -@c patches, etc. to Steve Cheng . - -@setfilename gpg.info -@dircategory GnuPG -@direntry -* gpg: (gpg). GnuPG encryption and signing tool. -@end direntry - -@node top -@top gpg -@menu -@end menu - -@majorheading Name -gpg ---- encryption and signing tool - -@majorheading Synopsis - -@majorheading DESCRIPTION -@code{gpg} is the main program for the GnuPG system. - -This man page only lists the commands and options available. -For more verbose documentation get the GNU Privacy Handbook (GPH) or -one of the other documents at http://www.gnupg.org/docs.html . - -Please remember that option parsing stops as soon as a non option is -encountered, you can explicitly stop option parsing by using the -special option "---". - -@majorheading COMMANDS -@code{gpg} recognizes these commands: - -@table @asis -@item -s, ---sign -Make a signature. This command may be combined -with ---encrypt. - -@item ---clearsign -Make a clear text signature. - -@item -b, ---detach-sign -Make a detached signature. - -@item -e, ---encrypt -Encrypt data. This option may be combined with ---sign. - -@item -c, ---symmetric -Encrypt with a symmetric cipher using a passphrase. The default -symmetric cipher used is CAST5, but may be chosen with the ----cipher-algo option. - -@item ---store -Store only (make a simple RFC1991 packet). - -@item ---decrypt @code{file} -Decrypt @code{file} (or stdin if no file is specified) and -write it to stdout (or the file specified with ----output). If the decrypted file is signed, the -signature is also verified. This command differs -from the default operation, as it never writes to the -filename which is included in the file and it -rejects files which don't begin with an encrypted -message. - -@item ---verify @code{sigfile} @code{signed-files} -Assume that @code{sigfile} is a signature and verify it -without generating any output. With no arguments, -the signature packet is read from stdin. 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 -".sig" or ".asc" extension. -With more than -1 argument, the first should be a detached signature -and the remaining files are the signed stuff. To read the signed -stuff from stdin, use @samp{-} as the second filename. -For security reasons a detached signature cannot read the signed -material from stdin without denoting it in the above way. - -@item ---verify-files @code{files} -This is a special version of the ---verify command which does not work with -detached signatures. The command expects the files to be verified either -on the command line or reads the filenames from stdin; each name must be on -separate line. The command is intended for quick checking of many files. - -@item ---encrypt-files @code{files} -This is a special version of the ---encrypt command. The command expects -the files to be encrypted either on the command line or reads the filenames -from stdin; each name must be on separate line. The command is intended -for a quick encryption of multiple files. - -@item ---decrypt-files @code{files} -The same as ---encrypt-files with the difference that files will be -decrypted. The syntax or the filenames is the same. - -@item ---list-keys @code{names} -@itemx ---list-public-keys @code{names} -List all keys from the public keyrings, or just the ones given on the -command line. - -Avoid using the output of this command in scripts or other programs as -it is likely to change as GnuPG changes. See ---with-colons for a -machine-parseable key listing command that is appropriate for use in -scripts and other programs. - -@item ---list-secret-keys @code{names} -List all keys from the secret keyrings, or just the ones given on the -command line. A '#' after the letters 'sec' means that the secret key -is not usable (for example, if it was created via ----export-secret-subkeys). - -@item ---list-sigs @code{names} -Same as ---list-keys, but the signatures are listed too. - -For each signature listed, there are several flags in between the -"sig" tag and keyid. These flags give additional information about -each signature. From left to right, they are the numbers 1-3 for -certificate check level (see ---default-cert-check-level), "L" for a -local or non-exportable signature (see ---lsign-key), "R" for a -nonRevocable signature (see ---nrsign-key), "P" for a signature that -contains a policy URL (see ---cert-policy-url), "N" for a signature -that contains a notation (see ---cert-notation), "X" for an eXpired -signature (see ---ask-cert-expire), and the numbers 1-9 or "T" for 10 -and above to indicate trust signature levels (see the ---edit-key -command "tsign"). - -@item ---check-sigs @code{names} -Same as ---list-sigs, but the signatures are verified. - -@item ---fingerprint @code{names} -List all keys with their fingerprints. This is the -same output as ---list-keys but with the additional output -of a line with the fingerprint. May also be combined -with ---list-sigs or --check-sigs. -If this command is given twice, the fingerprints of all -secondary keys are listed too. - -@item ---list-packets -List only the sequence of packets. This is mainly -useful for debugging. - -@item ---gen-key -Generate a new key pair. This command is normally only used -interactively. - -There is an experimental feature which allows you to create keys -in batch mode. See the file @file{doc/DETAILS} -in the source distribution on how to use this. - -@item ---edit-key @code{name} -Present a menu which enables you to do all key -related tasks: - -@table @asis -@item sign -Make a signature on key of user @code{name} -If the key is not yet signed by the default -user (or the users given with -u), the -program displays the information of the key -again, together with its fingerprint and -asks whether it should be signed. This -question is repeated for all users specified -with -u. - -@item lsign -Same as ---sign but the signature is marked as -non-exportable and will therefore never be used -by others. This may be used to make keys valid -only in the local environment. - -@item nrsign -Same as ---sign but the signature is marked as non-revocable and can -therefore never be revoked. - -@item nrlsign -Combines the functionality of nrsign and lsign to make a signature -that is both non-revocable and -non-exportable. - -@item tsign -Make a trust signature. This is a signature that combines the notions -of certification (like a regular signature), and trust (like the -"trust" command). It is generally only useful in distinct communities -or groups. - -@item revsig -Revoke a signature. For every signature which has been generated by -one of the secret keys, GnuPG asks whether a revocation certificate -should be generated. - -@item trust -Change the owner trust value. This updates the -trust-db immediately and no save is required. - -@item disable -@itemx enable -Disable or enable an entire key. A disabled key can not normally be -used for encryption. - -@item adduid -Create an alternate user id. - -@item addphoto -Create a photographic user id. This will prompt for a JPEG file that -will be embedded into the user ID. A very large JPEG will make for a -very large key. - -@item deluid -Delete a user id. - -@item revuid -Revoke a user id. - -@item addkey -Add a subkey to this key. - -@item delkey -Remove a subkey. - -@item addrevoker -Add a designated revoker. This takes one optional argument: -"sensitive". If a designated revoker is marked as sensitive, it will -not be exported by default (see -export-options). - -@item revkey -Revoke a subkey. - -@item expire -Change the key expiration time. If a subkey is selected, the -expiration time of this subkey will be changed. With no selection, -the key expiration of the primary key is changed. - -@item passwd -Change the passphrase of the secret key. - -@item primary -Flag the current user id as the primary one, removes the primary user -id flag from all other user ids and sets the timestamp of all affected -self-signatures one second ahead. Note that setting a photo user ID -as primary makes it primary over other photo user IDs, and setting a -regular user ID as primary makes it primary over other regular user -IDs. - -@item uid @code{n} -Toggle selection of user id with index @code{n}. -Use 0 to deselect all. - -@item key @code{n} -Toggle selection of subkey with index @code{n}. -Use 0 to deselect all. - -@item check -Check all selected user ids. - -@item showphoto -Display the selected photographic user -id. - -@item pref -List preferences from the selected user ID. This shows the actual -preferences, without including any implied preferences. - -@item showpref -More verbose preferences listing for the selected user ID. This shows -the preferences in effect by including the implied preferences of -3DES (cipher), SHA-1 (digest), and Uncompressed (compression) if they -are not already included in the preference list. - -@item setpref @code{string} -Set the list of user ID preferences to @code{string}, this should be a -string similar to the one printed by "pref". Using an empty string -will set the default preference string, using "none" will set the -preferences to nil. Use "gpg ---version" to get a list of available -algorithms. This command just initializes an internal list and does -not change anything unless another command (such as "updpref") which -changes the self-signatures is used. - -@item updpref -Change the preferences of all user IDs (or just of the selected ones -to the current list of preferences. The timestamp of all affected -self-signatures will be advanced by one second. Note that while you -can change the preferences on an attribute user ID (aka "photo ID"), -GnuPG does not select keys via attribute user IDs so these preferences -will not be used by GnuPG. - -@item toggle -Toggle between public and secret key listing. - -@item save -Save all changes to the key rings and quit. - -@item quit -Quit the program without updating the -key rings. - -@end table - -The listing shows you the key with its secondary -keys and all user ids. Selected keys or user ids -are indicated by an asterisk. The trust value is -displayed with the primary key: the first is the -assigned owner trust and the second is the calculated -trust value. Letters are used for the values: - -@table @asis -@item - -No ownertrust assigned / not yet calculated. - -@item e -Trust -calculation has failed; probably due to an expired key. - -@item q -Not enough information for calculation. - -@item n -Never trust this key. - -@item m -Marginally trusted. - -@item f -Fully trusted. - -@item u -Ultimately trusted. - -@end table - -@item ---sign-key @code{name} -Signs a public key with your secret key. This is a shortcut version of -the subcommand "sign" from ---edit. - -@item ---lsign-key @code{name} -Signs a public key with your secret key but marks it as -non-exportable. This is a shortcut version of the subcommand "lsign" -from ---edit. - -@item ---nrsign-key @code{name} -Signs a public key with your secret key but marks it as non-revocable. -This is a shortcut version of the subcommand "nrsign" from ---edit. - -@item ---delete-key @code{name} -Remove key from the public keyring. In batch mode either ---yes is -required or the key must be specified by fingerprint. This is a -safeguard against accidental deletion of multiple keys. - -@item ---delete-secret-key @code{name} -Remove key from the secret and public keyring. In batch mode the key -must be specified by fingerprint. - -@item ---delete-secret-and-public-key @code{name} -Same as ---delete-key, but if a secret key exists, it will be removed -first. In batch mode the key must be specified by fingerprint. - -@item ---gen-revoke -Generate a revocation certificate for the complete key. To revoke -a subkey or a signature, use the ---edit command. - -@item ---desig-revoke -Generate a designated revocation certificate for a key. This allows a -user (with the permission of the keyholder) to revoke someone else's -key. - -@item ---export @code{names} -Either export all keys from all keyrings (default -keyrings and those registered via option ---keyring), -or if at least one name is given, those of the given -name. The new keyring is written to stdout or to -the file given with option "output". Use together -with ---armor to mail those keys. - -@item ---send-keys @code{names} -Same as ---export but sends the keys to a keyserver. -Option ---keyserver must be used to give the name -of this keyserver. Don't send your complete keyring -to a keyserver - select only those keys which are new -or changed by you. - -@item ---export-all @code{names} -Same as ---export, but also exports keys which -are not compatible with OpenPGP. - -@item ---export-secret-keys @code{names} -@itemx ---export-secret-subkeys @code{names} -Same as ---export, but exports the secret keys instead. -This is normally not very useful and a security risk. -The second form of the command has the special property to -render the secret part of the primary key useless; this is -a GNU extension to OpenPGP and other implementations can -not be expected to successfully import such a key. -See the option ---simple-sk-checksum if you want to import such an -exported key with an older OpenPGP implementation. - -@item ---import @code{files} -@itemx ---fast-import @code{files} -Import/merge keys. This adds the given keys to the -keyring. The fast version is currently just a synonym. - -There are a few other options which control how this command works. -Most notable here is the ---merge-only option which does not insert new keys -but does only the merging of new signatures, user-IDs and subkeys. - -@item ---recv-keys @code{key IDs} -Import the keys with the given key IDs from a keyserver. Option ----keyserver must be used to give the name of this keyserver. - -@item ---refresh-keys @code{key IDs} -Request updates from a keyserver for keys that already exist on the -local keyring. This is useful for updating a key with the latest -signatures, user IDs, etc. Option ---keyserver must be used to give -the name of this keyserver. - -@item ---search-keys @code{names} -Search the keyserver for the given names. Multiple names given here -will be joined together to create the search string for the keyserver. -Option ---keyserver must be used to give the name of this keyserver. - -@item ---update-trustdb -Do trust database maintenance. This command iterates over all keys -and builds the Web-of-Trust. This is an interactive command because it -may have to ask for the "ownertrust" values for keys. The user has to -give an estimation of how far she trusts the owner of the displayed -key to correctly certify (sign) other keys. GnuPG only asks for the -ownertrust value if it has not yet been assigned to a key. Using the ----edit-key menu, the assigned value can be changed at any time. - -@item ---check-trustdb -Do trust database maintenance without user interaction. From time to -time the trust database must be updated so that expired keys or -signatures and the resulting changes in the Web-of-Trust can be -tracked. Normally, GnuPG will calculate when this is required and do -it automatically unless ---no-auto-check-trustdb is set. This command -can be used to force a trust database check at any time. The -processing is identical to that of ---update-trustdb but it skips keys -with a not yet defined "ownertrust". - -For use with cron jobs, this command can be used together with ---batch -in which case the trust database check is done only if a check is -needed. To force a run even in batch mode add the option ---yes. - -@item ---export-ownertrust -Send the ownertrust values to stdout. This is useful for backup -purposes as these values are the only ones which can't be re-created -from a corrupted trust DB. - -@item ---import-ownertrust @code{files} -Update the trustdb with the ownertrust values stored -in @code{files} (or stdin if not given); existing -values will be overwritten. - -@item ---rebuild-keydb-caches -When updating from version 1.0.6 to 1.0.7 this command should be used -to create signature caches in the keyring. It might be handy in other -situations too. - -@item ---print-md @code{algo} @code{files} -@itemx ---print-mds @code{files} -Print message digest of algorithm ALGO for all given files or stdin. -With the second form (or a deprecated "*" as algo) digests for all -available algorithms are printed. - -@item ---gen-random @code{0|1|2} @code{count} -Emit COUNT random bytes of the given quality level. If count is not given -or zero, an endless sequence of random bytes will be emitted. -PLEASE, don't use this command unless you know what you are doing; it may -remove precious entropy from the system! - -@item ---gen-prime @code{mode} @code{bits} @code{qbits} -Use the source, Luke :-). The output format is still subject to change. - -@item ---version -Print version information along with a list -of supported algorithms. - -@item ---warranty -Print warranty information. - -@item -h, ---help -Print usage information. This is a really long list even though it -doesn't list all options. For every option, consult this manual. - -@end table - -@majorheading OPTIONS -Long options can be put in an options file (default -"~/.gnupg/gpg.conf"). Short option names will not work - for example, -"armor" is a valid option for the options file, while "a" is not. Do -not write the 2 dashes, but simply the name of the option and any -required arguments. Lines with a hash ('#') as the first -non-white-space character are ignored. Commands may be put in this -file too, but that is not generally useful as the command will execute -automatically with every execution of gpg. - -@code{gpg} recognizes these options: - -@table @asis -@item -a, ---armor -Create ASCII armored output. - -@item -o, ---output @code{file} -Write output to @code{file}. - -@item ---mangle-dos-filenames -@itemx ---no-mangle-dos-filenames -Older version of Windows cannot handle filenames with more than one -dot. ---mangle-dos-filenames causes GnuPG to replace (rather than add -to) the extension of an output filename to avoid this problem. This -option is off by default and has no effect on non-Windows platforms. - -@item -u, ---local-user @code{name} -Use @code{name} as the user ID to sign. -This option is silently ignored for the list commands, -so that it can be used in an options file. - -@item ---default-key @code{name} -Use @code{name} as default user ID for signatures. If this -is not used the default user ID is the first user ID -found in the secret keyring. - -@item -r, ---recipient @code{name} -@itemx -Encrypt for user id @code{name}. If this option or ---hidden-recipient -is not specified, GnuPG asks for the user-id unless ----default-recipient is given. - -@item -R, ---hidden-recipient @code{name} -@itemx -Encrypt for user id @code{name}, but hide the keyid of the key. This -option hides the receiver of the message and is a countermeasure -against traffic analysis. If this option or ---recipient is not -specified, GnuPG asks for the user-id unless ---default-recipient is -given. - -@item ---default-recipient @code{name} -Use @code{name} as default recipient if option ---recipient is not used and -don't ask if this is a valid one. @code{name} must be non-empty. - -@item ---default-recipient-self -Use the default key as default recipient if option ---recipient is not used and -don't ask if this is a valid one. The default key is the first one from the -secret keyring or the one set with ---default-key. - -@item ---no-default-recipient -Reset ---default-recipient and --default-recipient-self. - -@item ---encrypt-to @code{name} -Same as ---recipient but this one is intended for use -in the options file and may be used with -your own user-id as an "encrypt-to-self". These keys -are only used when there are other recipients given -either by use of ---recipient or by the asked user id. -No trust checking is performed for these user ids and -even disabled keys can be used. - -@item ---hidden-encrypt-to @code{name} -Same as ---hidden-recipient but this one is intended for use in the -options file and may be used with your own user-id as a hidden -"encrypt-to-self". These keys are only used when there are other -recipients given either by use of ---recipient or by the asked user id. -No trust checking is performed for these user ids and even disabled -keys can be used. - -@item ---no-encrypt-to -Disable the use of all ---encrypt-to and --hidden-encrypt-to keys. - -@item -v, ---verbose -Give more information during processing. If used -twice, the input data is listed in detail. - -@item -q, ---quiet -Try to be as quiet as possible. - -@item -z @code{n}, ---compress @code{n} -Set compression level to @code{n}. A value of 0 for @code{n} -disables compression. Default is to use the default -compression level of zlib (normally 6). - -@item -t, ---textmode -@itemx ---no-textmode -Use canonical text mode. ---no-textmode disables this option. If -t -(but not ---textmode) is used together with armoring and signing, this -enables clearsigned messages. This kludge is needed for command-line -compatibility with command-line versions of PGP; normally you would -use ---sign or --clearsign to select the type of the signature. - -@item -n, ---dry-run -Don't make any changes (this is not completely implemented). - -@item -i, ---interactive -Prompt before overwriting any files. - -@item ---batch -@itemx ---no-batch -Use batch mode. Never ask, do not allow interactive commands. ----no-batch disables this option. - -@item ---no-tty -Make sure that the TTY (terminal) is never used for any output. -This option is needed in some cases because GnuPG sometimes prints -warnings to the TTY if ---batch is used. - -@item ---yes -Assume "yes" on most questions. - -@item ---no -Assume "no" on most questions. - -@item ---default-cert-check-level @code{n} -The default to use for the check level when signing a key. - -0 means you make no particular claim as to how carefully you verified -the key. - -1 means you believe the key is owned by the person who claims to own -it but you could not, or did not verify the key at all. This is -useful for a "persona" verification, where you sign the key of a -pseudonymous user. - -2 means you did casual verification of the key. For example, this -could mean that you verified that the key fingerprint and checked the -user ID on the key against a photo ID. - -3 means you did extensive verification of the key. For example, this -could mean that you verified the key fingerprint with the owner of the -key in person, and that you checked, by means of a hard to forge -document with a photo ID (such as a passport) that the name of the key -owner matches the name in the user ID on the key, and finally that you -verified (by exchange of email) that the email address on the key -belongs to the key owner. - -Note that the examples given above for levels 2 and 3 are just that: -examples. In the end, it is up to you to decide just what "casual" -and "extensive" mean to you. - -This option defaults to 0. - -@item ---trusted-key @code{long key ID} -Assume that the specified key (which must be given -as a full 8 byte key ID) is as trustworthy as one of -your own secret keys. This option is useful if you -don't want to keep your secret keys (or one of them) -online but still want to be able to check the validity of a given -recipient's or signator's key. - -@item ---trust-model @code{pgp|classic|always} -Set what trust model GnuPG should follow. The models are: - -@table @asis -@item pgp -This is the web-of-trust combined with trust signatures as used in PGP -5.x and later. This is the default trust model. - -@item classic -This is the standard web-of-trust as used in PGP 2.x and earlier. - -@item always -Skip key validation and assume that used keys are always fully -trusted. You won't use this unless you have installed some external -validation scheme. This option also suppresses the "[uncertain]" tag -printed with signature checks when there is no evidence that the user -ID is bound to the key. - -@end table - -@item ---always-trust -Identical to `---trust-model always' - -@item ---keyserver @code{name} -Use @code{name} as your keyserver. This is the server that ---recv-keys, ----send-keys, and --search-keys will communicate with to receive keys -from, send keys to, and search for keys on. The format of the -@code{name} is a URI: `scheme:[//]keyservername[:port]' The scheme is -the type of keyserver: "hkp" for the Horowitz (or compatible) -keyservers, "ldap" for the NAI LDAP keyserver, or "mailto" for the -Horowitz email keyserver. Note that your particular installation of -GnuPG may have other keyserver types available as well. Keyserver -schemes are case-insensitive. - -Most keyservers synchronize with each other, so there is generally no -need to send keys to more than one server. Using the command "host -l -pgp.net | grep wwwkeys" gives you a list of HKP keyservers. When -using one of the wwwkeys servers, due to load balancing using -round-robin DNS you may notice that you get a different key server -each time. - -@item ---keyserver-options @code{parameters} -This is a space or comma delimited string that gives options for the -keyserver. Options can be prepended with a `no-' to give the opposite -meaning. Valid import-options or export-options may be used here as -well to apply to importing (---recv-key) or exporting (--send-key) a -key from a keyserver. While not all options are available for all -keyserver types, some common options are: - -@table @asis -@item include-revoked -When searching for a key with ---search-keys, include keys that are -marked on the keyserver as revoked. Note that this option is always -set when using the NAI HKP keyserver, as this keyserver does not -differentiate between revoked and unrevoked keys. - -@item include-disabled -When searching for a key with ---search-keys, include keys that are -marked on the keyserver as disabled. Note that this option is not -used with HKP keyservers. - -@item include-subkeys -When receiving a key, include subkeys as potential targets. Note that -this option is not used with HKP keyservers, as they do not support -retrieving keys by subkey id. - -@item use-temp-files -On most Unix-like platforms, GnuPG communicates with the keyserver -helper program via pipes, which is the most efficient method. This -option forces GnuPG to use temporary files to communicate. On some -platforms (such as Win32 and RISC OS), this option is always enabled. - -@item keep-temp-files -If using `use-temp-files', do not delete the temp files after using -them. This option is useful to learn the keyserver communication -protocol by reading the temporary files. - -@item verbose -Tell the keyserver helper program to be more verbose. This option can -be repeated multiple times to increase the verbosity level. - -@item honor-http-proxy -For keyserver schemes that use HTTP (such as HKP), try to access the -keyserver over the proxy set with the environment variable -"http_proxy". - -@item auto-key-retrieve -This option enables the automatic retrieving of keys from a keyserver -when verifying signatures made by keys that are not on the local -keyring. - -Note that this option makes a "web bug" like behavior possible. -Keyserver operators can see which keys you request, so by sending you -a message signed by a brand new key (which you naturally will not have -on your local keyring), the operator can tell both your IP address and -the time when you verified the signature. - -@end table - -@item ---import-options @code{parameters} -This is a space or comma delimited string that gives options for -importing keys. Options can be prepended with a `no-' to give the -opposite meaning. The options are: - -@table @asis -@item allow-local-sigs -Allow importing key signatures marked as "local". This is not -generally useful unless a shared keyring scheme is being used. -Defaults to no. - -@item repair-pks-subkey-bug -During import, attempt to repair the damage caused by the PKS -keyserver bug (pre version 0.9.6) that mangles keys with multiple -subkeys. Note that this cannot completely repair the damaged key as -some crucial data is removed by the keyserver, but it does at least -give you back one subkey. Defaults to no for regular ---import and to -yes for keyserver ---recv-keys. - -@end table - -@item ---export-options @code{parameters} -This is a space or comma delimited string that gives options for -exporting keys. Options can be prepended with a `no-' to give the -opposite meaning. The options are: - -@table @asis -@item include-non-rfc -Include non-RFC compliant keys in the export. Defaults to yes. - -@item include-local-sigs -Allow exporting key signatures marked as "local". This is not -generally useful unless a shared keyring scheme is being used. -Defaults to no. - -@item include-attributes -Include attribute user IDs (photo IDs) while exporting. This is -useful to export keys if they are going to be used by an OpenPGP -program that does not accept attribute user IDs. Defaults to yes. - -@item include-sensitive-revkeys -Include designated revoker information that was marked as -"sensitive". Defaults to no. - -@end table - -@item ---list-options @code{parameters} -This is a space or comma delimited string that gives options used when -listing keys and signatures (that is, ---list-keys, --list-sigs, ----list-public-keys, --list-secret-keys, and the --edit-key functions). -Options can be prepended with a `no-' to give the opposite meaning. -The options are: - -@table @asis -@item show-photos -Causes ---list-keys, --list-sigs, --list-public-keys, and ----list-secret-keys to display any photo IDs attached to the key. -Defaults to no. See also ---photo-viewer. - -@item show-policy-url -Show policy URLs in the ---list-sigs or --check-sigs listings. -Defaults to no. - -@item show-notation -Show signature notations in the ---list-sigs or --check-sigs listings. -Defaults to no. - -@item show-keyserver-url -Show any preferred keyserver URL in the ---list-sigs or --check-sigs -listings. Defaults to no. - -@item show-validity -Display the calculated validity of keys and user IDs during key -listings. Defaults to no. - -@item show-long-keyid -Display all 64 bits (16 digits) of key IDs during key listings, rather -than the more common 32 bit (8 digit) IDs. Defaults to no. - -@item show-unusable-uids -Show revoked and expired user IDs in key listings. Defaults to no. - -@item show-keyring -Display the keyring name at the head of key listings to show which -keyring a given key resides on. Defaults to no. - -@item show-sig-expire -Show signature expiration dates (if any) during ---list-sigs or ----check-sigs listings. Defaults to no. - -@end table - -@item ---verify-options @code{parameters} -This is a space or comma delimited string that gives options used when -verifying signatures. Options can be prepended with a `no-' to give -the opposite meaning. The options are: - -@table @asis -@item show-photos -Display any photo IDs present on the key that issued the signature. -Defaults to no. See also ---photo-viewer. - -@item show-policy-url -Show policy URLs in the signature being verified. Defaults to no. - -@item show-notation -Show signature notations in the signature being verified. Defaults to -no. - -@item show-keyserver-url -Show any preferred keyserver URL in the signature being verified. -Defaults to no. - -@item show-validity -Display the calculated validity of the user IDs on the key that issued -the signature. Defaults to no. - -@item show-long-keyid -Display all 64 bits (16 digits) of key IDs during signature -verification, rather than the more common 32 bit (8 digit) IDs. -Defaults to no. - -@item show-unusable-uids -Show revoked and expired user IDs during signature verification. -Defaults to no. - -@end table - -@item ---show-photos -@itemx ---no-show-photos -Causes ---list-keys, --list-sigs, --list-public-keys, ----list-secret-keys, and verifying a signature to also display the -photo ID attached to the key, if any. See also ---photo-viewer. These -options are deprecated. Use `---list-options [no-]show-photos' and/or -`---verify-options [no-]show-photos' instead. - -@item ---photo-viewer @code{string} -This is the command line that should be run to view a photo ID. "%i" -will be expanded to a filename containing the photo. "%I" does the -same, except the file will not be deleted once the viewer exits. -Other flags are "%k" for the key ID, "%K" for the long key ID, "%f" -for the key fingerprint, "%t" for the extension of the image type -(e.g. "jpg"), "%T" for the MIME type of the image (e.g. "image/jpeg"), -and "%%" for an actual percent sign. If neither %i or %I are present, -then the photo will be supplied to the viewer on standard input. - -The default viewer is "xloadimage -fork -quiet -title 'KeyID 0x%k' -stdin". Note that if your image viewer program is not secure, then -executing it from GnuPG does not make it secure. - -@item ---exec-path @code{string} -Sets a list of directories to search for photo viewers and keyserver -helpers. If not provided, keyserver helpers use the compiled-in -default directory, and photo viewers use the $PATH environment -variable. - -@item ---show-keyring -Display the keyring name at the head of key listings to show which -keyring a given key resides on. This option is deprecated: use -`---list-options [no-]show-keyring' instead. - -@item ---keyring @code{file} -Add @code{file} to the list of keyrings. If @code{file} begins with a -tilde and a slash, these are replaced by the HOME directory. If the -filename does not contain a slash, it is assumed to be in the GnuPG -home directory ("~/.gnupg" if ---homedir is not used). The filename -may be prefixed with a scheme: - -"gnupg-ring:" is the default one. - -It might make sense to use it together with ---no-default-keyring. - -@item ---secret-keyring @code{file} -Same as ---keyring but for the secret keyrings. - -@item ---primary-keyring @code{file} -Designate @code{file} as the primary public keyring. This means that -newly imported keys (via ---import or keyserver --recv-from) will go to -this keyring. - -@item ---trustdb-name @code{file} -Use @code{file} instead of the default trustdb. If @code{file} begins -with a tilde and a slash, these are replaced by the HOME directory. If -the filename does not contain a slash, it is assumed to be in the -GnuPG home directory ("~/.gnupg" if ---homedir is not used). - -@item ---homedir @code{directory} -Set the name of the home directory to @code{directory} If this -option is not used it defaults to "~/.gnupg". It does -not make sense to use this in a options file. This -also overrides the environment variable "GNUPGHOME". - -@item ---charset @code{name} -Set the name of the native character set. This is used -to convert some strings to proper UTF-8 encoding. If this option is not used, the default character set is determined -from the current locale. A verbosity level of 3 shows the used one. -Valid values for @code{name} are: - -@table @asis -@item iso-8859-1 -This is the Latin 1 set. - -@item iso-8859-2 -The Latin 2 set. - -@item iso-8859-15 -This is currently an alias for -the Latin 1 set. - -@item koi8-r -The usual Russian set (rfc1489). - -@item utf-8 -Bypass all translations and assume -that the OS uses native UTF-8 encoding. - -@end table - -@item ---utf8-strings -@itemx ---no-utf8-strings -Assume that the arguments are already given as UTF8 strings. The default -(---no-utf8-strings) -is to assume that arguments are encoded in the character set as specified -by ---charset. These options affect all following arguments. Both options may -be used multiple times. - -@item ---options @code{file} -Read options from @code{file} and do not try to read -them from the default options file in the homedir -(see ---homedir). This option is ignored if used -in an options file. - -@item ---no-options -Shortcut for "---options /dev/null". This option is -detected before an attempt to open an option file. -Using this option will also prevent the creation of a -"~./gnupg" homedir. - -@item ---load-extension @code{name} -Load an extension module. If @code{name} does not contain a slash it is -searched for in the directory configured when GnuPG was built -(generally "/usr/local/lib/gnupg"). Extensions are not generally -useful anymore, and the use of this option is deprecated. - -@item ---debug @code{flags} -Set debugging flags. All flags are or-ed and @code{flags} may -be given in C syntax (e.g. 0x0042). - -@item ---debug-all -Set all useful debugging flags. - -@item ---enable-progress-filter -Enable certain PROGRESS status outputs. This option allows frontends -to display a progress indicator while gpg is processing larger files. -There is a slight performance overhead using it. - -@item ---status-fd @code{n} -Write special status strings to the file descriptor @code{n}. -See the file DETAILS in the documentation for a listing of them. - -@item ---logger-fd @code{n} -Write log output to file descriptor @code{n} and not to stderr. - -@item ---attribute-fd @code{n} -Write attribute subpackets to the file descriptor @code{n}. This is -most useful for use with ---status-fd, since the status messages are -needed to separate out the various subpackets from the stream -delivered to the file descriptor. - -@item ---sk-comments -@itemx ---no-sk-comments -Include secret key comment packets when exporting secret keys. This -is a GnuPG extension to the OpenPGP standard, and is off by default. -Please note that this has nothing to do with the comments in clear -text signatures or armor headers. ---no-sk-comments disables this -option. - -@item ---comment @code{string} -@itemx ---no-comments -Use @code{string} as a comment string in clear text signatures and -ASCII armored messages or keys (see ---armor). The default behavior is -not to use a comment string. ---comment may be repeated multiple times -to get multiple comment strings. ---no-comments removes all comments. - -@item ---emit-version -@itemx ---no-emit-version -Force inclusion of the version string in ASCII armored output. ----no-emit-version disables this option. - -@item ---sig-notation @code{name=value} -@itemx ---cert-notation @code{name=value} -@itemx -N, ---set-notation @code{name=value} -Put the name value pair into the signature as notation data. -@code{name} must consist only of printable characters or spaces, and -must contain a '@@' character. This is to help prevent pollution of -the IETF reserved notation namespace. The ---expert flag overrides the -'@@' check. @code{value} may be any printable string; it will be -encoded in UTF8, so you should check that your ---charset is set -correctly. If you prefix @code{name} with an exclamation mark, the -notation data will be flagged as critical (rfc2440:5.2.3.15). ----sig-notation sets a notation for data signatures. --cert-notation -sets a notation for key signatures (certifications). ---set-notation -sets both. - -There are special codes that may be used in notation names. "%k" will -be expanded into the key ID of the key being signed, "%K" into the -long key ID of the key being signed, "%f" into the fingerprint of the -key being signed, "%s" into the key ID of the key making the -signature, "%S" into the long key ID of the key making the signature, -"%g" into the fingerprint of the key making the signature (which might -be a subkey), "%p" into the fingerprint of the primary key of the key -making the signature, and "%%" results in a single "%". %k, %K, and -%f are only meaningful when making a key signature (certification). - -@item ---show-notation -@itemx ---no-show-notation -Show signature notations in the ---list-sigs or --check-sigs listings -as well as when verifying a signature with a notation in it. These -options are deprecated. Use `---list-options [no-]show-notation' -and/or `---verify-options [no-]show-notation' instead. - -@item ---sig-policy-url @code{string} -@itemx ---cert-policy-url @code{string} -@itemx ---set-policy-url @code{string} -Use @code{string} as a Policy URL for signatures (rfc2440:5.2.3.19). -If you prefix it with an exclamation mark, the policy URL packet will -be flagged as critical. ---sig-policy-url sets a a policy url for data -signatures. ---cert-policy-url sets a policy url for key signatures -(certifications). ---set-policy-url sets both. - -The same %-expandos used for notation data are available here as well. - -@item ---show-policy-url -@itemx ---no-show-policy-url -Show policy URLs in the ---list-sigs or --check-sigs listings as well -as when verifying a signature with a policy URL in it. These options -are deprecated. Use `---list-options [no-]show-policy-url' and/or -`---verify-options [no-]show-policy-url' instead. - -@item ---sig-keyserver-url @code{string} -Use @code{string} as a preferred keyserver URL for data signatures. If -you prefix it with an exclamation mark, the keyserver URL packet will -be flagged as critical. - -The same %-expandos used for notation data are available here as well. - -@item ---set-filename @code{string} -Use @code{string} as the filename which is stored inside messages. -This overrides the default, which is to use the actual filename of the -file being encrypted. - -@item ---for-your-eyes-only -@itemx ---no-for-your-eyes-only -Set the `for your eyes only' flag in the message. This causes GnuPG -to refuse to save the file unless the ---output option is given, and -PGP to use the "secure viewer" with a Tempest-resistant font to -display the message. This option overrides ---set-filename. ----no-for-your-eyes-only disables this option. - -@item ---use-embedded-filename -Try to create a file with a name as embedded in the data. -This can be a dangerous option as it allows to overwrite files. - -@item ---completes-needed @code{n} -Number of completely trusted users to introduce a new -key signer (defaults to 1). - -@item ---marginals-needed @code{n} -Number of marginally trusted users to introduce a new -key signer (defaults to 3) - -@item ---max-cert-depth @code{n} -Maximum depth of a certification chain (default is 5). - -@item ---cipher-algo @code{name} -Use @code{name} as cipher algorithm. Running the program -with the command ---version yields a list of supported -algorithms. If this is not used the cipher algorithm is -selected from the preferences stored with the key. - -@item ---digest-algo @code{name} -Use @code{name} as the message digest algorithm. Running the program -with the command ---version yields a list of supported algorithms. - -@item ---compress-algo @code{name} -Use compression algorithm @code{name}. "zlib" is RFC1950 ZLIB -compression. "zip" is RFC-1951 ZIP compression which is used by PGP. -"uncompressed" or "none" disables compression. If this option is not -used, the default behavior is to examine the recipient key preferences -to see which algorithms the recipient supports. If all else fails, -ZIP is used for maximum compatibility. Note, however, that ZLIB may -give better compression results if that is more important, as the -compression window size is not limited to 8k. - -@item ---cert-digest-algo @code{name} -Use @code{name} as the message digest algorithm used when signing a -key. Running the program with the command ---version yields a list of -supported algorithms. Be aware that if you choose an algorithm that -GnuPG supports but other OpenPGP implementations do not, then some -users will not be able to use the key signatures you make, or quite -possibly your entire key. - -@item ---s2k-cipher-algo @code{name} -Use @code{name} as the cipher algorithm used to protect secret keys. -The default cipher is CAST5. This cipher is also used for -conventional encryption if ---personal-cipher-preferences and ----cipher-algo is not given. - -@item ---s2k-digest-algo @code{name} -Use @code{name} as the digest algorithm used to mangle the passphrases. -The default algorithm is SHA-1. - -@item ---s2k-mode @code{n} -Selects how passphrases are mangled. If @code{n} is 0 a plain -passphrase (which is not recommended) will be used, a 1 adds a salt to -the passphrase and a 3 (the default) iterates the whole process a -couple of times. Unless ---rfc1991 is used, this mode is also used for -conventional encryption. - -@item ---simple-sk-checksum -Secret keys are integrity protected by using a SHA-1 checksum. This -method will be part of an enhanced OpenPGP specification but GnuPG -already uses it as a countermeasure against certain attacks. Old -applications don't understand this new format, so this option may be -used to switch back to the old behaviour. Using this this option -bears a security risk. Note that using this option only takes effect -when the secret key is encrypted - the simplest way to make this -happen is to change the passphrase on the key (even changing it to the -same value is acceptable). - -@item ---disable-cipher-algo @code{name} -Never allow the use of @code{name} as cipher algorithm. -The given name will not be checked so that a later loaded algorithm -will still get disabled. - -@item ---disable-pubkey-algo @code{name} -Never allow the use of @code{name} as public key algorithm. -The given name will not be checked so that a later loaded algorithm -will still get disabled. - -@item ---no-sig-cache -Do not cache the verification status of key signatures. -Caching gives a much better performance in key listings. However, if -you suspect that your public keyring is not save against write -modifications, you can use this option to disable the caching. It -probably does not make sense to disable it because all kind of damage -can be done if someone else has write access to your public keyring. - -@item ---no-sig-create-check -GnuPG normally verifies each signature right after creation to protect -against bugs and hardware malfunctions which could leak out bits from -the secret key. This extra verification needs some time (about 115% -for DSA keys), and so this option can be used to disable it. -However, due to the fact that the signature creation needs manual -interaction, this performance penalty does not matter in most settings. - -@item ---auto-check-trustdb -@itemx ---no-auto-check-trustdb -If GnuPG feels that its information about the Web-of-Trust has to be -updated, it automatically runs the ---check-trustdb command internally. -This may be a time consuming process. ---no-auto-check-trustdb -disables this option. - -@item ---throw-keyid -Do not put the keyids into encrypted packets. This option hides the -receiver of the message and is a countermeasure against traffic -analysis. It may slow down the decryption process because all -available secret keys are tried. - -@item ---no-throw-keyid -Resets the ---throw-keyid option. - -@item ---not-dash-escaped -This option changes the behavior of cleartext signatures -so that they can be used for patch files. You should not -send such an armored file via email because all spaces -and line endings are hashed too. You can not use this -option for data which has 5 dashes at the beginning of a -line, patch files don't have this. A special armor header -line tells GnuPG about this cleartext signature option. - -@item ---escape-from-lines -@itemx ---no-escape-from-lines -Because some mailers change lines starting with "From " to ">From -" it is good to handle such lines in a special way when creating -cleartext signatures to prevent the mail system from breaking the -signature. Note that all other PGP versions do it this way too. -Enabled by default. ---no-escape-from-lines disables this option. - -@item ---passphrase-fd @code{n} -Read the passphrase from file descriptor @code{n}. If you use -0 for @code{n}, the passphrase will be read from stdin. This -can only be used if only one passphrase is supplied. -Don't use this option if you can avoid it. - -@item ---command-fd @code{n} -This is a replacement for the deprecated shared-memory IPC mode. -If this option is enabled, user input on questions is not expected -from the TTY but from the given file descriptor. It should be used -together with ---status-fd. See the file doc/DETAILS in the source -distribution for details on how to use it. - -@item ---use-agent -@itemx ---no-use-agent -Try to use the GnuPG-Agent. Please note that this agent is still under -development. With this option, GnuPG first tries to connect to the -agent before it asks for a passphrase. ---no-use-agent disables this -option. - -@item ---gpg-agent-info -Override the value of the environment variable -@samp{GPG_AGENT_INFO}. This is only used when ---use-agent has been given - -@item Compliance options -These options control what GnuPG is compliant to. Only one of these -options may be active at a time. Note that the default setting of -this is nearly always the correct one. See the INTEROPERABILITY WITH -OTHER OPENPGP PROGRAMS section below before using one of these -options. - -@table @asis -@item ---gnupg -Use standard GnuPG behavior. This is essentially OpenPGP behavior -(see ---openpgp), but with some additional workarounds for common -compatibility problems in different versions of PGP. This is the -default option, so it is not generally needed, but it may be useful to -override a different compliance option in the gpg.conf file. - -@item ---openpgp -Reset all packet, cipher and digest options to strict OpenPGP -behavior. Use this option to reset all previous options like ----rfc1991, --force-v3-sigs, --s2k-*, --cipher-algo, --digest-algo and ----compress-algo to OpenPGP compliant values. All PGP workarounds are -disabled. - -@item ---rfc2440 -Reset all packet, cipher and digest options to strict RFC-2440 -behavior. Note that this is currently the same thing as ---openpgp. - -@item ---rfc1991 -Try to be more RFC-1991 (PGP 2.x) compliant. - -@item ---pgp2 -Set up all options to be as PGP 2.x compliant as possible, and warn if -an action is taken (e.g. encrypting to a non-RSA key) that will create -a message that PGP 2.x will not be able to handle. Note that `PGP -2.x' here means `MIT PGP 2.6.2'. There are other versions of PGP 2.x -available, but the MIT release is a good common baseline. - -This option implies `---rfc1991 --disable-mdc --no-force-v4-certs ----no-sk-comment --escape-from-lines --force-v3-sigs ----no-ask-sig-expire --no-ask-cert-expire --cipher-algo IDEA ----digest-algo MD5 --compress-algo 1'. It also disables --textmode -when encrypting. - -@item ---pgp6 -Set up all options to be as PGP 6 compliant as possible. This -restricts you to the ciphers IDEA (if the IDEA plugin is installed), -3DES, and CAST5, the hashes MD5, SHA1 and RIPEMD160, and the -compression algorithms none and ZIP. This also disables ----throw-keyid, and making signatures with signing subkeys as PGP 6 -does not understand signatures made by signing subkeys. - -This option implies `---disable-mdc --no-sk-comment --escape-from-lines ----force-v3-sigs --no-ask-sig-expire' - -@item ---pgp7 -Set up all options to be as PGP 7 compliant as possible. This is -identical to ---pgp6 except that MDCs are not disabled, and the list of -allowable ciphers is expanded to add AES128, AES192, AES256, and -TWOFISH. - -@item ---pgp8 -Set up all options to be as PGP 8 compliant as possible. PGP 8 is a -lot closer to the OpenPGP standard than previous versions of PGP, so -all this does is disable ---throw-keyid and set --escape-from-lines. -The allowed algorithms list is the same as ---pgp7 with the addition of -the SHA-256 digest algorithm. - -@end table - -@item ---force-v3-sigs -@itemx ---no-force-v3-sigs -OpenPGP states that an implementation should generate v4 signatures -but PGP versions 5 and higher only recognize v4 signatures on key -material. This option forces v3 signatures for signatures on data. -Note that this option overrides ---ask-sig-expire, as v3 signatures -cannot have expiration dates. ---no-force-v3-sigs disables this -option. - -@item ---force-v4-certs -@itemx ---no-force-v4-certs -Always use v4 key signatures even on v3 keys. This option also -changes the default hash algorithm for v3 RSA keys from MD5 to SHA-1. ----no-force-v4-certs disables this option. - -@item ---force-mdc -Force the use of encryption with a modification detection code. This -is always used with the newer ciphers (those with a blocksize greater -than 64 bits), or if all of the recipient keys indicate MDC support in -their feature flags. - -@item ---disable-mdc -Disable the use of the modification detection code. Note that by -using this option, the encrypted message becomes vulnerable to a -message modification attack. - -@item ---allow-non-selfsigned-uid -@itemx ---no-allow-non-selfsigned-uid -Allow the import and use of keys with user IDs which are not -self-signed. This is not recommended, as a non self-signed user ID is -trivial to forge. ---no-allow-non-selfsigned-uid disables. - -@item ---allow-freeform-uid -Disable all checks on the form of the user ID while generating a new -one. This option should only be used in very special environments as -it does not ensure the de-facto standard format of user IDs. - -@item ---ignore-time-conflict -GnuPG normally checks that the timestamps associated with keys and -signatures have plausible values. However, sometimes a signature -seems to be older than the key due to clock problems. This option -makes these checks just a warning. See also ---ignore-valid-from for -timestamp issues on subkeys. - -@item ---ignore-valid-from -GnuPG normally does not select and use subkeys created in the future. -This option allows the use of such keys and thus exhibits the -pre-1.0.7 behaviour. You should not use this option unless you there -is some clock problem. See also ---ignore-time-conflict for timestamp -issues with signatures. - -@item ---ignore-crc-error -The ASCII armor used by OpenPGP is protected by a CRC checksum against -transmission errors. Sometimes it happens that the CRC gets mangled -somewhere on the transmission channel but the actual content (which is -protected by the OpenPGP protocol anyway) is still okay. This option -will let gpg ignore CRC errors. - -@item ---ignore-mdc-error -This option changes a MDC integrity protection failure into a warning. -This can be useful if a message is partially corrupt, but it is -necessary to get as much data as possible out of the corrupt message. -However, be aware that a MDC protection failure may also mean that the -message was tampered with intentionally by an attacker. - -@item ---lock-once -Lock the databases the first time a lock is requested -and do not release the lock until the process -terminates. - -@item ---lock-multiple -Release the locks every time a lock is no longer -needed. Use this to override a previous ---lock-once -from a config file. - -@item ---lock-never -Disable locking entirely. This option should be used only in very -special environments, where it can be assured that only one process -is accessing those files. A bootable floppy with a stand-alone -encryption system will probably use this. Improper usage of this -option may lead to data and key corruption. - -@item ---no-random-seed-file -GnuPG uses a file to store its internal random pool over invocations. -This makes random generation faster; however sometimes write operations -are not desired. This option can be used to achieve that with the cost of -slower random generation. - -@item ---no-verbose -Reset verbose level to 0. - -@item ---no-greeting -Suppress the initial copyright message. - -@item ---no-secmem-warning -Suppress the warning about "using insecure memory". - -@item ---no-permission-warning -Suppress the warning about unsafe file and home directory (---homedir) -permissions. Note that the permission checks that GnuPG performs are -not intended to be authoritative, but rather they simply warn about -certain common permission problems. Do not assume that the lack of a -warning means that your system is secure. - -Note that the warning for unsafe ---homedir permissions cannot be -supressed in the gpg.conf file, as this would allow an attacker to -place an unsafe gpg.conf file in place, and use this file to supress -warnings about itself. The ---homedir permissions warning may only be -supressed on the command line. - -@item ---no-mdc-warning -Suppress the warning about missing MDC integrity protection. - -@item ---no-armor -Assume the input data is not in ASCII armored format. - -@item ---no-default-keyring -Do not add the default keyrings to the list of -keyrings. - -@item ---skip-verify -Skip the signature verification step. This may be -used to make the decryption faster if the signature -verification is not needed. - -@item ---with-colons -Print key listings delimited by colons. Note that the output will be -encoded in UTF-8 regardless of any ---charset setting. This format is -useful when GnuPG is called from scripts and other programs as it is -easily machine parsed. The details of this format are documented in -the file doc/DETAILS, which is included in the GnuPG source -distribution. - -@item ---with-key-data -Print key listings delimited by colons (like ---with-colons) and print the public key data. - -@item ---with-fingerprint -Same as the command ---fingerprint but changes only the format of the output -and may be used together with another command. - -@item ---fast-list-mode -Changes the output of the list commands to work faster; this is achieved -by leaving some parts empty. Some applications don't need the user ID and -the trust information given in the listings. By using this options they -can get a faster listing. The exact behaviour of this option may change -in future versions. - -@item ---fixed-list-mode -Do not merge primary user ID and primary key in ---with-colon listing -mode and print all timestamps as seconds since 1970-01-01. - -@item ---list-only -Changes the behaviour of some commands. This is like ---dry-run but -different in some cases. The semantic of this command may be extended in -the future. Currently it only skips the actual decryption pass and -therefore enables a fast listing of the encryption keys. - -@item ---no-literal -This is not for normal use. Use the source to see for what it might be useful. - -@item ---set-filesize -This is not for normal use. Use the source to see for what it might be useful. - -@item ---emulate-md-encode-bug -GnuPG versions prior to 1.0.2 had a bug in the way a signature was encoded. -This options enables a workaround by checking faulty signatures again with -the encoding used in old versions. This may only happen for ElGamal signatures -which are not widely used. - -@item ---show-session-key -Display the session key used for one message. See ---override-session-key -for the counterpart of this option. - -We think that Key-Escrow is a Bad Thing; however the user should -have the freedom to decide whether to go to prison or to reveal the content of -one specific message without compromising all messages ever encrypted for one -secret key. DON'T USE IT UNLESS YOU ARE REALLY FORCED TO DO SO. - -@item ---override-session-key @code{string} -Don't use the public key but the session key @code{string}. The format of this -string is the same as the one printed by ---show-session-key. This option -is normally not used but comes handy in case someone forces you to reveal the -content of an encrypted message; using this option you can do this without -handing out the secret key. - -@item ---ask-sig-expire -@itemx ---no-ask-sig-expire -When making a data signature, prompt for an expiration time. If this -option is not specified, the expiration time is "never". ----no-ask-sig-expire disables this option. - -@item ---ask-cert-expire -@itemx ---no-ask-cert-expire -When making a key signature, prompt for an expiration time. If this -option is not specified, the expiration time is "never". ----no-ask-cert-expire disables this option. - -@item ---expert -@itemx ---no-expert -Allow the user to do certain nonsensical or "silly" things like -signing an expired or revoked key, or certain potentially incompatible -things like generating deprecated key types. This also disables -certain warning messages about potentially incompatible actions. As -the name implies, this option is for experts only. If you don't fully -understand the implications of what it allows you to do, leave this -off. ---no-expert disables this option. - -@item ---merge-only -Don't insert new keys into the keyrings while doing an import. - -@item ---allow-secret-key-import -This is an obsolete option and is not used anywhere. - -@item ---try-all-secrets -Don't look at the key ID as stored in the message but try all secret keys in -turn to find the right decryption key. This option forces the behaviour as -used by anonymous recipients (created by using ---throw-keyid) and might come -handy in case where an encrypted message contains a bogus key ID. - -@item ---enable-special-filenames -This options enables a mode in which filenames of the form -@file{-&n}, where n is a non-negative decimal number, -refer to the file descriptor n and not to a file with that name. - -@item ---no-expensive-trust-checks -Experimental use only. - -@item ---group @code{name=value1 value2 value3 ...} -Sets up a named group, which is similar to aliases in email programs. -Any time the group name is a recipient (-r or ---recipient), it will -be expanded to the values specified. - -The values are @code{key IDs} or fingerprints, but any key description -is accepted. Note that a value with spaces in it will be treated as -two different values. Note also there is only one level of expansion -- you cannot make an group that points to another group. When used -from the command line, it may be necessary to quote the argument to -this option to prevent the shell from treating it as multiple -arguments. - -@item ---no-groups -Clear the ---group list. - -@item ---preserve-permissions -Don't change the permissions of a secret keyring back to user -read/write only. Use this option only if you really know what you are doing. - -@item ---personal-cipher-preferences @code{string} -Set the list of personal cipher preferences to @code{string}, this list -should be a string similar to the one printed by the command "pref" in -the edit menu. This allows the user to factor in their own preferred -algorithms when algorithms are chosen via recipient key preferences. -The most highly ranked cipher in this list is also used for the ----symmetric encryption command. - -@item ---personal-digest-preferences @code{string} -Set the list of personal digest preferences to @code{string}, this list -should be a string similar to the one printed by the command "pref" in -the edit menu. This allows the user to factor in their own preferred -algorithms when algorithms are chosen via recipient key preferences. -The most highly ranked digest algorithm in this list is algo used when -signing without encryption (e.g. ---clearsign or --sign). The default -value is SHA-1. - -@item ---personal-compress-preferences @code{string} -Set the list of personal compression preferences to @code{string}, this -list should be a string similar to the one printed by the command -"pref" in the edit menu. This allows the user to factor in their own -preferred algorithms when algorithms are chosen via recipient key -preferences. The most highly ranked algorithm in this list is also -used when there are no recipient keys to consider (e.g. ---symmetric). - -@item ---default-preference-list @code{string} -Set the list of default preferences to @code{string}, this list should -be a string similar to the one printed by the command "pref" in the -edit menu. This affects both key generation and "updpref" in the edit -menu. - -@end table - -@majorheading How to specify a user ID -There are different ways to specify a user ID to GnuPG; here are some -examples: - -@table @asis -@item -@item 234567C4 -@itemx 0F34E556E -@itemx 01347A56A -@itemx 0xAB123456 -Here the key ID is given in the usual short form. - -@item 234AABBCC34567C4 -@itemx 0F323456784E56EAB -@itemx 01AB3FED1347A5612 -@itemx 0x234AABBCC34567C4 -Here the key ID is given in the long form as used by OpenPGP -(you can get the long key ID using the option ---with-colons). - -@item 1234343434343434C434343434343434 -@itemx 123434343434343C3434343434343734349A3434 -@itemx 0E12343434343434343434EAB3484343434343434 -@itemx 0xE12343434343434343434EAB3484343434343434 -The best way to specify a key ID is by using the fingerprint of -the key. This avoids any ambiguities in case that there are duplicated -key IDs (which are really rare for the long key IDs). - -@item =Heinrich Heine -Using an exact to match string. The equal sign indicates this. - -@item -Using the email address part which must match exactly. The left angle bracket -indicates this email address mode. - -@item +Heinrich Heine duesseldorf -All words must match exactly (not case sensitive) but can appear in -any order in the user ID. Words are any sequences of letters, -digits, the underscore and all characters with bit 7 set. - -@item Heine -@itemx *Heine -By case insensitive substring matching. This is the default mode but -applications may want to explicitly indicate this by putting the asterisk -in front. - -@end table - -Note that you can append an exclamation mark to key IDs or -fingerprints. This flag tells GnuPG to use exactly the given primary -or secondary key and not to try to figure out which secondary or -primary key to use. - -@majorheading RETURN VALUE -The program returns 0 if everything was fine, 1 if at least -a signature was bad, and other error codes for fatal errors. - -@majorheading EXAMPLES -@table @asis -@item gpg -se -r @code{Bob} @code{file} -sign and encrypt for user Bob - -@item gpg ---clearsign @code{file} -make a clear text signature - -@item gpg -sb @code{file} -make a detached signature - -@item gpg ---list-keys @code{user_ID} -show keys - -@item gpg ---fingerprint @code{user_ID} -show fingerprint - -@item gpg ---verify @code{pgpfile} -@itemx gpg ---verify @code{sigfile} @code{files} -Verify the signature of the file but do not output the data. The second form -is used for detached signatures, where @code{sigfile} is the detached -signature (either ASCII armored of binary) and @code{files} are the signed -data; if this is not given the name of the file holding the signed data is -constructed by cutting off the extension (".asc" or ".sig") of -@code{sigfile} or by asking the user for the filename. - -@end table - -@majorheading ENVIRONMENT -@table @asis -@item HOME -Used to locate the default home directory. - -@item GNUPGHOME -If set directory used instead of "~/.gnupg". - -@item GPG_AGENT_INFO -Used to locate the gpg-agent; only honored when ----use-agent is set. The value consists of 3 colon delimited fields: -The first is the path to the Unix Domain Socket, the second the PID of -the gpg-agent and the protocol version which should be set to 1. When -starting the gpg-agent as described in its documentation, this -variable is set to the correct value. The option ---gpg-agent-info can -be used to override it. - -@item http_proxy -Only honored when the keyserver-option -honor-http-proxy is set. - -@end table - -@majorheading FILES -@table @asis -@item ~/.gnupg/secring.gpg -The secret keyring - -@item ~/.gnupg/secring.gpg.lock -and the lock file - -@item ~/.gnupg/pubring.gpg -The public keyring - -@item ~/.gnupg/pubring.gpg.lock -and the lock file - -@item ~/.gnupg/trustdb.gpg -The trust database - -@item ~/.gnupg/trustdb.gpg.lock -and the lock file - -@item ~/.gnupg/random_seed -used to preserve the internal random pool - -@item ~/.gnupg/gpg.conf -Default configuration file - -@item ~/.gnupg/options -Old style configuration file; only used when gpg.conf -is not found - -@item /usr[/local]/share/gnupg/options.skel -Skeleton options file - -@item /usr[/local]/lib/gnupg/ -Default location for extensions - -@end table - -@majorheading WARNINGS -Use a *good* password for your user account and a *good* passphrase -to protect your secret key. This passphrase is the weakest part of the -whole system. Programs to do dictionary attacks on your secret keyring -are very easy to write and so you should protect your "~/.gnupg/" -directory very well. - -Keep in mind that, if this program is used over a network (telnet), it -is *very* easy to spy out your passphrase! - -If you are going to verify detached signatures, make sure that the -program knows about it; either be giving both filenames on the -command line or using @samp{-} to specify stdin. - -@majorheading INTEROPERABILITY WITH OTHER OPENPGP PROGRAMS -GnuPG tries to be a very flexible implementation of the OpenPGP -standard. In particular, GnuPG implements many of the "optional" -parts of the standard, such as the RIPEMD/160 hash, and the ZLIB -compression algorithms. It is important to be aware that not all -OpenPGP programs implement these optional algorithms and that by -forcing their use via the ---cipher-algo, --digest-algo, ----cert-digest-algo, or --compress-algo options in GnuPG, it is -possible to create a perfectly valid OpenPGP message, but one that -cannot be read by the intended recipient. - -For example, as of this writing, no version of official PGP supports -the BLOWFISH cipher algorithm. If you use it, no PGP user will be -able to decrypt your message. The same thing applies to the ZLIB -compression algorithm. By default, GnuPG uses the OpenPGP preferences -system that will always do the right thing and create messages that -are usable by all recipients, regardless of which OpenPGP program they -use. Only override this safe default if you know what you are doing. - -If you absolutely must override the safe default, or if the -preferences on a given key are invalid for some reason, you are far -better off using the ---pgp2, --pgp6, --pgp7, or --pgp8 options. These -options are safe as they do not force any particular algorithms in -violation of OpenPGP, but rather reduce the available algorithms to a -"PGP-safe" list. - -@majorheading BUGS -On many systems this program should be installed as setuid(root). This -is necessary to lock memory pages. Locking memory pages prevents the -operating system from writing memory pages to disk. If you get no -warning message about insecure memory your operating system supports -locking without being root. The program drops root privileges as soon -as locked memory is allocated. - -@bye diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi deleted file mode 100644 index 4bb688c44..000000000 --- a/doc/gpgsm.texi +++ /dev/null @@ -1,848 +0,0 @@ -@c Copyright (C) 2002 Free Software Foundation, Inc. -@c This is part of the GnuPG manual. -@c For copying conditions, see the file gnupg.texi. - -@node Invoking GPGSM -@chapter Invoking GPGSM -@cindex GPGSM command options -@cindex command options -@cindex options, GPGSM command - -@c man begin DESCRIPTION - -@sc{gpgsm} is a tool similar to @sc{gpg} to provide digital encryption -and signing servicesd on X.509 certificates and the CMS protocoll. It -is mainly used as a backend for S/MIME mail processing. @sc{gpgsm} -includes a full features certificate management and complies with all -rules defined for the German Sphinx project. - -@c man end - -@xref{Option Index}, for an index to GPGSM's commands and options. - -@menu -* GPGSM Commands:: List of all commands. -* GPGSM Options:: List of all options. -* GPGSM Examples:: Some usage examples. - -Developer information: -* Unattended Usage:: Using @sc{gpgsm} from other programs. -* GPGSM Protocol:: The protocol the server mode uses. -@end menu - -@c man begin COMMANDS - -@node GPGSM Commands -@section Commands - -Commands are not distinguished from options execpt for the fact that -only one one command is allowed. - -@menu -* General Commands:: Commands not specific to the functionality. -* Operational Commands:: Commands to select the type of operation. -* Certificate Management:: How to manage certificates. -@end menu - -@node General Commands -@subsection Commands not specific to the function - -@table @gnupgtabopt -@item --version -@opindex version -Print the program version and licensing information. Not that you can -abbreviate this command. - -@item --help, -h -@opindex help -Print a usage message summarizing the most usefule command-line options. -Not that you can abbreviate this command. - -@item --dump-options -@opindex dump-options -Print a list of all available options and commands. Not that you can -abbreviate this command. -@end table - - - -@node Operational Commands -@subsection Commands to select the type of operation - -@table @gnupgtabopt -@item --encrypt -@opindex encrypt -Perform an encryption. - -@item --decrypt -@opindex decrypt -Perform a decryption; the type of input is automatically detmerined. It -may either be in binary form or PEM encoded; automatic determination of -base-64 encoding is not done. - -@item --sign -@opindex sign -Create a digital signature. The key used is either the fist one found -in the keybox or thise set with the -u option - -@item --verify -@opindex verify -Check a signature file for validity. Depending on the arguments a -detached signatrue may also be checked. - -@item --server -@opindex server -Run in server mode and wait for commands on the @code{stdin}. - -@item --call-dirmngr @var{command} [@var{args}] -@opindex call-dirmngr -Behave as a Dirmngr client issuing the request @var{command} with the -optional list of @var{args}. The output of the Dirmngr is printed -stdout. Please note that file names given as arguments should have an -absulte file name (i.e. commencing with @code{/} because they are -passed verbatim to the Dirmngr and the working directory of the -Dirmngr might not be the same as the one of this client. Currently it -is not possible to pass data via stdin to the Dirmngr. @var{command} -should not contain spaces. - -This is command is required for certain maintaining tasks of the dirmngr -where a dirmngr must be able to call back to gpgsm. See the Dirmngr -manual for details. - -@item --call-protect-tool @var{arguments} -@opindex call-protect-tool -Certain maintenance operations are done by an external program call -@command{gpg-protect-tool}; this is usually not installed in a directory -listed in the PATH variable. This command provides a simple wrapper to -access this tool. @var{arguments} are passed verbatim to this command; -use @samp{--help} to get a list of supported operations. - - -@end table - - -@node Certificate Management -@subsection How to manage the certificate and keys - -@table @gnupgtabopt -@item --gen-key -@opindex gen-key -Generate a new key and a certificate request. - -@item --list-keys -@itemx -k -@opindex list-keys -List all available certificates stored in the local key database. - -@item --list-secret-keys -@itemx -K -@opindex list-secret-keys -List all available certificates for which a corresponding a secret key -is available. - -@item --list-external-keys @var{pattern} -@opindex list-keys -List certificates matching @var{pattern} using an external server. This -utilizes the @code{dirmngr} service. - -@item --dump-keys -@opindex dump-keys -List all available certificates stored in the local key database using a -format useful mainly for debugging. - -@item --dump-secret-keys -@opindex dump-secret-keys -List all available certificates for which a corresponding a secret key -is available using a format useful mainly for debugging. - -@item --dump-external-keys @var{pattern} -@opindex dump-keys -List certificates matching @var{pattern} using an external server. -This utilizes the @code{dirmngr} service. It uses a format useful -mainly for debugging. - -@item --keydb-clear-some-cert-flags -@opindex keydb-clear-some-cert-flags -This is a debugging aid to reset certain flags in the key database -which are used to cache certain certificate stati. It is especially -useful if a bad CRL or a weird running OCSP reponder did accidently -revoke certificate. There is no security issue with this command -because gpgsm always make sure that the validity of a certificate is -checked right before it is used. - -@item --delete-keys @var{pattern} -@opindex delete-keys -Delete the keys matching @var{pattern}. - -@item --export [@var{pattern}] -@opindex export -Export all certificates stored in the Keybox or those specified by the -optional @var{pattern}. When using along with the @code{--armor} option -a few informational lines are prepended before each block. - -@item --export-secret-key-p12 @var{key-id} -@opindex export -Export the private key and the certificate identified by @var{key-id} -in a PKCS#12 format. When using along with the @code{--armor} option -a few informational lines are prepended to the output. Note, that the -PKCS#12 format is higly insecure and this command is only provided if -there is no other way to exchange the private key. - -@item --learn-card -@opindex learn-card -Read information about the private keys from the smartcard and import -the certificates from there. This command utilizes the @sc{gpg-agent} -and in turn the @sc{scdaemon}. - -@item --passwd @var{user_id} -@opindex passwd -Change the passphrase of the private key belonging to the certificate -specified as @var{user_id}. Note, that changing the passphrase/PIN of a -smartcard is not yet supported. - -@end table - - -@node GPGSM Options -@section Option Summary - -GPGSM comes features a bunch ofoptions to control the exact behaviour -and to change the default configuration. - -@menu -* Configuration Options:: How to change the configuration. -* Certificate Options:: Certificate related options. -* Input and Output:: Input and Output. -* CMS Options:: How to change how the CMS is created. -* Esoteric Options:: Doing things one usually don't want to do. -@end menu - -@c man begin OPTIONS - -@node Configuration Options -@subsection How to change the configuration - -These options are used to change the configuraton and are usually found -in the option file. - -@table @gnupgtabopt - -@item --options @var{file} -@opindex options -Reads configuration from @var{file} instead of from the default -per-user configuration file. The default configuration file is named -@file{gpgsm.conf} and expected in the @file{.gnupg} directory directly -below the home directory of the user. - -@item -v -@item --verbose -@opindex v -@opindex verbose -Outputs additional information while running. -You can increase the verbosity by giving several -verbose commands to @sc{gpgsm}, such as @samp{-vv}. - -@item --policy-file @var{filename} -@opindex policy-file -Change the default name of the policy file to @var{filename}. - -@item --agent-program @var{file} -@opindex agent-program -Specify an agent program to be used for secret key operations. The -default value is the @file{/usr/local/bin/gpg-agent}. This is only used -as a fallback when the envrionment variable @code{GPG_AGENT_INFO} is not -set or a running agent can't be connected. - -@item --dirmngr-program @var{file} -@opindex dirmnr-program -Specify a dirmngr program to be used for @acronym{CRL} checks. The -default value is @file{/usr/sbin/dirmngr}. This is only used as a -fallback when the environment variable @code{DIRMNGR_INFO} is not set or -a running dirmngr can't be connected. - -@item --no-secmem-warning -@opindex no-secmem-warning -Don't print a warning when the so called "secure memory" can't be used. - - - -@end table - - -@node Certificate Options -@subsection Certificate related options - -@table @gnupgtabopt - -@item --enable-policy-checks -@itemx --disable-policy-checks -@opindex enable-policy-checks -@opindex disable-policy-checks -By default policy checks are enabled. These options may be used to -change it. - -@item --enable-crl-checks -@itemx --disable-crl-checks -@opindex enable-crl-checks -@opindex disable-crl-checks -By default the @acronym{CRL} checks are enabled and the DirMngr is used -to check for revoked certificates. The disable option is most useful -with an off-line network connection to suppress this check. - -@item --force-crl-refresh -@opindex force-crl-refresh -Tell the dirmngr to reload the CRL for each request. For better -performance, the dirmngr will actually optimize this by suppressing -the loading for short time intervalls (e.g. 30 minutes). This option -is useful to make sure that a fresh CRL is available for certificates -hold in the keybox. The suggested way of doing this is by using it -along with the option @code{--with-validation} for a ke listing -command. This option should not be used in a configuration file. - -@item --enable-ocsp -@itemx --disable-ocsp -@opindex enable-ocsp -@opindex disable-ocsp -Be default @acronym{OCSP} checks are disabled. The enable opton may -be used to enable OCSP checks via Dirmngr. If @acronym{CRL} checks -are also enabled, CRLs willbe used as a fallback if for some reason an -OCSP request won't succeed. - -@end table - -@node Input and Output -@subsection Input and Output - -@table @gnupgtabopt -@item --armor -@itemx -a -@opindex armor -@opindex -a -Create PEM encoded output. Default is binary output. - -@item --base64 -@opindex base64 -Create Base-64 encoded output; i.e. PEM without the header lines. - -@item --assume-armor -@opindex assume-armor -Assume the input data is PEM encoded. Default is to autodetect the -encoding but this is may fail. - -@item --assume-base64 -@opindex assume-base64 -Assume the input data is plain base-64 encoded. - -@item --assume-binary -@opindex assume-binary -Assume the input data is binary encoded. - -@item --local-user @var{user_id} -@item -u @var{user_id} -@opindex local-user -@opindex -u -Set the user(s) to be used for signing. The default is the first -secret key found in the database. - -@item --with-key-data -@opindex with-key-data -Displays extra information with the @code{--list-keys} commands. Especially -a line tagged @code{grp} is printed which tells you the keygrip of a -key. This string is for example used as the file name of the -secret key. - -@item --with-validation -@opindex with-validation -When doing a key listing, do a full validation check for each key and -print the result. This is usually a slow operation because it -requires a CRL lookup and other operations. - -@item --with-md5-fingerprint -For standard key listings, also print the MD5 fingerprint of the -certificate. - -@end table - -@node CMS Options -@subsection How to change how the CMS is created. - -@table @gnupgtabopt -@item --include-certs @var{n} -Using @var{n} of -2 includes all certificate except for the root cert, --1 includes all certs, 0 does not include any certs, 1 includes only -the signers cert (this is the default) and all other positive -values include up to @var{n} certificates starting with the signer cert. - -@end table - - - -@node Esoteric Options -@subsection Doing things one usually don't want todo. - - -@table @gnupgtabopt - -@item --faked-system-time @var{epoch} -@opindex faked-system-time -This option is only useful for testing; it sets the system time back or -forth to @var{epoch} which is the number of seconds elapsed since the year -1970. - -@item --debug-level @var{level} -@opindex debug-level -Select the debug level for investigating problems. @var{level} may be -one of: - - @table @code - @item none - no debugging at all. - @item basic - some basic debug messages - @item advanced - more verbose debug messages - @item expert - even more detailed messages - @item guru - all of the debug messages you can get - @end table - -How these messages are mapped to the actual debugging flags is not -specified and may change with newer releaes of this program. They are -however carefully selected to best aid in debugging. - -@item --debug @var{flags} -@opindex debug -This option is only useful for debugging and the behaviour may change -at any time without notice; using @code{--debug-levels} is the -preferred method to select the debug verbosity. FLAGS are bit encoded -and may be given in usual C-Syntax. The currently defined bits are: - - @table @code - @item 0 (1) - X.509 or OpenPGP protocol related data - @item 1 (2) - values of big number integers - @item 2 (4) - low level crypto operations - @item 5 (32) - memory allocation - @item 6 (64) - caching - @item 7 (128) - show memory statistics. - @item 9 (512) - write hashed data to files named @code{dbgmd-000*} - @item 10 (1024) - trace Assuan protocol - @end table - -Note, that all flags set using this option may get overriden by -@code{--debug-level}. - -@item --debug-all -@opindex debug-all -Same as @code{--debug=0xffffffff} - -@item --debug-allow-core-dump -@opindex debug-allow-core-dump -Usually gpgsm tries to avoid dumping core by well written code and by -disabling core dumps for security reasons. However, bugs are pretty -durable beasts and to squash them it is sometimes useful to have a core -dump. This option enables core dumps unless the Bad Thing happened -before the option parsing. - -@item --debug-no-chain-validation -@opindex debug-no-chain-validation -This is actually not a debugging option but only useful as such. It -lets gpgsm bypass all certificate chain validation checks. - -@item --debug-ignore-expiration -@opindex debug-ignore-expiration -This is actually not a debugging option but only useful as such. It -lets gpgsm ignore all notAfter dates, this is used by the regresssion -tests. - -@end table - -All the long options may also be given in the configuration file after -stripping off the two leading dashes. - - - -@c -@c Examples -@c -@node GPGSM Examples -@section Examples - -@c man begin EXAMPLES - -@example -$ gpgsm -er goo@@bar.net ciphertext -@end example - -@c man end - - - -@c --------------------------------- -@c The machine interface -@c -------------------------------- -@node Unattended Usage -@section Unattended Usage - -@sc{gpgsm} is often used as a backend engine by other software. To help -with this a machine interface has been defined to have an unambiguous -way to do this. This is most likely used with the @code{--server} command -but may also be used in the standard operation mode by using the -@code{--status-fd} option. - -@menu -* Automated signature checking:: Automated signature checking. -@end menu - -@node Automated signature checking,,,Unattended Usage -@section Automated signature checking - -It is very important to understand the semantics used with signature -verification. Checking a signature is not as simple as it may sound and -so the ooperation si a bit complicated. In mosted cases it is required -to look at several status lines. Here is a table of all cases a signed -message may have: - -@table @asis -@item The signature is valid -This does mean that the signature has been successfully verified, the -certificates are all sane. However there are two subcases with -important information: One of the certificates may have expired or a -signature of a message itself as expired. It is a sound practise to -consider such a signature still as valid but additional information -should be displayed. Depending on the subcase @sc{gpgsm} will issue -these status codes: - @table @asis - @item signature valid and nothing did expire - @code{GOODSIG}, @code{VALIDSIG}, @code{TRUST_FULLY} - @item signature valid but at least one certificate has expired - @code{EXPKEYSIG}, @code{VALIDSIG}, @code{TRUST_FULLY} - @item signature valid but expired - @code{EXPSIG}, @code{VALIDSIG}, @code{TRUST_FULLY} - Note, that this case is currently not implemented. - @end table - -@item The signature is invalid -This means that the signature verification failed (this is an indication -of af a transfer error, a programm error or tampering with the message). -@sc{gpgsm} issues one of these status codes sequences: - @table @code - @item @code{BADSIG} - @item @code{GOODSIG}, @code{VALIDSIG} @code{TRUST_NEVER} - @end table - -@item Error verifying a signature -For some reason the signature could not be verified, i.e. it can't be -decided whether the signature is valid or invalid. A common reason for -this is a missing certificate. - -@end table - - -@c -@c Assuan Protocol -@c -@node GPGSM Protocol -@section The Protocol the Server Mode Uses. - -Description of the protocol used to access GPGSM. GPGSM does implement -the Assuan protocol and in addition provides a regular command line -interface which exhibits a full client to this protocol (but uses -internal linking). To start gpgsm as a server the commandline "gpgsm ---server" must be used. Additional options are provided to select the -communication method (i.e. the name of the socket). - -We assume that the connection has already been established; see the -Assuan manual for details. - -@menu -* GPGSM ENCRYPT:: Encrypting a message. -* GPGSM DECRYPT:: Decrypting a message. -* GPGSM SIGN:: Signing a message. -* GPGSM VERIFY:: Verifying a message. -* GPGSM GENKEY:: Generating a key. -* GPGSM LISTKEYS:: List available keys. -* GPGSM EXPORT:: Export certificates. -* GPGSM IMPORT:: Import certificates. -* GPGSM DELETE:: Delete certificates. -@end menu - - -@node GPGSM ENCRYPT -@subsection Encrypting a Message - -Before encrytion can be done the recipient must be set using the -command: - -@example - RECIPIENT @var{userID} -@end example - -Set the recipient for the encryption. @var{userID} should be the -internal representation of the key; the server may accept any other way -of specification. If this is a valid and trusted recipient the server -does respond with OK, otherwise the return is an ERR with the reason why -the recipient can't be used, the encryption will then not be done for -this recipient. If the policy is not to encrypt at all if not all -recipients are valid, the client has to take care of this. All -@code{RECIPIENT} commands are cumulative until a @code{RESET} or an -successful @code{ENCRYPT} command. - -@example - INPUT FD=@var{n} [--armor|--base64|--binary] -@end example - -Set the file descriptor for the message to be encrypted to @var{n}. -Obviously the pipe must be open at that point, the server establishes -its own end. If the server returns an error the client should consider -this session failed. - -The @code{--armor} option may be used to advice the server that the -input data is in @acronym{PEM} format, @code{--base64} advices that a -raw base-64 encoding is used, @code{--binary} advices of raw binary -input (@acronym{BER}). If none of these options is used, the server -tries to figure out the used encoding, but this may not always be -correct. - -@example - OUTPUT FD=@var{n} [--armor|--base64] -@end example - -Set the file descriptor to be used for the output (i.e. the encrypted -message). Obviously the pipe must be open at that point, the server -establishes its own end. If the server returns an error he client -should consider this session failed. - -The option armor encodes the output in @acronym{PEM} format, the -@code{--base64} option applies just a base 64 encoding. No option -creates binary output (@acronym{BER}). - -The actual encryption is done using the command - -@example - ENCRYPT -@end example - -It takes the plaintext from the @code{INPUT} command, writes to the -ciphertext to the file descriptor set with the @code{OUTPUT} command, -take the recipients from all the recipients set so far. If this command -fails the clients should try to delete all output currently done or -otherwise mark it as invalid. GPGSM does ensure that there won't be any -security problem with leftover data on the output in this case. - -This command should in general not fail, as all necessary checks have -been done while setting the recipients. The input and output pipes are -closed. - - -@node GPGSM DECRYPT -@subsection Decrypting a message - -Input and output FDs are set the same way as in encryption, but -@code{INPUT} refers to the ciphertext and output to the plaintext. There -is no need to set recipients. GPGSM automatically strips any -@acronym{S/MIME} headers from the input, so it is valid to pass an -entire MIME part to the INPUT pipe. - -The encryption is done by using the command - -@example - DECRYPT -@end example - -It performs the decrypt operation after doing some check on the internal -state. (e.g. that all needed data has been set). Because it utilizes -the GPG-Agent for the session key decryption, there is no need to ask -the client for a protecting passphrase - GpgAgent takes care of this by -requesting this from the user. - - -@node GPGSM SIGN -@subsection Signing a Message - -Signing is usually done with these commands: - -@example - INPUT FD=@var{n} [--armor|--base64|--binary] -@end example - -This tells GPGSM to read the data to sign from file descriptor @var{n}. - -@example - OUTPUT FD=@var{m} [--armor|--base64] -@end example - -Write the output to file descriptor @var{m}. If a detached signature is -requested, only the signature is written. - -@example - SIGN [--detached] -@end example - -Sign the data set with the INPUT command and write it to the sink set by -OUTPUT. With @code{--detached}, a detached signature is created -(surprise). - -The key used for signining is the default one or the one specified in -the configuration file. To get finer control over the keys, it is -possible to use the command - -@example - SIGNER @var{userID} -@end example - -to the signer's key. @var{userID} should be the -internal representation of the key; the server may accept any other way -of specification. If this is a valid and trusted recipient the server -does respond with OK, otherwise the return is an ERR with the reason why -the key can't be used, the signature will then not be created using -this key. If the policy is not to sign at all if not all -keys are valid, the client has to take care of this. All -@code{SIGNER} commands are cumulative until a @code{RESET} is done. -Note that a @code{SIGN} does not reset this list of signers which is in -contrats to the @code{RECIPIENT} command. - - -@node GPGSM VERIFY -@subsection Verifying a Message - -To verify a mesage the command: - -@example - VERIFY -@end example - -is used. It does a verify operation on the message send to the input FD. -The result is written out using status lines. If an output FD was -given, the signed text will be written to that. If the signature is a -detached one, the server will inquire about the signed material and the -client must provide it. - -@node GPGSM GENKEY -@subsection Generating a Key - -This is used to generate a new keypair, store the secret part in the -@acronym{PSE} and the public key in the key database. We will probably -add optional commands to allow the client to select whether a hardware -token is used to store the key. Configuration options to GPGSM can be -used to restrict the use of this command. - -@example - GENKEY -@end example - -GPGSM checks whether this command is allowed and then does an -INQUIRY to get the key parameters, the client should then send the -key parameters in the native format: - -@example - S: INQUIRE KEY_PARAM native - C: D foo:fgfgfg - C: D bar - C: END -@end example - -Please note that the server may send Status info lines while reading the -data lines from the client. After this the key generation takes place -and the server eventually does send an ERR or OK response. Status lines -may be issued as a progress indicator. - - -@node GPGSM LISTKEYS -@subsection List available keys - -To list the keys in the internal database or using an external key -provider, the command: - -@example - LISTKEYS @var{pattern} -@end example - -is used. To allow multiple patterns (which are ORed during the search) -quoting is required: Spaces are to be translated into "+" or into "%20"; -in turn this requires that the usual escape quoting rules are done. - -@example - LISTSECRETKEYS @var{pattern} -@end example - -Lists only the keys where a secret key is available. - -The list commands commands are affected by the option - -@example - OPTION list-mode=@var{mode} -@end example - -where mode may be: -@table @code -@item 0 -Use default (which is usually the same as 1). -@item 1 -List only the internal keys. -@item 2 -List only the external keys. -@item 3 -List internal and external keys. -@end table - -Note that options are valid for the entire session. - - -@node GPGSM EXPORT -@subsection Export certificates - -To export certificate from the internal key database the command: - -@example - EXPORT @var{pattern} -@end example - -is used. To allow multiple patterns (which are ORed) quoting is -required: Spaces are to be translated into "+" or into "%20"; in turn -this requires that the usual escape quoting rules are done. - -The format of the output depends on what was set with the OUTPUT -command. When using @acronym{PEM} encoding a few informational lines -are prepended. - - -@node GPGSM IMPORT -@subsection Import certificates - -To import certificates into the internal key database, the command - -@example - IMPORT -@end example - -is used. The data is expected on the file descriptor set with the -@code{INPUT} command. Certain checks are performend on the -certificate. Note that the code will also handle PKCS\#12 files and -import private keys; a helper program is used for that. - - -@node GPGSM DELETE -@subsection Delete certificates - -To delete certificate the command - -@example - DELKEYS @var{pattern} -@end example - -is used. To allow multiple patterns (which are ORed) quoting is -required: Spaces are to be translated into "+" or into "%20"; in turn -this requires that the usual escape quoting rules are done. - -The certificates must be specified unambiguously otherwise an error is -returned. - diff --git a/doc/gpl.texi b/doc/gpl.texi deleted file mode 100644 index ca0508fad..000000000 --- a/doc/gpl.texi +++ /dev/null @@ -1,397 +0,0 @@ -@node Copying -@appendix GNU GENERAL PUBLIC LICENSE - -@cindex GPL, GNU General Public License -@center Version 2, June 1991 - -@display -Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc. -59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@appendixsubsec Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software---to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - -@iftex -@appendixsubsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -@end iftex -@ifinfo -@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -@end ifinfo - -@enumerate -@item -This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The ``Program'', below, -refers to any such program or work, and a ``work based on the Program'' -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term ``modification''.) Each licensee is addressed as ``you''. - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - -@item -You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - -@item -You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - -@enumerate a -@item -You must cause the modified files to carry prominent notices -stating that you changed the files and the date of any change. - -@item -You must cause any work that you distribute or publish, that in -whole or in part contains or is derived from the Program or any -part thereof, to be licensed as a whole at no charge to all third -parties under the terms of this License. - -@item -If the modified program normally reads commands interactively -when run, you must cause it, when started running for such -interactive use in the most ordinary way, to print or display an -announcement including an appropriate copyright notice and a -notice that there is no warranty (or else, saying that you provide -a warranty) and that users may redistribute the program under -these conditions, and telling the user how to view a copy of this -License. (Exception: if the Program itself is interactive but -does not normally print such an announcement, your work based on -the Program is not required to print an announcement.) -@end enumerate - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - -@item -You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - -@enumerate a -@item -Accompany it with the complete corresponding machine-readable -source code, which must be distributed under the terms of Sections -1 and 2 above on a medium customarily used for software interchange; or, - -@item -Accompany it with a written offer, valid for at least three -years, to give any third party, for a charge no more than your -cost of physically performing source distribution, a complete -machine-readable copy of the corresponding source code, to be -distributed under the terms of Sections 1 and 2 above on a medium -customarily used for software interchange; or, - -@item -Accompany it with the information you received as to the offer -to distribute corresponding source code. (This alternative is -allowed only for noncommercial distribution and only if you -received the program in object code or executable form with such -an offer, in accord with Subsection b above.) -@end enumerate - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - -@item -You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - -@item -You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - -@item -Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - -@item -If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - -@item -If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - -@item -The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and ``any -later version'', you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - -@item -If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - -@iftex -@heading NO WARRANTY -@end iftex -@ifinfo -@center NO WARRANTY -@end ifinfo - -@item -BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - -@item -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. -@end enumerate - -@iftex -@heading END OF TERMS AND CONDITIONS -@end iftex -@ifinfo -@center END OF TERMS AND CONDITIONS -@end ifinfo - -@page -@unnumberedsec How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the ``copyright'' line and a pointer to where the full notice is found. - -@smallexample -@var{one line to give the program's name and an idea of what it does.} -Copyright (C) 19@var{yy} @var{name of author} - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -@end smallexample - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - -@smallexample -Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author} -Gnomovision comes with ABSOLUTELY NO WARRANTY; for details -type `show w'. This is free software, and you are welcome -to redistribute it under certain conditions; type `show c' -for details. -@end smallexample - -The hypothetical commands @samp{show w} and @samp{show c} should show -the appropriate parts of the General Public License. Of course, the -commands you use may be called something other than @samp{show w} and -@samp{show c}; they could even be mouse-clicks or menu items---whatever -suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a ``copyright disclaimer'' for the program, if -necessary. Here is a sample; alter the names: - -@smallexample -@group -Yoyodyne, Inc., hereby disclaims all copyright -interest in the program `Gnomovision' -(which makes passes at compilers) written -by James Hacker. - -@var{signature of Ty Coon}, 1 April 1989 -Ty Coon, President of Vice -@end group -@end smallexample - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi deleted file mode 100644 index 51ec4b34c..000000000 --- a/doc/scdaemon.texi +++ /dev/null @@ -1,387 +0,0 @@ -@c Copyright (C) 2002 Free Software Foundation, Inc. -@c This is part of the GnuPG manual. -@c For copying conditions, see the file gnupg.texi. - -@node Invoking SCDAEMON -@chapter Invoking the SCDAEMON -@cindex SCDAEMON command options -@cindex command options -@cindex options, SCDAEMON command - -@c man begin DESCRIPTION - -The @sc{scdaeon} is a daemon to manage smartcards. It is usually -invoked by gpg-agent and in general not used directly. - -@c man end - -@xref{Option Index}, for an index to GPG-AGENTS's commands and options. - -@menu -* Scdaemon Commands:: List of all commands. -* Scdaemon Options:: List of all options. -* Scdaemon Examples:: Some usage examples. -* Scdaemon Protocol:: The protocol the daemon uses. -@end menu - -@c man begin COMMANDS - -@node Scdaemon Commands -@section Commands - -Commands are not distinguished from options execpt for the fact that -only one one command is allowed. - -@table @gnupgtabopt -@item --version -@opindex version -Print the program version and licensing information. Not that you can -abbreviate this command. - -@item --help, -h -@opindex help -Print a usage message summarizing the most usefule command-line options. -Not that you can abbreviate this command. - -@item --dump-options -@opindex dump-options -Print a list of all available options and commands. Not that you can -abbreviate this command. - -@item --server -@opindex server -Run in server mode and wait for commands on the @code{stdin}. This is -default mode is to create a socket and listen for commands there. - -@item --daemon -@opindex daemon -Run the program in the background. This option is required to prevent -it from being accidently running in the background. - -@item --print-atr -@opindex print-atr -This is mainly a debugging command, used to print the ATR -(Answer-To-Reset) of a card and exit immediately. - -@end table - - -@c man begin OPTIONS - -@node Scdaemon Options -@section Option Summary - -@table @gnupgtabopt - -@item --options @var{file} -@opindex options -Reads configuration from @var{file} instead of from the default -per-user configuration file. The default configuration file is named -@file{scdaemon.conf} and expected in the @file{.gnupg} directory directly -below the home directory of the user. - -@item -v -@item --verbose -@opindex v -@opindex verbose -Outputs additional information while running. -You can increase the verbosity by giving several -verbose commands to @sc{gpgsm}, such as @samp{-vv}. - -@item --debug-level @var{level} -@opindex debug-level -Select the debug level for investigating problems. @var{level} may be -one of: - - @table @code - @item none - no debugging at all. - @item basic - some basic debug messages - @item advanced - more verbose debug messages - @item expert - even more detailed messages - @item guru - all of the debug messages you can get - @end table - -How these messages are mapped to the actual debugging flags is not -specified and may change with newer releaes of this program. They are -however carefully selected to best aid in debugging. - -@item --debug @var{flags} -@opindex debug -This option is only useful for debugging and the behaviour may change at -any time without notice. FLAGS are bit encoded and may be given in -usual C-Syntax. The currently defined bits are: - - @table @code - @item 0 (1) - X.509 or OpenPGP protocol related data - @item 1 (2) - values of big number integers - @item 2 (4) - low level crypto operations - @item 5 (32) - memory allocation - @item 6 (64) - caching - @item 7 (128) - show memory statistics. - @item 9 (512) - write hashed data to files named @code{dbgmd-000*} - @item 10 (1024) - trace Assuan protocol - @item 12 (4096) - bypass all certificate validation - @end table - -@item --debug-all -@opindex debug-all -Same as @code{--debug=0xffffffff} - -@item --debug-wait @var{n} -@opindex debug-wait -When running in server mode, wait @var{n} seconds before entering the -actual processing loop and print the pid. This gives time to attach a -debugger. - -@item --debug-sc @var{n} -@opindex debug-sc -Set the debug level of the OpenSC library to @var{n}. - -@item --no-detach -@opindex no-detach -Don't detach the process from the console. This is manly usefule for -debugging. - -@item --log-file @var{file} -@opindex log-file -Append all logging output to @var{file}. This is very helpful in -seeing what the agent actually does. - -@item --reader-port @var{number} -When the program has been build without OpenSC support, this option must -be used to specify the port of the card terminal. A value of 0 refers -to the first serial device; add 32768 to access USB devices. The -default is 32768 (first USB device). - -@item --ctapi-driver @var{library} -Use @var{library} to access the smartcard reader. The current default -is @code{libtowitoko.so}. - - -@item --allow-admin -@itemx --deny-admin -@opindex allow-admin -@opindex deny-admin -This enables the use of Admin class commands for card application -where this is supported. Currently we support it for the OpenPGP -card. Deny is the default. This commands is useful to inhibit -accidental access to admin class command which could ultimately lock -the card through worng PIN numbers. - -@end table - -All the long options may also be given in the configuration file after -stripping off the two leading dashes. - - -@c -@c Examples -@c -@node Scdaemon Examples -@section Examples - -@c man begin EXAMPLES - -@example -$ scdaemon --server -v -@end example - -@c man end - -@c -@c Assuan Protocol -@c -@node Scdaemon Protocol -@section Scdaemon's Assuan Protocol - -The SC-Daemon should be started by the system to provide access to -external tokens. Using Smartcards on a multi-user system does not -make much sense expcet for system services, but in this case no -regular user accounts are hosted on the machine. - -A client connects to the SC-Daemon by connecting to the socket named -@file{/var/run/scdaemon/socket}, configuration information is read from -@var{/etc/scdaemon.conf} - -Each connection acts as one session, SC-Daemon takes care of -syncronizing access to a token between sessions. - -@menu -* Scdaemon SERIALNO:: Return the serial number. -* Scdaemon LEARN:: Read all useful information from the card. -* Scdaemon READCERT:: Return a certificate. -* Scdaemon READKEY:: Return a public key. -* Scdaemon PKSIGN:: Signing data with a Smartcard. -* Scdaemon PKDECRYPT:: Decrypting data with a Smartcard. -* Scdaemon GETATTR:: Read an attribute's value. -* Scdaemon SETATTR:: Update an attribute's value. -* Scdaemon GENKEY:: Generate a new key on-card. -* Scdaemon RANDOM:: Return random bytes generate on-card. -* Scdaemon PASSWD:: Change PINs. -* Scdaemon CHECKPIN:: Perform a VERIFY operation. -@end menu - -@node Scdaemon SERIALNO -@subsection Return the serial number - -This command should be used to check for the presence of a card. It is -special in that it can be used to reset the card. Most other commands -will return an error when a card change has been detected and the use of -this function is therefore required. - -Background: We want to keep the client clear of handling card changes -between operations; i.e. the client can assume that all operations are -done on the same card unless he call this function. - -@example - SERIALNO -@end example - -Return the serial number of the card using a status reponse like: - -@example - S SERIALNO D27600000000000000000000 0 -@end example - -The trailing 0 should be ignored for now, it is reserved for a future -extension. The serial number is the hex encoded value identified by -the @code{0x5A} tag in the GDO file (FIX=0x2F02). - - - -@node Scdaemon LEARN -@subsection Read all useful information from the card - -@example - LEARN [--force] -@end example - -Learn all useful information of the currently inserted card. When -used without the force options, the command might do an INQUIRE -like this: - -@example - INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp> -@end example - -The client should just send an @code{END} if the processing should go on -or a @code{CANCEL} to force the function to terminate with a cancel -error message. The response of this command is a list of status lines -formatted as this: - -@example - S KEYPAIRINFO @var{hexstring_with_keygrip} @var{hexstring_with_id} -@end example - -If there is no certificate yet stored on the card a single "X" is -returned in @var{hexstring_with_keygrip}. - -@node Scdaemon READCERT -@subsection Return a certificate - -@example - READCERT @var{hexified_certid} -@end example - -This function is used to read a certificate identified by -@var{hexified_certid} from the card. - - -@node Scdaemon READKEY -@subsection Return a public key - -@example -READKEY @var{hexified_certid} -@end example - -Return the public key for the given cert or key ID as an standard -S-Expression. - - - -@node Scdaemon PKSIGN -@subsection Signing data with a Smartcard - -To sign some data the caller should use the command - -@example - SETDATA @var{hexstring} -@end example - -to tell scdaemon about the data to be signed. The data must be given in -hex notation. The actual signing is done using the command - -@example - PKSIGN @var{keyid} -@end example - -where @var{keyid} is the hexified ID of the key to be used. The key id -may have been retrieved using the command @code{LEARN}. - - -@node Scdaemon PKDECRYPT -@subsection Decrypting data with a Smartcard - -To decrypt some data the caller should use the command - -@example - SETDATA @var{hexstring} -@end example - -to tell scdaemon about the data to be decrypted. The data must be given in -hex notation. The actual decryption is then done using the command - -@example - PKDECRYPT @var{keyid} -@end example - -where @var{keyid} is the hexified ID of the key to be used. - - -@node Scdaemon GETATTR -@subsection Read an attribute's value. - -TO BE WRITTEN. - -@node Scdaemon SETATTR -@subsection Update an attribute's value. - -TO BE WRITTEN. - -@node Scdaemon GENKEY -@subsection Generate a new key on-card. - -TO BE WRITTEN. - -@node Scdaemon RANDOM -@subsection Return random bytes generate on-card. - -TO BE WRITTEN. - - -@node Scdaemon PASSWD -@subsection Change PINs. - -TO BE WRITTEN. - - -@node Scdaemon CHECKPIN -@subsection Perform a VERIFY operation. - -TO BE WRITTEN. - - diff --git a/g10/ChangeLog b/g10/ChangeLog deleted file mode 100644 index 0e87c2f46..000000000 --- a/g10/ChangeLog +++ /dev/null @@ -1,8948 +0,0 @@ -2004-04-30 Werner Koch <wk@gnupg.org> - - * g10.c (main) <gpgconf>: Use gpg.conf and not /dev/null as - default filename. - -2004-04-28 Werner Koch <wk@gnupg.org> - - * card-util.c (card_edit): Remove PIN verification. - (generate_card_keys): New arg SERIALNO. Do PIN verification here - after resetting forced_chv1. - -2004-04-26 Werner Koch <wk@gnupg.org> - - * card-util.c (change_name): Check that the NAME is not too long. - (change_url): Likewise. - (change_login): Likewise. - -2004-03-23 Werner Koch <wk@gnupg.org> - - * g10.c: New options --gpgconf-list, --debug-level and --log-file - (set_debug): Add arg DEBUG_LEVEL. - (main): Look at less and less version specific config files. From - gnupg 1.3. - -2004-02-17 Werner Koch <wk@gnupg.org> - - * call-agent.c (start_agent): Ignore an empty GPG_AGENT_INFO. - * passphrase.c (agent_open): Ditto. - -2004-02-12 Werner Koch <wk@gnupg.org> - - * gpgv.c: Removed g10defs.h. - - * Makefile.am: Include cmacros.am for common flags. - -2004-02-11 Werner Koch <wk@gnupg.org> - - * openfile.c (try_make_homedir): Use GNUPG_DEFAULT_HOMEDIR. - * gpgv.c (main): Ditto. - * g10.c (main): Ditto. - -2004-01-19 Moritz Schulte <mo@g10code.com> - - * keygen.c (do_generate_keypair): Print member fname, instead of - newfname, again. - (do_generate_keypair): Don't try to execute certain pieces of code - in case an error occured. - (gen_card_key): Don't print out a message, which is already - printed by do_generate_keypair(). - -2004-01-18 Moritz Schulte <mo@g10code.com> - - * keygen.c (do_generate_keypair): Print member fname, instead of - newfname. - -2003-12-17 Werner Koch <wk@gnupg.org> - - * card-util.c (print_name): Fixed bad format string usage. - (print_isoname): Ditto. - - * trustdb.c (check_regexp): s/exp/expr/. - - * keyedit.c (trustsig_prompt): Removed a "> 255" term; it is - always false due to the data type. - - * passphrase.c (agent_get_passphrase): Use xasprintf and avoid - non-literal format strings. - - * tdbio.c (upd_hashtable, drop_from_hashtable, lookup_hashtable): - Fixed log_error format string bugs. Kudos to the now working - gcc-3.3 -Wformat-nonliteral and Florian Weimer's investigations in - gnupg 1.2.3. - -2003-12-15 Werner Koch <wk@gnupg.org> - - * seckey-cert.c (protect_secret_key): Use gry_create_nonce for the - IV; there is not need for real strong random here and it even - better protect the random bits used for the key. - -2003-11-16 Moritz Schulte <mo@g10code.com> - - * signal.c: Removed unused file. - -2003-11-10 Moritz Schulte <mo@g10code.com> - - * Makefile.am (INCLUDES): Added: @LIBGCRYPT_CFLAGS@. - -2003-10-25 Werner Koch <wk@gnupg.org> - - * call-agent.c (learn_status_cb, scd_genkey_cb): Fixed faulty use - of !spacep(). - -2003-10-20 Werner Koch <wk@gnupg.org> - - * card-util.c (card_edit): New command "passwd". Add logic to - check the PIN in advance. - (card_status): Add new args to return the serial number. Changed - all callers. - * call-agent.c (agent_scd_checkpin): New. - -2003-10-08 Werner Koch <wk@gnupg.org> - - * call-agent.c (agent_scd_getattr): Don't clear the passed info - structure, so that it can indeed be updated. - - * card-util.c (fpr_is_zero): New. - (generate_card_keys): New. - (card_edit): New command "generate". - * keygen.c (generate_keypair): New arg CARD_SERIALNO, removed call - to check_smartcard. - (check_smartcard,show_smartcard): Removed. - (show_sha1_fpr,fpr_is_zero): Removed. - -2003-10-01 Werner Koch <wk@gnupg.org> - - * card-util.c: Tweaked to use this source also under 1.3. - -2003-09-30 Werner Koch <wk@gnupg.org> - - * keylist.c (print_card_serialno): New. - (list_keyblock_print): Use it here. - - * card-util.c (toggle_forcesig): New. - (card_edit): New command "forcesig". - - * card-util.c (print_name, print_isoname): Use 0 and not LF fro - the max_n arg of tty_print_utf8_string2. - - * call-agent.c (agent_scd_getattr): New. - (learn_status_cb): Release values before assignment so that it can - be used by getattr to update the structure. - - * card-util.c (change_pin): Simplified. We now have only a PIN - and an Admin PIN. - -2003-09-27 Werner Koch <wk@gnupg.org> - - * sign.c (do_sign): Removed disabled testcode. - -2003-09-26 Timo Schulz <twoaday@freakmail.de> - - * card_status (card_status): Do not use fputs since the fp - parameter can be NULL. This fixes a segv. - -2003-09-24 Werner Koch <wk@gnupg.org> - - * card-util.c (print_isoname,card_status): Handle opt.with_colons. - (print_sha1_fpr_colon): New. - -2003-09-23 Werner Koch <wk@gnupg.org> - - Merged most of David Shaw's changes in 1.3 since 2003-06-03. - - * Makefile.am: Include W32LIBS where appropriate. - - * armor.c (parse_hash_header,armor_filter): Drop TIGER/192 support. - * g10.c (print_hex,print_mds): Ditto. - * pkclist.c (algo_available): Ditto. - - * armor.c (armor_filter): Allow using --comment multiple times to - get multiple Comment header lines. --no-comments resets list. - * options.h, g10.c (main): Ditto. Deprecate --default-comment in - favor of --no-comments. - - * g10.c (main): Trim --help to commonly used options. Remove -f. - - * g10.c (main): Add --multifile as an alias to turn --encrypt into - --encrypt-files (plus --verify-files, --decrypt-files). Error out - if --multifile is used with the commands that don't support it yet. - - * encode.c (use_mdc), g10.c (main): Use RFC1991 and RFC2440 - directly to check for MDC usability. Do not set the force_mdc or - disable_mdc flags since there is no point any longer. - - * g10.c (main): Use "keyserver-url" instead of - "preferred-keyserver" for the sake of short and simple commands. - (add_keyserver_url): Clarify a few strings. It's a - "preferred keyserver URL". - * keyedit.c (keyedit_menu): Ditto. - * sign.c (mk_notation_policy_etc): Ditto. - - * main.h, keygen.c (keygen_add_keyserver_url): Signature callback - for adding a keyserver URL. - * keyedit.c (keyedit_menu, menu_set_keyserver_url): New command to - set preferred keyserver to specified (or all) user IDs. - * build-packet.c (build_sig_subpkt): Set preferred keyserver flag - while building a preferred keyserver subpacket. - - * keylist.c (show_policy_url, show_keyserver_url): URLs might be - UTF8. - - * keyedit.c (menu_addrevoker): Fix leaking a few bytes. - - * keyedit.c (show_key_with_all_names): Use list-option - show-long-keyid in main --edit-key display. - - * keyedit.c (print_and_check_one_sig): Use list-option - show-long-keyid in --edit-key "check" function. - - * passphrase.c (agent_send_all_options): Make use of $GPG_TTY. - - * g10.c (main): Disable use-agent if passphrase-fd is given - later. Suggested by Kurt Garloff. - - * exec.c, g10.c, gpgv.c, passphrase.c, photoid.c: - s/__MINGW32__/_WIN32/ to help building on native Windows - compilers. Requested by Brian Gladman. From Werner on stable - branch. - - * options.h, g10.c (main): Add list-option - list-preferred-keyserver. - - * keyedit.c (change_passphrase): When responding 'no' to the blank - passphrase question, re-prompt for a new passphrase. This is bug - #202. - - * mainproc.c (check_sig_and_print): Use two different preferred - keyserver displays - one if the key is not present (to tell the - user where to get the key), the other if it is present (to tell - the user where the key can be refreshed). - - * packet.h, parse-packet.c (parse_signature): Set flag if a - preferred keyserver is present. - - * keylist.c (list_keyblock_print): Show keyserver url in listings - with list-option show-keyserver-url. - - * mainproc.c (check_sig_and_print): Get the uid validity before - printing any sig results to avoid munging the output with trustdb - warnings. - - * g10.c (main): Don't include --show-keyring in --help as it is - deprecated. - - * options.skel: Note that keyserver.pgp.com isn't synchronized, - and explain the roundrobin a bit better. - - * sig-check.c (check_key_signature2), import.c (import_one, - import_revoke_cert, chk_self_sigs, delete_inv_parts, - collapse_uids, merge_blocks): Make much quieter during import of - slightly munged, but recoverable, keys. Use log_error for - unrecoverable import failures. - - * keyring.c (keyring_rebuild_cache): Comment. - - * sign.c (mk_notation_and_policy): Making a v3 signature with - notations or policy urls is an error, not an info (i.e. increment - the errorcount). Don't print the notation or policy url to stdout - since it can be mixed into the output stream when piping and munge - the stream. - - * packet.h, sig-check.c (signature_check2, do_check, - do_check_messages): Provide a signing-key-is-revoked flag. Change - all callers. - - * status.h, status.c (get_status_string): New REVKEYSIG status tag - for a good signature from a revoked key. - - * mainproc.c (do_check_sig, check_sig_and_print): Use it here. - - * import.c (import_revoke_cert, merge_blocks, merge_sigs): Compare - actual signatures on import rather than using keyid or class - matching. This does not change actual behavior with a key, but - does mean that all sigs are imported whether they will be used or - not. - - * parse-packet.c (parse_signature): Don't give "signature packet - without xxxx" warnings for experimental pk algorithms. An - experimental algorithm may not have a notion of (for example) a - keyid (i.e. PGP's x.509 stuff). - - * options.h, g10.c (main), keylist.c (list_keyblock_print), - keyedit.c (print_and_check_one_sig): New "show-sig-expire" - list-option to show signature expiration dates (if any). - - * options.h, g10.c (main, add_keyserver_url): Add - --sig-preferred-keyserver to implant a "where to get my key" - subpacket into a signature. - - * sign.c (mk_notation_and_policy): Rename to - mk_notation_policy_etc and add preferred keyserver support for - signatures. - - * keygen.c (do_add_key_flags): Don't set the certify flag for - subkeys. - (ask_algo): Provide key flags for DSA, Elgamal_e, and Elgamal - subkeys. - (generate_keypair): Provide key flags for the default DSA/Elgamal - keys. - - * sig-check.c (signature_check, signature_check2, - check_key_signature, check_key_signature2): Allow passing NULLs - for unused parameters in the x2 form of each function to avoid the - need for dummy variables. getkey.c, mainproc.c: Change all - callers. - - * trustdb.h, trustdb.c (read_trust_options): New. Returns items - from the trustdb version record. - * keylist.c (public_key_list): Use it here for the new "tru" - record. - * gpgv.c (read_trust_options): Stub. - - * keyedit.c (show_key_with_all_names): Use list-option - show-validity in --edit-key interface as well. - - * options.h, g10.c (main), mainproc.c (check_sig_and_print): Add - verify-options "show-validity" and "show-long-keyid" to show - trustdb validity and long keyids during (file) signature - verification. - - * packet.h, main.h, sig-check.c (signature_check2) - (check_key_signature2, do_check): If ret_pk is set, fill in the pk - used to verify the signature. Change all callers in getkey.c, - mainproc.c, and sig-check.c. - - * keylist.c (list_keyblock_colon): Use the ret_pk from above to - put the fingerprint of the signing key in "sig" records during a - --with-colons --check-sigs. This requires --no-sig-cache as well - since we don't cache fingerprints. - - * parse-packet.c (parse_signature): No need to reserve 8 bytes for - the unhashed signature cache any longer. - - * misc.c (pct_expando): Add two new expandos - signer's - fingerprint (%g), and signer's primary fingerprint (%p). - - * g10.c (main): Add --rfc2440 alias for --openpgp since in a few - months, they won't be the same thing. - - * keyserver.c (parse_keyserver_uri): Accept "http" as an alias for - "hkp", since it is occasionally written that way. - (keyserver_spawn): Use ascii_isspace to avoid locale issues. - - * keygen.c (ask_user_id): Make --allow-freeform-uid apply to the - email field as well as the name field, and allow mixing fields - when it is set. - - * trustdb.c (validate_one_keyblock): Certifications on revoked or - expired uids do not count in the web of trust. - - * signal.c (init_one_signal, pause_on_sigusr, do_block): Only use - sigprocmask() if we have sigset_t, and only use sigaction() if we - have struct sigaction. This is for Forte c89 on Solaris which - seems to define only the function call half of the two pairs by - default. - (pause_on_sigusr): Typo. - (do_block): If we can't use sigprocmask() and sigset_t, try to get - the number of signals from NSIG as well as MAXSIG, and if we - can't, fail with an explanation. - - * signal.c, tdbio.c: Comment out the transaction code. It was not - used in this version, and was causing some build problems on - quasi-posix platforms (Solaris and Forte c89). - - * keylist.c (list_keyblock_colon): Don't include validity values - when listing secret keys since they can be incorrect and/or - misleading. This is a temporary kludge, and will be handled - properly in 1.9/2.0. - - * mainproc.c (check_sig_and_print): Only show the "key available - from" preferred keyserver line if the key is not currently - present. - - * keyedit.c (sign_uids): Do not sign expired uids without --expert - (same behavior as revoked uids). Do not allow signing a user ID - without a self-signature. --expert overrides. Add additional - prompt to the signature level question. - (menu_expire): When changing expiration dates, don't replace - selfsigs on revoked uids since this would effectively unrevoke - them. There is also no point in replacing expired selfsigs. This - is bug #181 - - * g10.c (add_notation_data): Make sure that only ascii is passed - to iscntrl. Noted by Christian Biere. - * getkey.c (classify_user_id2): Replaced isspace by spacep - * keygen.c (ask_user_id): Ditto. - (get_parameter_algo): Ditto. - * keyedit.c (keyedit_menu): Ditto. - * tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/. - * revoke.c (ask_revocation_reason): - * keyserver.c (keyserver_spawn): Dito. - - * parse-packet.c (parse): Disallow old style partial length for - all key material packets to avoid possible corruption of keyrings. - - * import.c (import_keys_internal): Invalidate the cache so that - the file descriptor gets closed. Fixes bug reported by Juan - F. Codagnone. - - * options.h, g10.c (main), main.h, keylist.c (show_keyserver_url), - mainproc.c (check_sig_and_print), parse-packet.c (dump_sig_subpkt, - parse_one_sig_subpkt, can_handle_critical): Add read-only support - for preferred keyserver subpackets. They're basically policy URLs - with a different name. Add a verify-option - "show-preferred-keyserver" to turn them on and off (on by default, - as per stable branch). - - * g10.c (main): Add "--set-notation" as alias to "--notation-data" - this is to make things consistent with --set-policy-url meaning - both sigs and certs. - - * options.h, g10.c (main), keylist.c (list_keyblock_print): Add - "show-validity" and "show-long-keyid" list-options. - - * gpgv.c (get_validity, trust_value_to_string): Stubs. - - * g10.c (main): Use SAFE_VERSION instead of VERSION in the - version-specific gpg.conf file so it can be overridden on RISCOS. - - * keyedit.c (show_key_with_all_names): Fix assertion failure when - using toggle to see a secret key. Reported by Maxim Britov. - - -2003-09-22 Timo Schulz <twoaday@freakmail.de> - - * card-util.c (card_status): Free pk in case of an error - and return if the card is no OpenPGP card. - -2003-09-18 Werner Koch <wk@gnupg.org> - - * g10.c: New command --card-edit. - * card-util.c (card_status): Use tty_fprintf for all output. - (print_sha1_fpr, print_isoname): Ditto. - (get_one_name,change_name, change_url, change_login,change_lang) - (change_sex): New; taken from keygen.c. - * keygen.c (smartcard_get_one_name, smartcard_change_name) - (smartcard_change_url, smartcard_change_login_data) - (smartcard_change_lang, smartcard_change_sex): Removed. - (check_smartcard): Removed most menu items. - -2003-09-06 Werner Koch <wk@gnupg.org> - - * misc.c (openpgp_pk_algo_usage): Allow AUTH where SIGN is allowed. - - * keygen.c (ask_passphrase): No need to allocated S2K in secure - memory. - -2003-09-04 Werner Koch <wk@gnupg.org> - - * keygen.c (do_add_key_flags, parse_parameter_usage) - (do_generate_keypair): Add support the proposed AUTH key flag. - * getkey.c (fixup_uidnode, merge_selfsigs_main) - (merge_selfsigs_subkey, premerge_public_with_secret): Ditto. - * keylist.c (print_capabilities): Ditto. - -2003-08-25 Timo Schulz <twoaday@freakmail.de> - - * pkglue.c (mpi_from_sexp): New. Used to factor out - some common code. - -2003-08-24 Werner Koch <wk@gnupg.org> - - * keygen.c (do_generate_keypair): Print a reminder to use --gen-revoke. - -2003-08-18 Timo Schulz <twoaday@freakmail.de> - - * encode.c (encode_sesskey): Checked the code and removed - the warning since all compatibility checks with PGP succeeded. - * mainproc.c (symkey_decrypt_sesskey): Better check for the - algorithm and check the return values of some functions. - * mdc.c (use_mdc): Simplified. - -2003-08-07 Werner Koch <wk@gnupg.org> - - * pkglue.c (pk_sign): Fix last change. - (pk_verify): Check for valid DATA array so that we don't segv in - Libgcrypt. - (pk_verify): Ditto. - -2003-08-06 Werner Koch <wk@gnupg.org> - - * pkglue.c (pk_sign): Allow signing using RSA. - -2003-08-05 Werner Koch <wk@gnupg.org> - - * Makefile.am (install-data-local): Dropped check for the ancient - gpgm tool. - (bin_PROGRAMS): Renamed gpg to gpg2 and gpgv to gpgv2. This is so - that it won't conflict with the current stable version of gpg. - - * pkglue.c (pk_check_secret_key): New. - * seckey-cert.c (do_check): Reenable this test here again. - - * g10.c (main): Add command -K as an alias for - --list-secret-keys. Command "-k" is now an alias to --list-keys. - Remove special treatment of -kv and -kvv. - (set_cmd): Ditto. - (main): Strip a "-cvs" suffix when testing for a version specific - config file. - - * status.h, status.c, g10.c [USE_SHM_COPROCESSING]: Removed. This - is not any longer available. - -2003-07-29 Werner Koch <wk@gnupg.org> - - * g10.c (main): Add secmem features and set the random seed file. - (g10_exit): Update the random seed file. - - * parse-packet.c (parse_signature,read_protected_v3_mpi) - (parse_key): Fixed use of mpi_set_opaque. - * keygen.c (gen_card_key): Ditto. - -2003-07-28 Werner Koch <wk@gnupg.org> - - * status.c (progress_cb): Adjusted for use with Libcgrypt. - (set_status_fd): Register that callback. - - * keygen.c (smartcard_change_login_data): New. - (smartcard_change_lang): New. - (smartcard_change_sex): New. - (check_smartcard): Add menu entries to edit the above. - (gen_elg,gen_dsa,gen_rsa): Reimplemented in terms of Libgcrypt. - (genhelp_protect, genhelp_factors, key_from_sexp): New. - * comment.c (make_comment_node_from_buffer): New. - (make_comment_node): Reimplemented in terms of above. - -2003-07-27 Werner Koch <wk@gnupg.org> - - Adjusted for gcry_mpi_print and gcry_mpi_scan API change. - -2003-07-24 Werner Koch <wk@gnupg.org> - - * g10.c: New command --card-status. - * card-util.c (card_status): New. - * call-agent.c (learn_status_cb): Parse more information. - - * keylist.c (print_pubkey_info): Add FP arg for optional printing - to a stream. Changed all callers. - -2003-07-23 Werner Koch <wk@gnupg.org> - - * keygen.c (generate_keypair): Create an AUTHKEYTYPE entry for cards. - (do_generate_keypair): Abd generate the authkey. - (check_smartcard): Changed menu accordingly. - -2003-07-22 Werner Koch <wk@gnupg.org> - - * g10.c: New command --change-pin. - * card-util.c: New. - * call-agent.c (agent_scd_change_pin): New. - (agent_release_card_info): New. - * keygen.c (check_smartcard): Use it here. - -2003-07-16 Werner Koch <wk@gnupg.org> - - * export.c (parse_export_options): New option sexp-format. - (export_seckeys,export_secsubkeys): Check sexp-format option. - (do_export): Ignore armor for sexp format. - (do_export_stream): Handle sexp-format. - (write_sexp_line,write_sexp_keyparm, build_sexp_seckey): New. - (build_sexp): New. - -2003-07-03 Werner Koch <wk@gnupg.org> - - * options.h (DBG_CIPHER): Reintroduced it. - * seskey.c (encode_session_key): Debug output of the session key. - - * pubkey-enc.c (get_it): Handle card case. - * call-agent.c (agent_scd_pkdecrypt): New. - * pkglue.c (pk_encrypt): Add RSA support. - - * g10.c (main): Default to --use-agent. - - * keygen.c (show_smartcard): Print info about the public key. - (check_smartcard): Check for existing key here. - (gen_card_key): And not anymore here. - (fpr_is_zero): New. - (generate_keypair): Generate both keys for a card. - (smartcard_change_url): Nw. - -2003-07-02 Werner Koch <wk@gnupg.org> - - * seckey-cert.c (is_secret_key_protected): Let it handle mode 1002. - -2003-07-01 Werner Koch <wk@gnupg.org> - - * keygen.c (gen_card_key): Obviously we should use the creation - date received from SCDAEMON, so that the fingerprints will match. - * sign.c (do_sign): Pass the serialno to the sign code. - * keyid.c (serialno_and_fpr_from_sk): New. - -2003-06-30 Werner Koch <wk@gnupg.org> - - * call-agent.h (agent_card_info_s): Add field serialno. - * call-agent.c (store_serialno): New. - (learn_status_cb): Store the serial number. - * keygen.c (gen_card_key): Store the serial number - (check_smartcard): New argument to return the serial number. - (generate_keypair): Get the serial number from check_smartcard and - store it as a parameter. - * parse-packet.c (parse_key): Use the protect.iv field to store the - serial number. - * build-packet.c (do_secret_key): Write the serial number. - -2003-06-27 Werner Koch <wk@gnupg.org> - - * seckey-cert.c (check_secret_key): Bypass the unprotection for - mode 1002. - * sign.c (do_sign): Handle card case (i.e. mode 1002). - -2003-06-26 Werner Koch <wk@gnupg.org> - - * build-packet.c (do_secret_key): Implement special protection - mode 1002. - * parse-packet.c (parse_key): Likewise. - - * keygen.c (smartcard_gen_key): New. - * call-agent.c (agent_scd_setattr): New. - -2003-06-24 Werner Koch <wk@gnupg.org> - - * Makefile.am: Removed signal.c - - * g10.c (emergency_cleanup): New. - (main): Use gnupg_init_signals and register malloc for assuan. - -2003-06-23 Werner Koch <wk@gnupg.org> - - * keyid.c (do_fingerprint_md): Made it work again. - -2003-06-19 Werner Koch <wk@gnupg.org> - - Fixed all "==" comparisons against error code constants to use - gpg_err_code(). - - * import.c (import_secret_one): - (import_revoke_cert): - (chk_self_sigs): - - * misc.c (openpgp_md_map_name): Check also for the Hx format. - (openpgp_cipher_map_name): Check also for the Sx format. - (pubkey_get_npkey): Adjusted for changed gcrypt API. - (pubkey_get_nskey): Ditto. - (pubkey_get_nsig): Ditto. - (pubkey_get_nenc): Ditto. - -2003-06-18 Werner Koch <wk@gnupg.org> - - Finished the bulk of changes for gnupg 1.9. This included - switching to libgcrypt functions, using shared error codes from - libgpg-error, replacing the old functions we used to have in - ../util by those in ../jnlib and ../common, renaming the malloc - functions and a couple of types. Note, that not all changes are - listed below becuause they are too similar and done at far too - many places. As of today the code builds using the current - libgcrypt from CVS but it is very unlikely that it actually works. - - * sig-check.c (cmp_help): Removed. Was never used. - - * pkglue.c: New. Most stuff taken from gnupg 1.1.2. - * pkglue.h: New. - - * misc.c (pull_in_libs): Removed. - - * keygen.c (count_chr): New. - (ask_user_id): Removed faked RNG support. - - * misc.c (openpgp_md_map_name,openpgp_cipher_map_name) - (openpgp_pk_map_name): New. - - * skclist.c (build_sk_list): Removed faked RNG support. - (is_insecure): Removed. - - * comment.c (make_mpi_comment_node): Use gcry MPI print function. - - * keyid.c (v3_keyid): New. - - * misc.c (mpi_write,mpi_write_opaque,mpi_read,mpi_read_opaque) - (mpi_print): New. Taken from gnupg 1.1.2. - (checksum_mpi): Replaced by implementation from 1.1.2. - - * g10.c (my_strusage): Renamed from strusage and return NULL - instead calling a default function. - (add_to_strlist2): New. Taken from ../util/strgutil.c of gnupg 1.2. - - * plaintext.c (handle_plaintext): New arg CREATE_FILE to cope with - the fact that gpg-error does not have this error code anymore. - - * mainproc.c (symkey_decrypt_sesskey): Ditto. - - * seskey.c (make_session_key): Adjusted for use with libgcrypt. - (encode_session_key): Ditto. - (do_encode_md): Ditto. - (encode_md_value): Ditto. - - * keyring.c: Use libgpg-error instead of READ_ERROR etc. - - * g10.c: Adjusted all algorithm name/id mapping functions. - (set_debug): Pass MPI and CRYPTO debug values to libgcrypt. - - * Makefile.am (INCLUDES): Define LOCALEDIR and the default error - source. - - * g10.c (i18n_init): s/G10_LOCALEDIR/LOCALEDIR/. - - Renamed m_alloc et al to xmalloc et al. - s/g10_errstr/gpg_strerror/ - s/MPI/gcry_mpi_t/ - Adjusted all md_open calls to the libgcrypt API. - - * build-packet.c (do_comment): Return error code from iobuf write - function. - (do_user_id): Ditto. - (do_public_key): Ditto. - - * Makefile.am: Add new files, link gpg with libgpg-error. - * g10.c, options.h: New option --agent-program. - * call-agent.c: New. - * gpg.h, call-agent.h: New. - -2003-06-03 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), keylist.c (list_keyblock_print): Add - "show-validity" and "show-long-keyid" list-options. - - * gpgv.c (get_validity, trust_value_to_string): Stubs. - - * g10.c (main): Use SAFE_VERSION instead of VERSION in the - version-specific gpg.conf file so it can be overridden on RISCOS. - -2003-06-01 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main), keylist.c (show_policy_url, show_notation), - mainproc.c (check_sig_and_print): Emulate the old policy and - notation behavior (display by default). Send to status-fd whether - it is displayed on the screen or not. - - * g10.c (main): Since we now have some options in devel that won't - work in a stable branch gpg.conf file, try for a version-specific - gpg.conf-VERSION file before falling back to gpg.conf. - - * main.h, options.h: Move various option flags to options.h. - -2003-05-31 David Shaw <dshaw@jabberwocky.com> - - * mainproc.c (check_sig_and_print), main.h, keylist.c - (show_policy, show_notation): Collapse the old print_notation_data - into show_policy() and show_notation() so there is only one - function to print notations and policy URLs. - - * options.h, main.h, g10.c (main), keyedit.c - (print_and_check_one_sig), keylist.c (list_one, - list_keyblock_print), pkclist.c (do_edit_ownertrust), sign.c - (mk_notation_and_policy): New "list-options" and "verify-options" - commands. These replace the existing - --show-photos/--no-show-photos, - --show-notation/--no-show-notation, - --show-policy-url/--no-show-policy-url, and --show-keyring - options. The new method is more flexible since a user can specify - (for example) showing photos during sig verification, but not in - key listings. The old options are emulated. - - * main.h, misc.c (parse_options): New general option line - parser. Fix the bug in the old version that did not handle report - syntax errors after a valid entry. - - * import.c (parse_import_options), export.c - (parse_export_options): Call it here instead of duplicating the - code. - -2003-05-30 David Shaw <dshaw@jabberwocky.com> - - * keylist.c (list_one): Don't show the keyring filename when in - --with-colons mode. Actually translate "Keyring" string. - - * mainproc.c (proc_tree): We can't currently handle multiple - signatures of different classes or digests (we'd pretty much have - to run a different hash context for each), but if they are all the - same, make an exception. This is Debian bug #194292. - - * sig-check.c (check_key_signature2): Make string translatable. - - * packet.h, getkey.c (fixup_uidnode): Mark real primary uids - differently than assumed primaries. - - * keyedit.c (no_primary_warning): Use the differently marked - primaries here in a new function to warn when an --edit-key - command might rearrange the self-sig dates enough to change which - uid is primary. - (menu_expire, menu_set_preferences): Use no_primary_warning() - here. - - * Makefile.am: Use @DLLIBS@ for -ldl. - -2003-05-26 David Shaw <dshaw@jabberwocky.com> - - * getkey.c (premerge_public_with_secret): Made "no secret subkey - for" warning a verbose item and translatable. (From wk on stable - branch) - - * sig-check.c (check_key_signature2): Made "no subkey for subkey - binding packet" a verbose item instead of a !quiet one. There are - too many garbled keys out in the wild. (From wk on stable branch) - - * filter.h: Remove const from WHAT. (From wk on stable branch) - - * progress.c (handle_progress): Store a copy of - NAME. (progress_filter): Release WHAT, make sure not to print a - NULL WHAT. (From wk on stable branch) - - * openfile.c (open_sigfile): Adjust free for new progress - semantics. (From wk on stable branch) - - * plaintext.c (ask_for_detached_datafile): Don't dealloc - pfx->WHAT. (From wk on stable branch) - - * seckey-cert.c (do_check): Issue the RSA_OR_IDEA status when the - cipher algo is IDEA to make it easier to track down the - problem. (From twoaday on stable branch) - -2003-05-24 David Shaw <dshaw@jabberwocky.com> - - * armor.c, g10.c, kbnode.c, misc.c, pkclist.c, sign.c, - build-packet.c, getkey.c, keydb.c, openfile.c, plaintext.c, - status.c, gpgv.c, keygen.c, options.h, sig-check.c, tdbio.h, - encode.c, mainproc.c, parse-packet.c, signal.c, textfilter.c: Edit - all preprocessor instructions to remove whitespace before the '#'. - This is not required by C89, but there are some compilers out - there that don't like it. - -2003-05-21 David Shaw <dshaw@jabberwocky.com> - - * trustdb.h, trustdb.c (is_disabled), gpgv.c (is_disabled): Rename - is_disabled to cache_disabled_value, which now takes a pk and not - just the keyid. This is for speed since there is no need to - re-fetch a key when we already have that key handy. Cache the - result of the check so we don't need to hit the trustdb more than - once. - - * getkey.c (skip_disabled): New function to get a pk and call - is_disabled on it. (key_byname): Use it here. - - * packet.h, getkey.c (skip_disabled), keylist.c - (print_capabilities): New "pk_is_disabled" macro to retrieve the - cached disabled value if available, and fill it in via - cache_disabled_value if not available. - - * trustdb.c (get_validity): Cache the disabled value since we have - it handy and it might be useful later. - - * parse-packet.c (parse_key): Clear disabled flag when parsing a - new key. Just in case someone forgets to clear the whole key. - - * getkey.c (merge_selfsigs_main): Add an "if all else fails" path - for setting a single user ID primary when there are multiple set - primaries all at the same second, or no primaries set and the most - recent user IDs are at the same second, or no signed user IDs at - all. This is arbitrary, but deterministic. - - * exec.h, photoid.h: Add copyright message. - - * keylist.c (list_keyblock_print): Don't dump attribs for - revoked/expired/etc uids for non-colon key listings. This is for - consistency with --show-photos. - - * main.h, keylist.c (dump_attribs), mainproc.c - (check_sig_and_print): Dump attribs if --attrib-fd is set when - verifying signatures. - - * g10.c (main): New --gnupg option to disable the various - --openpgp, --pgpX, etc. options. This is the same as --no-XXXX - for those options. - - * revoke.c (ask_revocation_reason): Clear old reason if user - elects to repeat question. This is bug 153. - - * keyedit.c (sign_uids): Show keyid of the key making the - signature. - -2003-05-21 Werner Koch <wk@gnupg.org> - - * progress.c (handle_progress) - * sign.c (write_plaintext_packet) - * encode.c (encode_simple,encode_crypt): Make sure that a filename - of "-" is considered to be stdin so that iobuf_get_filelength - won't get called. This fixes bug 156 reported by Gregery Barton. - -2003-05-02 David Shaw <dshaw@jabberwocky.com> - - * packet.h, build-packet.c (build_sig_subpkt), export.c - (do_export_stream), import.c (remove_bad_stuff, import), - parse-packet.c (dump_sig_subpkt, parse_one_sig_subpkt): Remove - vestigal code for the old sig cache subpacket. This wasn't - completely harmless as it caused subpacket 101 to disappear on - import and export. - - * options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, - sign.c, encode.c, getkey.c, revoke.c: The current flags for - different levels of PGP-ness are massively complex. This is step - one in simplifying them. No functional change yet, just use a - macro to check for compliance level. - - * sign.c (sign_file): Fix bug that causes spurious compression - preference warning. - - * sign.c (clearsign_file): Fix bug that prevents proper warning - message from appearing when clearsigning in --pgp2 mode with a - non-v3 RSA key. - - * main.h, misc.c (compliance_option_string, compliance_string, - compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file, - clearsign_file), encode.c (encode_crypt, - write_pubkey_enc_from_list): New functions to put the "this - message may not be usable...." warning in one place. - - * options.h, g10.c (main): Part two of the simplification. Use a - single enum to indicate what we are compliant to (1991, 2440, - PGPx, etc.) - - * g10.c (main): Show errors for failure in export, send-keys, - recv-keys, and refresh-keys. - - * options.h, g10.c (main): Give algorithm warnings for algorithms - chosen against the --pgpX and --openpgp rules. - - * keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in - --openpgp mode. - - * sign.c (sign_file), pkclist.c (algo_available): Allow passing a - hint of 0. - -2003-05-01 David Shaw <dshaw@jabberwocky.com> - - * tdbio.c (create_version_record): Only create new trustdbs with - TM_CLASSIC or TM_PGP. - - * trustdb.h, trustdb.c (trust_string, get_ownertrust_string, - get_validity_string, ask_ownertrust, validate_keys), pkclist.c - (do_edit_ownertrust): Rename trust_string to trust_value_to_string - for naming consistency. - - * trustdb.h, trustdb.c (string_to_trust_value): New function to - translate a string to a trust value. - - * g10.c (main): Use string_to_trust_value here for - --force-ownertrust. - - * options.h, g10.c (main), trustdb.c (trust_model_string, - init_trustdb, check_trustdb, update_trustdb, get_validity, - validate_one_keyblock): An "OpenPGP" trust model is misleading - since there is no official OpenPGP trust model. Use "PGP" - instead. - -2003-04-30 David Shaw <dshaw@jabberwocky.com> - - * build-packet.c (build_sig_subpkt): Comments. - - * exec.c (exec_write): Cast NULL to void* to properly terminate - varargs list. - - * keyedit.c (show_key_with_all_names): Just for safety, catch an - invalid pk algorithm. - - * sign.c (make_keysig_packet): Crucial that the call to mksubpkt - comes LAST before the calls to finalize the sig as that makes it - possible for the mksubpkt function to get a reliable pointer to - the subpacket area. - - * pkclist.c (do_we_trust_pre): If an untrusted key was chosen by a - particular user ID, use that ID as the one to ask about when - prompting whether to use the key anyway. - (build_pk_list): Similar change here when adding keys to the - recipient list. - - * trustdb.c (update_validity): Fix bug that prevented more than - one validity record per trust record. - (get_validity): When retrieving validity for a (user) supplied - user ID, return the validity for that user ID only, and do not - fall back to the general key validity. - (validate_one_keyblock): Some commentary on whether - non-self-signed user IDs belong in the web of trust (arguably, - they do). - -2003-04-27 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Add --no-textmode. - - * export.c (do_export_stream), keyedit.c (show_key_with_all_names, - menu_addrevoker), mainproc.c (check_sig_and_print), photoid.c - (show_photos), sign.c (mk_notation_and_policy), trustdb.c - (get_validity, reset_trust_records, validate_keys): Make some - strings translatable. - - * mainproc.c (check_sig_and_print): Show digest algorithm and sig - class when verifying a sig with --verbose on, and add version, pk - and hash algorithms and sig class to VALIDSIG. - - * parse-packet.c (enum_sig_subpkt): Make a warning message a - --verbose warning message since we don't need to warn every time - we see an unknown critical (we only need to invalidate the - signature). - - * trustdb.c (init_trustdb): Check the trustdb options even with - TM_AUTO since the auto may become TM_CLASSIC or TM_OPENPGP. - -2003-04-26 David Shaw <dshaw@jabberwocky.com> - - * sign.c (do_sign): Show the hash used when making a signature in - verbose mode. - - * tdbio.h, tdbio.c (tdbio_read_model): New function to return the - trust model used in a given trustdb. - - * options.h, g10.c (main), trustdb.c (init_trustdb, check_trustdb, - update_trustdb): Use tdbio_read_model to implement an "auto" trust - model which is set via the trustdb. - -2003-04-23 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_revoke_cert): Remove ultimate trust when - revoking an ultimately trusted key. - - * keyedit.c (sign_uids): Allow replacing expired signatures. - Allow duplicate signatures with --expert. - - * pkclist.c (check_signatures_trust): Don't display a null - fingerprint when checking a signature with --always-trust enabled. - - * filter.h (progress_filter_context_t), progress.c - (handle_progress), plaintext.c (ask_for_detached_datafile, - hash_datafiles): Fix compiler warnings. Make "what" constant. - - * build-packet.c (do_plaintext): Do not create invalid literal - packets with >255-byte names. - -2003-04-15 Werner Koch <wk@gnupg.org> - - * Makefile.am (AM_CFLAGS): Make use of AM_CFLAGS and AM_LDFLAGS. - - * g10.c, options.h: New option --enable-progress-filter. - * progress.c (handle_progress): Make use of it. - -2003-04-15 Marcus Brinkmann <marcus@g10code.de> - - * progress.c: New file. - * Makefile.am (common_source): Add progress.c. - * filter.h (progress_filter_context_t): New type. - (progress_filter, handle_progress): New prototypes. - * main.h (open_sigfile): New argument for prototype. - * openfile.c (open_sigfile): New argument to install progress - filter. - * encode.c (encode_simple): New variable PFX. Register - progress filter. Install text_filter after that. - (encode_crypt): Likewise. - * sign.c (sign_file): Likewise. - (clearsign_file): Likewise. - * decrypt.c (decrypt_message): Likewise. - (decrypt_messages): Likewise. - * verify.c (verify_signatures): Likewise. - (verify_one_file): Likewise. - * plaintext.c (hash_datafiles): Likewise. - (ask_for_detached_datafile): Likewise. - -2003-04-10 Werner Koch <wk@gnupg.org> - - * passphrase.c (read_passphrase_from_fd): Do a dummy read if the - agent is to be used. Noted by Ingo Klöcker. - (agent_get_passphrase): Inhibit caching when we have no - fingerprint. This is required for key generation as well as for - symmetric only encryption. - - * passphrase .c (agent_get_passphrase): New arg CANCELED. - (passphrase_to_dek): Ditto. Passed to above. Changed all - callers to pass NULL. - * seckey-cert.c (do_check): New arg CANCELED. - (check_secret_key): Terminate loop when canceled. - - * keyedit.c (change_passphrase): Pass ERRTEXT untranslated to - passphrase_to_dek and translate where appropriate. - * seckey-cert.c (check_secret_key): Ditto. - * keygen.c (ask_passphrase): Ditto. - * passphrase.c (agent_get_passphrase): Translate the TRYAGAIN_TEXT. - Switch the codeset to utf-8. - -2003-04-09 Werner Koch <wk@gnupg.org> - - * decrypt.c (decrypt_messages): Fixed error handling; the function - used to re-loop with same file after an error. Reported by Joseph - Walton. - -2003-04-08 David Shaw <dshaw@jabberwocky.com> - - * main.h, g10.c (main), import.c (parse_import_options, - fix_pks_corruption): It's really PKS corruption, not HKP - corruption. Keep the old repair-hkp-subkey-bug command as an - alias. - - * g10.c (main): Rename --no-version to --no-emit-version for - consistency. Keep --no-version as an alias. - -2003-04-04 David Shaw <dshaw@jabberwocky.com> - - * pkclist.c (algo_available): PGP 8 can use the SHA-256 hash. - - * sign.c (sign_file, clearsign_file, sign_symencrypt_file): Remove - unused code. - -2003-04-01 Werner Koch <wk@gnupg.org> - - * mainproc.c (check_sig_and_print): Add primary key fpr to VALIDSIG - status. - -2003-03-24 David Shaw <dshaw@jabberwocky.com> - - * keydb.h: Err on the side of making an unknown signature a SIG - rather than a CERT. - - * import.c (delete_inv_parts): Discard any key signatures that - aren't key types (i.e. 0x00, 0x01, etc.) - - * g10.c (main): Add deprecated option warning for - --list-ownertrust. Add --compression-algo alias for - --compress-algo. Change --version output strings to match - "showpref" strings, and make translatable. - - * status.c (do_get_from_fd): Accept 'y' as well as 'Y' for - --command-fd boolean input. - - * trustdb.c: Fix typo (DISABLE_REGEXP -> DISABLE_REGEX) - - * keyedit.c (show_key_with_all_names_colon): Show no-ks-modify - flag. - -2003-03-11 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), keyserver.c (kopts): Add "try-dns-srv" - keyserver option. Defaults to on. - - * passphrase.c (agent_get_passphrase): Fix memory leak with - symmetric messages. Fix segfault with symmetric messages. Fix - incorrect prompt with symmetric messages. - -2003-03-10 Werner Koch <wk@gnupg.org> - - * compress.c (init_uncompress): Use a 15 bit window size so that - the output of implementations which don't run for PGP 2 - compatibility won't get garbled. - -2003-03-04 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (validate_keys): Mask the ownertrust when building the - list of fully valid keys so that disabled keys are still counted - in the web of trust. - (get_ownertrust_with_min): Do the same for the minimum ownertrust - calculation. - - * parse-packet.c (dump_sig_subpkt): Show the notation names for - not-human-readable notations. Fix cosmetic off-by-one length - counter. - - * options.skel: Add explantion and commented-out - "no-mangle-dos-filenames". - - * mainproc.c (proc_encrypted): Make string translatable. - - * keyserver.c (keyserver_spawn): Quote ':', '%', and any 8-bit - characters in the uid strings sent to the keyserver helper. - - * keyring.c (keyring_rebuild_cache): Lock the keyring while - rebuilding the signature caches to prevent another gpg from - tampering with the temporary copy. - - * keygen.c (keygen_set_std_prefs): Include AES192 and AES256 in - default prefs. - - * keyedit.c (show_prefs): Make strings translatable. - - * keydb.c: Double the maximum number of keyrings to 40. - - * gpgv.c (main): Fix bug #113 - gpgv should accept the - --ignore-time-conflict option. - - * g10.c (main): --openpgp disables --pgpX. Double the amount of - secure memory to 32k (keys are getting bigger these days). - - * Makefile.am: Makefile.am: Use @CAPLIBS@ to link in -lcap if we - are using capabilities. - -2003-02-26 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_spawn): Include various pieces of - information about the key in the data sent to the keyserver - helper. This allows the helper to use it in instructing a remote - server which may not have any actual OpenPGP smarts in parsing - keys. - - * main.h, export.c (export_pubkeys_stream, do_export_stream): Add - ability to return only the first match in an exported keyblock for - keyserver usage. This should be replaced at some point with a - more flexible solution where each key can be armored seperately. - -2003-02-22 David Shaw <dshaw@jabberwocky.com> - - * sign.c (sign_file): Do not push textmode filter onto an unopened - IOBUF (segfault). Noted by Marcus Brinkmann. Push and - reinitialize textmode filter for each file in a multiple file - list. - - * packet.h, getkey.c (fixup_uidnode), keyedit.c (show_prefs): Set - and show the keyserver no-modify flag. - - * keygen.c (add_keyserver_modify): New. - (keygen_upd_std_prefs): Call it here. - (keygen_set_std_prefs): Accept "ks-modify" and "no-ks-modify" as - prefs to set and unset keyserver modify flag. - - * g10.c (main): Accept "s1" in addition to "idea" to match the - other ciphers. - - * main.h, misc.c (idea_cipher_warn): We don't need this if IDEA - has been disabled. - -2003-02-21 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (keygen_set_std_prefs): Don't put AES or CAST5 in - default prefs if they are disabled. - - * g10.c (main): Use 3DES instead of CAST5 if we don't have CAST5 - support. Use 3DES for the s2k cipher in --openpgp mode. - (print_mds): #ifdef all of the optional digest algorithms. - -2003-02-12 David Shaw <dshaw@jabberwocky.com> - - * keydb.h, getkey.c (classify_user_id, classify_user_id2): Make - 'exact' a per-desc item. Merge into one function since - 'force_exact' is no longer needed. - (key_byname): Use new classify_user_id function, and new exact - flag in KEYDB_SEARCH_DESC. - - * keyring.h, keyring.c (keyring_search): Return an optional index - to show which KEYDB_SEARCH_DESC was the matching one. - - * keydb.h, keydb.c (keydb_search): Rename to keydb_search2, and - pass the optional index to keyring_search. Add a macro version of - keydb_search that calls this new function. - - * export.c (do_export_stream): If the keyid! syntax is used, - export only that specified key. If the key in question is a - subkey, export the primary plus that subkey only. - -2003-02-11 David Shaw <dshaw@jabberwocky.com> - - * exec.c (set_exec_path): Add debugging line. - - * g10.c (print_hex, print_mds): Print long hash strings a lot - neater. This assumes at least an 80-character display, as there - are a few other similar assumptions here and there. Users who - need unformatted hashes can still use with-colons. Check that - SHA384 and 512 are available before using them as they are no - longer always available. - - * Makefile.am: Use a local copy of libexecdir along with @PACKAGE@ - as GNUPG_LIBEXECDIR so it can be easily overridden at make time. - -2003-02-04 David Shaw <dshaw@jabberwocky.com> - - * armor.c (parse_hash_header, armor_filter): Accept the new SHAs - in the armor Hash: header. - - * g10.c (print_hex): Print long hash strings a little neater. - (print_mds): Add the new SHAs to the hash list. - -2003-02-02 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_revuid): Properly handle a nonselfsigned uid on - a v4 key (treat as a v4 revocation). - - * import.c (print_import_check): Do not re-utf8 convert user IDs. - -2003-01-27 David Shaw <dshaw@jabberwocky.com> - - * mainproc.c (list_node): Show signature expiration date in - with-colons sig records. - - * keylist.c (list_keyblock_colon), mainproc.c (list_node): Show - trust sig information in with-colons sig records. - -2003-01-16 David Shaw <dshaw@jabberwocky.com> - - * g10.c (add_group): Trim whitespace after a group name so it does - not matter where the user puts the = sign. - - * options.skel: Comment out the first three lines in case someone - manually copies the skel file to their homedir. - - * sign.c (clearsign_file): Only use pgp2mode with v3 keys and - MD5. This matches what we do when decoding such messages and - prevents creating a message (v3+RIPEMD/160) that we can't verify. - - * sig-check.c (signature_check2): Use G10ERR_GENERAL as the error - for signature digest conflict. BAD_SIGN implies that a signature - was checked and we may try and print out a user ID for a key that - doesn't exist. - -2003-01-15 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (init_trustdb, get_validity): Don't use a changed - trust model to indicate a dirty trustdb, and never auto-rebuild a - dirty trustdb with the "always" trust model. - - * g10.c (add_group): Last commit missed the \t ;) - -2003-01-14 David Shaw <dshaw@jabberwocky.com> - - * packet.h, parse-packet.c (setup_user_id), free-packet.c - (free_user_id), keydb.h, keyid.c (namehash_from_uid): New function - to rmd160-hash the contents of a user ID packet and cache it in - the uid object. - - * keylist.c (list_keyblock_colon): Use namehash in field 8 of - uids. Show dates for creation (selfsig date), and expiration in - fields 6 and 7. - - * trustdb.c (get_validity, get_validity_counts, update_validity): - Use new namehash function rather than hashing it locally. - -2003-01-14 Werner Koch <wk@gnupg.org> - - * g10.c (add_group): Fixed group parsing to allow more than one - delimiter in a row and also allow tab as delimiter. - -2003-01-12 David Shaw <dshaw@jabberwocky.com> - - * tdbio.c (tdbio_set_dbname): Fix assertion failure with - non-fully-qualified trustdb names. - -2003-01-11 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (get_validity_info, get_ownertrust_info, - trust_letter): Simplify by returning a ? for error directly. - - * keyedit.c (show_key_with_all_names): Use get_validity_string and - get_ownertrust_string to show full word versions of trust - (i.e. "full" instead of 'f'). - - * trustdb.h, trustdb.c (get_ownertrust_string, - get_validity_string): Same as get_ownertrust_info, and - get_validity_info, except returns a full string. - - * trustdb.c (get_ownertrust_with_min): New. Same as - 'get_ownertrust' but takes the min_ownertrust value into account. - -2003-01-10 David Shaw <dshaw@jabberwocky.com> - - * armor.c (armor_filter): Comment about PGP's end of line tab - problem. - - * trustdb.h, trustdb.c (trust_letter): Make - static. (get_ownertrust_info, get_validity_info): Don't mask the - trust level twice. - - * trustdb.h, gpgv.c, trustdb.c (get_validity, get_validity_info), - keylist.c (list_keyblock_colon), keyedit.c - (show_key_with_all_names_colon, menu_revuid): Pass a user ID in - rather than a namehash, so we only have to do the hashing in one - place. - - * packet.h, pkclist.c (build_pk_list), free-packet.c - (release_public_key_parts): Remove unused namehash element for - public keys. - -2003-01-07 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (keygen_set_std_prefs): Warn when setting an IDEA - preference when IDEA is not available. - -2003-01-06 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (get_validity_info): 'd' for disabled is not a - validity value any more. - - * packet.h, tdbio.h, tdbio.c (tdbio_read_record, - tdbio_write_record), trustdb.c (update_validity): Store temporary - full & marginal counts in the trustdb. - (clear_validity, get_validity_counts): Return and clear temp - counts. - (store_validation_status): Keep track of which keyids have been - stored. - (validate_one_keyblock, validate_key_list): Use per-uid copies of - the full & marginal counts so they can be recalled for multiple - levels. - (validate_keys): Only use unused keys for each new round. - (reset_unconnected_keys): Rename to reset_trust_records, and only - skip specifically excluded records. - - * keylist.c (print_capabilities): Show 'D' for disabled keys in - capabilities section. - - * trustdb.c (is_disabled): Remove incorrect comment. - -2003-01-03 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_one): Only do the work to create the status - display for interactive import if status is enabled. - - * keyring.c (keyring_search): skipfnc didn't work properly with - non-keyid searches. Noted by Stefan Bellon. - - * getkey.c (merge_selfsigs_main): Remove some unused code and make - sure that the pk selfsigversion member accounts for 1F direct - sigs. - -2003-01-02 Werner Koch <wk@gnupg.org> - - * keydb.c (keydb_add_resource): Don't assume that try_make_homedir - terminates but check again for the existence of the directory and - continue then. - * openfile.c (copy_options_file): Print a warning if the skeleton - file has active options. - -2002-12-29 David Shaw <dshaw@jabberwocky.com> - - * getkey.c (merge_selfsigs_main), main.h, sig-check.c - (check_key_signature2): Pass the ultimately trusted pk directly to - check_key_signature2 to avoid going through the key selection - mechanism. This prevents a deadly embrace when two keys without - selfsigs each sign the other. - -2002-12-27 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_refresh): Don't print the "refreshing..." - line if there are no keys to refresh or if there is no keyserver - set. - - * getkey.c (merge_selfsigs_main): Any valid user ID should make a - key valid, not just the last one. This also fixes Debian bug - #174276. - -2002-12-27 Stefan Bellon <sbellon@sbellon.de> - - * import.c (print_import_check): Changed int to size_t. - -2002-12-27 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (keyedit_menu, menu_revuid): Add "revuid" feature to - revoke a user ID. This is the same as issuing a revocation for - the self-signature, but a much simpler interface to do it. - -2002-12-26 David Shaw <dshaw@jabberwocky.com> - - * keydb.h, getkey.c (key_byname): Flag to enable or disable - including disabled keys. Keys specified via keyid (i.e. 0x...) - are always included. - - * getkey.c (get_pubkey_byname, get_seckey_byname2, - get_seckey_bynames), keyedit.c (keyedit_menu, menu_addrevoker): - Include disabled keys in these functions. - - * pkclist.c (build_pk_list): Do not include disabled keys for -r - or the key prompt. Do include disabled keys for the default key - and --encrypt-to. - - * trustdb.h, trustdb.c (is_disabled): New skipfnc for skipping - disabled keys. - - * gpgv.c (is_disabled): Stub. - - * keygen.c (keygen_add_key_expire): Properly handle updating a key - expiration to a no-expiration value. - - * keyedit.c (enable_disable_key): Comment. - - * import.c (import_one): When in interactive mode and --verbose, - don't repeat some key information twice. - -2002-12-22 Timo Schulz <ts@winpt.org> - - * import.c (print_import_check): New. - (import_one): Use it here. - Use merge_keys_and_selfsig in the interactive mode to avoid - wrong key information. - * status.h: Add new status code. - * status.c: Ditto. - -2002-12-13 David Shaw <dshaw@jabberwocky.com> - - * pkclist.c (do_we_trust): Tweak language to refer to the "named - user" rather than "owner". Noted by Stefan Bellon. - - * trustdb.h, trustdb.c (trustdb_pending_check): New function to - check if the trustdb needs a check. - - * import.c (import_keys_internal): Used here so we don't rebuild - the trustdb if it is still clean. - (import_one, chk_self_sigs): Only mark trustdb dirty if the key - that is being imported has any sigs other than self-sigs. - Suggested by Adrian von Bidder. - - * options.skel: Include the required '=' sign in the sample - 'group' option. Noted by Stefan Bellon. - - * import.c (chk_self_sigs): Don't try and check a subkey as if it - was a signature. - -2002-12-11 David Shaw <dshaw@jabberwocky.com> - - * tdbio.c (tdbio_read_record, tdbio_write_record): Compact the - RECTYPE_TRUST records a bit. - - * g10.c (main): Comment out --list-trust-path until it can be - implemented. - - * import.c (import_one): Warn when importing an Elgamal primary - that this may take some time (to verify self-sigs). - (chk_self_sigs): Try and cache all self-sigs so the keyblock is - written to the keyring with a good rich cache. - - * keygen.c (ask_algo): Make the Elgamal sign+encrypt warning - stronger, and remove the RSA sign+encrypt warning. - -2002-12-06 Stefan Bellon <sbellon@sbellon.de> - - * options.h: Fixed typo (mangle_dos_names instead of - mangle_dos_filenames). - -2002-12-05 Werner Koch <wk@gnupg.org> - - * g10.c: New options --[no-]mangle-dos-filenames. - * options.h (opt): Added mangle-dos-filenames. - * openfile.c (open_outfile) [USE_ONLY_8DOT3]: Truncate the - filename only when this option is set; this is the default. - -2002-12-04 David Shaw <dshaw@jabberwocky.com> - - * main.h, keyedit.c, keygen.c: Back out previous (2002-12-01) - change. Minimal isn't always best. - - * sign.c (update_keysig_packet): Use the current time rather then - a modification of the original signature time. Make sure that - this doesn't cause a time warp. - - * keygen.c (keygen_add_key_expire): Properly handle a key - expiration date in the past (use a duration of 0). - - * keyedit.c (menu_expire): Use update_keysig_packet so any sig - subpackets are maintained during the update. - - * build-packet.c (build_sig_subpkt): Mark sig expired or unexpired - when the sig expiration subpacket is added. - (build_sig_subpkt_from_sig): Handle making an expiration subpacket - from a sig that has already expired (use a duration of 0). - - * packet.h, sign.c (update_keysig_packet), keyedit.c - (menu_set_primary_uid, menu_set_preferences): Add ability to issue - 0x18 subkey binding sigs to update_keysig_packet and change all - callers. - - * trustdb.c (validate_keys): Show trust parameters when building - the trustdb, and make sure that the version record update was - successful. - (init_trustdb): If the current parameters aren't what was used for - building the trustdb, the trustdb is invalid. - - * tbio.c (tdbio_db_matches_options): Update to work with new - trustdbs. - -2002-12-03 David Shaw <dshaw@jabberwocky.com> - - * tdbio.h, tdbio.c (tdbio_read_record, tdbio_write_record): Store - trust model in the trustdb version record. - (tdbio_update_version_record): New function to update version - record values during a trustdb check or update. - (tdbio_dump_record): Show trust model in dump. - - * trustdb.c (validate_keys): Call tdbio_update_version_record on - success so that the correct options are stored in the trustdb. - - * options.h: rearrange trust models so that CLASSIC is 0 and - OPENPGP is 1. - - * options.h, g10.c (main), encode.c (write_pubkey_enc_from_list), - pkclist.c (algo_available), revoke.c (gen_revoke): Add --pgp8 - mode. This is basically identical to --pgp7 in all ways except - that signing subkeys, v4 data sigs (including expiration), and SK - comments are allowed. - - * getkey.c (finish_lookup): Comment. - - * main.h, keylist.c (reorder_keyblock), keyedit.c (keyedit_menu): - Reorder user ID display in the --edit-key menu to match that of - the --list-keys display. - - * g10.c (add_notation_data): Fix initialization. - -2002-12-01 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_expire): Don't lose key flags when changing the - expiration date of a subkey. This is not the most optimal - solution, but it is minimal change on the stable branch. - - * main.h, keygen.c (do_copy_key_flags): New function to copy key - flags, if any, from one sig to another. - (do_add_key_expire): New function to add key expiration to a sig. - (keygen_copy_flags_add_expire): New version of - keygen_add_key_expire that also copies key flags. - (keygen_add_key_flags_and_expire): Use do_add_key_expire. - - * import.c (fix_hkp_corruption): Comment. - -2002-11-25 Stefan Bellon <sbellon@sbellon.de> - - * plaintext.c (handle_plaintext) [__riscos__]: If nooutput is set, - no filetype is needed obviously. - -2002-11-24 David Shaw <dshaw@jabberwocky.com> - - * main.h, misc.c (default_cipher_algo, default_compress_algo): - New. Return the default algorithm by trying - --cipher-algo/--compress-algo, then the first item in the pref - list, then s2k-cipher-algo or ZIP. - - * sign.c (sign_file, sign_symencrypt_file), encode.c - (encode_simple, encode_crypt): Call default_cipher_algo and - default_compress_algo to get algorithms. - - * g10.c (main): Allow pref selection for compress algo with - --openpgp. - - * mainproc.c (proc_encrypted): Use --s2k-digest-algo for - passphrase mangling rather than --digest-algo. - - * sign.c (hash_for): If --digest-algo is not set, but - --personal-digest-preferences is, then use the first hash - algorithm in the personal list. If the signing algorithm is DSA, - then use the first 160-bit hash algorithm in the personal list. - If --pgp2 is set and it's a v3 RSA key, use MD5. - - * g10.c (main), keydb.c (keydb_add_resource, - keydb_locate_writable): Rename --default-keyring as - --primary-keyring. Stefan wins the naming contest. - -2002-11-23 David Shaw <dshaw@jabberwocky.com> - - * g10.c (add_notation_data): Disallow notation names that do not - contain a '@', unless --expert is set. This is to help prevent - people from polluting the (as yet unused) IETF namespace. - - * main.h: Comments about default algorithms. - - * photoid.c (image_type_to_string): Comments about 3-letter file - extensions. - - * encode.c (encode_simple), passphrase.c (passphrase_to_dek), - sign.c (sign_symencrypt_file): Use --s2k-digest-algo for - passphrase mangling rather than --digest-algo. - -2002-11-21 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (keygen_set_std_prefs): Properly handle an empty - preference string. - - * misc.c (string_to_compress_algo): "none" is a bad choice since - it conflicts with the "none" in setpref. - -2002-11-14 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Allow compression algorithm names as the argument - to --compress-algo. The old algorithm names still work for - backwards compatibility. - - * misc.c (string_to_compress_algo): Allow "none" as an alias for - "uncompressed". - -2002-11-13 Stefan Bellon <sbellon@sbellon.de> - - * getkey.c (get_pubkey_byfprint_fast): Fixed type incompatibility, - was unsigned char instead of byte. - -2002-11-13 David Shaw <dshaw@jabberwocky.com> - - * encode.c (encode_simple): Make sure that files larger than about - 4G use partial length encoding. This is required because OpenPGP - allows only for 32 bit length fields. From Werner on stable - branch. - - * getkey.c (get_pubkey_direct): Renamed to... - (get_pubkey_fast): this and made extern. - (get_pubkey_byfprint_fast): New. From Werner on stable branch. - - * keydb.h, import.c (import_one): Use get_pubkey_fast instead of - get_pubkey. We don't need a merged key and actually this might - lead to recursions. - (revocation_present): Likewise for search by fingerprint. From - Werner on stable branch. - - * g10.c (main): Try to create the trustdb even for non-colon-mode - list-key operations. This is required because getkey needs to - know whether a a key is ultimately trusted. From Werner on stable - branch. - - * exec.c [__CYGWIN32__]: Keep cygwin separate from Mingw32; - we don't need it here as it behaves more like a Posix system. - From Werner on stable branch. - - * passphrase.c (agent_get_passphrase): Ditto. From Werner on - stable branch. - - * tdbio.c (MY_O_BINARY): Need binary mode with Cygwin. From - Werner on stable branch. - - * g10.c, gpgv.c (main) [__CYGWIN32__]: Don't get the homedir from - the registry. From Werner on stable branch. - - * keyedit.c (show_key_with_all_names_colon): Make --with-colons - --edit display match the validity and trust of --with-colons - --list-keys. - - * passphrase.c (agent_send_all_options): Fix compile warning. - - * keylist.c (list_keyblock_colon): Validity for subkeys should - match that of the primary key, and not that of the last user ID. - - * getkey.c (merge_selfsigs): Revoked/expired/invalid primary keys - carry these facts onto all their subkeys, but only after the - subkey has a chance to be marked valid. This is to fix an - incorrect "invalid public key" error verifying a signature made by - a revoked signing subkey, with a valid unrevoked primary key. - -2002-11-09 Werner Koch <wk@gnupg.org> - - * passphrase.c (agent_send_all_options): Use tty_get_ttyname to - get the default ttyname. - -2002-11-07 David Shaw <dshaw@jabberwocky.com> - - * keyring.h, keyring.c (keyring_register_filename): Return the - pointer if a given keyring is registered twice. - - * keydb.h, keydb.c (keydb_add_resource): Use flags to indicate a - default keyring. - (keydb_locate_writable): Prefer the default keyring if possible. - - * g10.c (main): Add --default-keyring option. - -2002-11-06 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), trustdb.c (ask_ownertrust): Add - --force-ownertrust option for debugging purposes. This allows - setting a whole keyring to a given trust during an - --update-trustdb. Not for normal use - it's just easier than - hitting "4" all the time to test a large trustdb. - - * pubkey-enc.c (get_session_key): With hidden recipients or try a - given passphrase against all secret keys rather than trying all - secret keys in turn. Don't if --try-all-secrets or --status-fd is - enabled. - - * passphrase.c (passphrase_to_dek): Mode 1 means do a regular - passphrase query, but don't prompt with the key info. - - * seckey-cert.c (do_check, check_secret_key): A negative ask count - means to enable passphrase mode 1. - - * keydb.h, getkey.c (enum_secret_keys): Add flag to include - secret-parts-missing keys (or not) in the list. - -2002-11-05 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_search_prompt): When --with-colons is - enabled, don't try and fit the search output to the screen size - - just dump the whole list. - -2002-11-04 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_search_prompt): When --with-colons is - enabled, just dump the raw keyserver protocol to stdout and don't - print the menu. - - * keyserver.c (show_prompt): Don't show a prompt when command-fd - is being used. - - * trustdb.c (trust_model_string, check_trustdb, update_trustdb, - validate_one_keyblock): It's not clear what a trustdb rebuild or - check means with a trust model other than "classic" or "openpgp", - so disallow this. - -2002-11-03 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main): Add --trust-model option. Current - models are "openpgp" which is classic+trustsigs, "classic" which - is classic only, and "always" which is the same as the current - option --always-trust (which still works). Default is "openpgp". - - * trustdb.c (validate_one_keyblock): Use "openpgp" trust model to - enable trust sigs. - - * gpgv.c (main), mainproc.c (check_sig_and_print), pkclist.c - (do_we_trust, do_we_trust_pre, check_signatures_trust): Use new - --trust-model option in place of --always-trust. - - * keyedit.c (sign_mk_attrib, trustsig_prompt, sign_uids, - keyedit_menu): Prompt for and create a trust signature with - "tsign". This is functional, but needs better UI text. - - * build-packet.c (build_sig_subpkt): Able to build trust and - regexp subpackets. - - * pkclist.c (do_edit_ownertrust): Comment. - -2002-11-02 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (set_one_pref, keygen_set_std_prefs): Allow using the - full algorithm name (CAST5, SHA1) rather than the short form (S3, - H2). - - * main.h, keygen.c (keygen_get_std_prefs), keyedit.c - (keyedit_menu): Return and use a fake uid packet rather than a - string since we already have a nice parser/printer in - keyedit.c:show_prefs. - - * main.h, misc.c (string_to_compress_algo): New. - -2002-11-01 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Add --no-throw-keyid. - - * keydb.h, encode.c (write_pubkey_enc_from_list), g10.c (main), - pkclist.c (build_pk_list): Add --hidden-recipient (-R) and - --hidden-encrypt-to, which do a single-user variation on - --throw-keyid. The "hide this key" flag is carried in bit 0 of - the pk_list flags field. - - * keyserver.c (parse_keyrec): Fix shadowing warning. - -2002-10-31 Stefan Bellon <sbellon@sbellon.de> - - * compress.c (init_compress) [__riscos__]: Use - riscos_load_module() to load ZLib module. - - * g10.c (main) [__riscos__]: Renames due to changes in riscos.c - (e.g. prefixes all RISC OS specific functions with riscos_*). - * photoid.c (show_photos) [__riscos__]: Likewise. - * signal.c (got_fatal_signal) [__riscos__]: Likewise. - - * trustdb.c (check_regexp) [__riscos__]: Branch to RISC OS RegEx - handling. - -2002-10-31 David Shaw <dshaw@jabberwocky.com> - - * build-packet.c (do_plaintext), encode.c (encode_sesskey, - encode_simple, encode_crypt), sign.c (write_plaintext_packet): Use - wipememory() instead of memset() to wipe sensitive memory as the - memset() might be optimized away. - -2002-10-30 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (check_regexp): Modern regexps require REG_EXTENDED. - -2002-10-29 David Shaw <dshaw@jabberwocky.com> - - * packet.h, trustdb.h, trustdb.c (trust_string): New. Return a - string like "fully trusted", "marginally trusted", etc. - (get_min_ownertrust): New. Return minimum ownertrust. - (update_min_ownertrust): New. Set minimum ownertrust. - (check_regexp): New. Check a regular epression against a user ID. - (ask_ownertrust): Allow specifying a minimum value. - (get_ownertrust_info): Follow the minimum ownertrust when - returning a letter. - (clear_validity): Remove minimum ownertrust when a key becomes - invalid. - (release_key_items): Release regexp along with the rest of the - info. - (validate_one_keyblock, validate_keys): Build a trust sig chain - while validating. Call check_regexp for regexps. Use the minimum - ownertrust if the user does not specify a genuine ownertrust. - - * pkclist.c (do_edit_ownertrust): Only allow user to select a - trust level greater than the minimum value. - - * parse-packet.c (can_handle_critical): Can handle critical trust - and regexp subpackets. - - * trustdb.h, trustdb.c (clear_ownertrusts), delkey.c - (do_delete_key), import.c (import_one): Rename clear_ownertrust to - clear_ownertrusts and have it clear the min_ownertrust value as - well. - - * keylist.c (list_keyblock_print): Indent uid to match pub and - sig. - - * keyedit.c (print_and_check_one_sig, show_key_and_fingerprint, - menu_addrevoker), keylist.c (list_keyblock_print, - print_fingerprint): Show "T" or the trust depth for trust - signatures, and add spaces to some strings to make room for it. - - * packet.h, parse-packet.c (dump_sig_subpkt, parse_one_sig_subpkt, - parse_signature): Parse trust signature values. - - * tdbio.h, tdbio.c (tdbio_read_record, tdbio_write_record): - Reserve a byte for the minimum ownertrust value (for use with - trust signatures). - -2002-10-29 Stefan Bellon <sbellon@sbellon.de> - - * build-packet.c (calc_plaintext, do_plaintext): Removed RISC OS - specific filetype parts (it's now done in make_basename()). - - * plaintext.c (handle_plaintext): Tidied up RISC OS specific - filetype parts. - - * encode.c (encode_simple, encode_crypt): Added argument to - make_basename() call. - - * sign.c (write_plaintext_packet): Added argument to - make_basename() call. - -2002-10-28 Stefan Bellon <sbellon@sbellon.de> - - * build-packet.c (calc_plaintext, do_plaintext): Added filetype - handling for RISC OS' file types. - - * plaintext.c (handle_plaintext) [__riscos__]: Added filetype - handling for RISC OS' file types. - -2002-10-23 David Shaw <dshaw@jabberwocky.com> - - * main.h, import.c (sec_to_pub_keyblock, import_secret_one, - parse_import_options), g10.c (main): New import-option - "convert-sk-to-pk" to convert a secret key into a public key - during import. It is on by default. - -2002-10-23 Werner Koch <wk@gnupg.org> - - * pubkey-enc.c (get_it): Fix segv, test for revoked only when PK - has been assigned. - -2002-10-18 Timo Schulz <ts@winpt.org> - - * keylist.c: (print_pubkey_info): New. - (print_seckey_info): New. - * main.h: Prototypes for the new functions. - * delkey.c (do_delete_key): Use it here. - * revoke.c (gen_desig_revoke): Ditto. - -2002-10-17 Werner Koch <wk@gnupg.org> - - * pkclist.c (do_edit_ownertrust): Show all user IDs. This should - be enhanced to also show the current trust level. Suggested by - Florian Weimer. - -2002-10-17 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Handle --strict and --no-strict from the command - line before the options file is loaded. - -2002-10-15 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Disable --textmode when encrypting (symmetric or - pk) in --pgp2 mode as PGP 2 can't handle the unknown length - literal packet. Reported by Michael Richardson. - -2002-10-14 David Shaw <dshaw@jabberwocky.com> - - * keyserver-internal.h, keyserver.c (print_keyrec, parse_keyrec, - show_prompt, keyserver_search_prompt, keyserver_spawn): Go to - version 1 of the keyserver protocol. This is a better design, - similar to --with-colons, that allows for keys with multiple user - IDs rather than using multiple keys. It also matches the machine - readable pksd format. Also use a prettier --search-keys listing - format that can fill different size windows (currently set at 24 - lines). - -2002-10-12 Werner Koch <wk@gnupg.org> - - * keygen.c (print_status_key_created): New. - (do_generate_keypair): Use it to print the fingerprint. - (generate_subkeypair): Likewise. - -2002-10-11 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_addrevoker): Properly back out if the signature - fails. Also, do not allow appointing the same revoker twice, and - report ALREADY_SIGNED if the user tries it. - -2002-10-07 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_keys_internal): Missed one s/inp/inp2/. - - * keylist.c (print_capabilities): Properly indicate per-key - capabilities of sign&encrypt primary keys that have - secret-parts-missing (i.e. no capabilities at all) - - * mainproc.c (symkey_decrypt_sesskey): Fix compiler warning. - -2002-10-04 David Shaw <dshaw@jabberwocky.com> - - * getkey.c (get_pubkey_direct): Don't cache keys retrieved via - this function as they may not have all their fields filled in. - - * sig-check.c (signature_check2): Use new is_primary flag to check - rather than comparing main_keyid with keyid as this still works in - the case of a not fully filled in pk. - -2002-10-04 Werner Koch <wk@gnupg.org> - - * import.c (import_keys_internal): s/inp/inp2/ to avoid shadowing - warning. - - * passphrase.c (agent_get_passphrase): Fixed signed/unsigned char - problem in %-escaping. Noted by Ingo Klöcker. - -2002-10-03 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main): Add --strict and --no-strict to switch - the log_warning severity level from info to error. - - * keylist.c (print_capabilities): Secret-parts-missing keys should - show that fact in the capabilities, and only primary signing keys - can certify other keys. - - * packet.h, parse_packet.c (parse_key): Add is_primary flag for - public keys (it already exists for secret keys). - -2002-10-02 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_secret_one): Check for an illegal (>110) - protection cipher when importing a secret key. - - * keylist.c (list_keyblock_print): Show a '#' for a - secret-parts-missing key. - - * parse_packet.c (parse_key): Some comments. - - * revoke.c (gen_revoke): Remove some debugging code. - - * trustdb.c (verify_own_keys): Make trusted-key a non-deprecated - option again. - - * seckey-cert.c (do_check): Don't give the IDEA warning unless the - cipher in question is in fact IDEA. - -2002-10-01 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_one): Make sure that a newly imported key - starts with a clean ownertrust. - -2002-10-01 Werner Koch <wk@gnupg.org> - - * getkey.c (get_pubkey_direct): New. - (merge_selfsigs_main): Use it here to look for an ultimately - trusted key. Using the full get_pubkey might lead to an - infinitive recursion. - -2002-09-29 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (parse_keyserver_uri): Force the keyserver URI - scheme to lowercase to be case-insensitive. - -2002-09-28 David Shaw <dshaw@jabberwocky.com> - - * export.c (do_export_stream): Comment. - - * sig-check.c (check_key_signature2): Properly handle a - non-designated revocation import. - -2002-09-26 Werner Koch <wk@gnupg.org> - - * g10.c (set_homedir): New. Changed all direct assignments to use - this. - * gpgv.c (set_homedir): Ditto. - -2002-09-25 David Shaw <dshaw@jabberwocky.com> - - * Makefile.am: Link gpg with EGDLIBS (i.e. NETLIBS) as EGD uses - sockets. Remove the old NETLIBS variable since the keyserver - stuff is no longer internal. - -2002-09-24 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_keys_stream): Fix compiler type warning. - - * keyring.c (keyring_rebuild_cache), sig-check.c - (check_key_signature2), import.c (import, chk_self_sigs): Minor - language cleanups. - -2002-09-23 Stefan Bellon <sbellon@sbellon.de> - - * main.h: Introduced fast-import as import option. Removed - fast as separate option from prototypes. - * import.c (parse_import_options): Added fast-import option. - (import_*): Removed fast as separate option. - * g10.c (main): Added option fast-import, removed old fast - as separate argument. - * keyserver.c (keyserver_spawn): Removed old fast as separate - argument. - -2002-09-22 Stefan Bellon <sbellon@sbellon.de> - - * import.c (import_keys, import_keys_stream, - import_keys_internal): Added trustdb update/check to key import if - not fast-import and interactive set/no-auto-check-trustdb unset. - Avoided function clone by introducing import_keys_internal. - -2002-09-19 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_spawn): Properly handle line truncation. - Don't leak memory (~10-20 bytes) on searches. - (keyserver_search_prompt): Cleanup. - - * keylist.c (list_keyblock_colon): Show 1F direct key signatures - in --with-colons listing. - -2002-09-16 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_addrevoker): The direct key signature for - revocation keys must be at least v4 to carry the revocation key - subpacket. Add a PGP 2.x warning for revocation keys. - -2002-09-14 David Shaw <dshaw@jabberwocky.com> - - * g10.c (check_permissions): Rearrange strings to make translating - easier (don't incorporate string parts). - - * keyedit.c (sign_uids): Make strings translatable. - - * sig-check.c (check_key_signature2): Make string translatable. - -2002-09-13 David Shaw <dshaw@jabberwocky.com> - - * getkey.c (check_revocation_keys): Move.... - * main.h, sig-check.c (check_revocation_keys): to here. Also - return the signature_check error code rather than 0/1 and cache - the sig result. - - * sig-check.c (check_key_signature2): Divert to - check_revocation_keys if a revocation sig is made by someone other - than the pk owner. - - * getkey.c (merge_selfsigs_main): Tidy. - -2002-09-13 Werner Koch <wk@gnupg.org> - - * g10.c (main) [__MINGW32__]: Activate oLoadExtension. - -2002-09-12 David Shaw <dshaw@jabberwocky.com> - - * Makefile.am, hkp.c, hkp.h, keyserver.c (keyserver_work): Remove - internal HKP support. - - * keyserver.c (keyserver_spawn): Remove whitespace after keyserver - commands. - -2002-09-10 David Shaw <dshaw@jabberwocky.com> - - * exec.c (expand_args): Remove loop left over from earlier - implementation. - (exec_write): Missed one tick. - -2002-09-10 Werner Koch <wk@gnupg.org> - - * g10.c, options.h: Removed option --emulate-checksum-bug. - * misc.c (checksum_u16_nobug): Removed. - (checksum_u16): Removed the bug emulation. - (checksum_mpi): Ditto. - (checksum_mpi_counted_nbits): Removed and replaced all calls - with checksum_mpi. - - * parse-packet.c (read_protected_v3_mpi): New. - (parse_key): Use it here to store it as an opaque MPI. - * seckey-cert.c (do_check): Changed the v3 unprotection to the new - why to store these keys. - (protect_secret_key): Likewise. - * build-packet.c (do_secret_key): And changed the writing. - - * tdbio.c (tdbio_set_dbname, open_db): Use new macro MY_O_BINARY - to avoid silly ifdefs. - (open_db): Fallback to RDONLY so that gpg may be used from a - RO-medium. - - * encode.c (encode_simple): Make sure we don't use an ESK packet - when we don't have a salt in the S2K. - - * misc.c (pct_expando) <case f>: Make sure that LEN is initialized. - - * exec.c (exec_finish): Use ticks to denote filenames in messages. - (make_tempdir, exec_write): Changed format of messages. - - * keyserver.c (print_keyinfo): Release USERID in on error. - (keyserver_work) [!DISABLE_KEYSERVER_HELPERS]: Exclude the unused - code. - -2002-09-09 Werner Koch <wk@gnupg.org> - - * parse-packet.c (make_attribute_uidname): Add new ar MAX_NAMELEN - for sanity checks. Changed both callers. Limit the size of an %s. - - * options.skel: Comment lock-once out, so that this file does not - change anything when copied to a new home directory. - * openfile.c (try_make_homedir): Don't exit after copying the - option skeleton. - - * options.h: Don't use a comma when declaring variables over more - than one line. - - * mainproc.c (symkey_decrypt_sesskey): Check length of the session - key. - - * hkp.c (dehtmlize): Use ascii_tolower to protect against weird - locales. Cast the argument for isspace for the sake of broken - HP/UXes. - (parse_hkp_index): s/ascii_memcasecmp/ascii_strncasecmp/. - - * g10.c: Removed option --emulate-3des-s2k-bug. - - * passphrase.c (hash_passphrase): Was used here. - - * export.c (parse_export_options) - * keyserver.c (parse_keyserver_options) - * import.c (parse_import_options) - * g10.c (check_permissions): s/ascii_memcasecmp/ascii_strncasecmp/. - -2002-09-09 David Shaw <dshaw@jabberwocky.com> - - * g10.c (add_group): Use '=' to separate group name from group - members. Use a better error message for when no = is found. - - * hkp.c (hkp_export): Use CRLF in headers. - -2002-09-03 David Shaw <dshaw@jabberwocky.com> - - * mainproc.c (print_pkenc_list): Don't increment the error counter - when printing the list of keys a message was encrypted to. This - would make gpg give a non-zero exit code even for completely valid - messages if the message was encrypted to more than one key that - the user owned. - -2002-09-02 Werner Koch <wk@gnupg.org> - - * g10.c (main): Try to set a default character set. Print the - used one in verbosity level 3. - * gpgv.c (main): Try to set a default character set. - - * status.c, status.h (STATUS_IMPORT_OK): New. - * import.c (import_one,import_secret_one): Print new status. - -2002-08-30 David Shaw <dshaw@jabberwocky.com> - - * pkclist.c (build_pk_list): Add new status code to indicate an - untrusted user. This (or a disabled key) fail with "unavailable - pubkey" (G10ERR_UNU_PUBKEY). - - * pkclist.c (build_pk_list): Fail if any recipient keys are - unusable. - - * options.skel: The PGP LDAP keyserver is back. Use MIT keyserver - as a sample rather than cryptnet as cryptnet does not support - searching yet. - - * keyedit.c (show_key_with_all_names): Fix error message - (preferences are userid/selfsig and not key specific). - -2002-08-30 Werner Koch <wk@gnupg.org> - - * pkclist.c (do_we_trust_pre): Changed the wording of a warning. - - * encode.c (encode_simple,encode_crypt): Use new style CTB for - compressssed packets when using MDC. We need to do this so that - concatenated messages are properly decrypted. Old style - compression assumes that it is the last packet; given that we - can't determine the length in advance, the uncompressor does not - know where to start. Actually we should use the new CTB always - but this would break PGP 2 compatibility. - - * parse-packet.c (parse): Special treatment for new style CTB - compressed packets. - - * build-packet.c (do_mdc): Removed. Was not used. - (do_encrypted_mdc): Count in the version number and the MDC packet. - -2002-08-28 David Shaw <dshaw@jabberwocky.com> - - * sig-check.c (do_check_messages, do_check): Show keyid in error - messages. - - * keyserver.c (print_keyinfo): More readable key listings for - --search-keys responses. - -2002-08-26 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (parse_hkp_index, dehtmlize): Move HTML functionality into - new "dehtmlize" function. Remove HTML before trying to parse each - line from the keyserver. If the keyserver provides key type - information in the listing, use it. - -2002-08-23 David Shaw <dshaw@jabberwocky.com> - - * sig-check.c (do_check, do_check_messages): Emit the usual sig - warnings even for cached sigs. This also serves to protect - against missing a sig expiring while cached. - - * getkey.c (merge_selfsigs_main): Don't check UID self-sigs twice. - -2002-08-22 David Shaw <dshaw@jabberwocky.com> - - * import.c (clean_subkeys, chk_self_sigs): Merge clean_subkeys - into chk_self_sigs. This improves efficiency as the same - signatures are not checked multiple times. Clarify when a subkey - is revoked (any revocation signature, even if it is dated before - the binding signature). - - * getkey.c (merge_selfsigs_subkey): Subkey revocation comments. - - * keylist.c (list_one): Stats are only for public key listings. - - * g10.c (main), options.skel: Default should be include-revoked - for keyserver operations. - -2002-08-21 Werner Koch <wk@gnupg.org> - - * import.c (import_print_stats): Print new non_imported counter - which is currently not used because we terminate on errors. - -2002-08-20 David Shaw <dshaw@jabberwocky.com> - - * options.skel: Document no-include-attributes for - keyserver-options. - - * keylist.c, keyedit.c, keyserver.c, sign.c: Some TODOs and - comments. - - * export.c (do_export_stream): Fix noop bug in exporting sensitive - revocation keys. - - * pkclist.c (do_edit_ownertrust): Comment out the option for - showing trust paths until it can be implemented. - -2002-08-19 Werner Koch <wk@gnupg.org> - - * getkey.c (get_user_id_native): Renamed to .. - (get_user_id_printable): this. Filter out all dangerous - characters. Checked all usages. - (get_user_id_string_native): Renamed to.. - (get_user_id_string_printable): this. Filter out all dangerous - characters. Checked all usages. - * keyedit.c (show_basic_key_info): New. - * keylist.c (print_fingerprint): New mode 3. - * import.c (import_one): Use new function to display the user ID. - -2002-08-16 Timo Schulz <ts@winpt.org> - - * g10.c (main): Enable opt.interactive. - - * import.c (import_one): Ask the user if the key shall be - imported when the interactive mode is used. Useful to extract - selected keys from a file. - -2002-08-16 Werner Koch <wk@gnupg.org> - - * seckey-cert.c: Workaround to allow decryption of v3 keys created - with a bug in the mpi_get_secure_buffer. - -2002-08-14 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (parse_hkp_index): Properly handle really large keys - (5 digit key length) in HKP searches. - -2002-08-13 David Shaw <dshaw@jabberwocky.com> - - * encode.c (encode_simple): Fix problem with using compression - algo 2 and symmetric compressed files. - - * encode.c (encode_simple, encode_crypt): If we are not using a - MDC, compress even if a file is already compressed. This is to - help against the chosen ciphertext attack. - - * pkclist.c (select_algo_from_prefs): Fix requested algorithm bug - so the request succeeds even if the requested algorithm is not the - first found. - - * cipher.c (write_header), encode.c (use_mdc, encode_simple, - encode_crypt, encrypt_filter), g10.c (main): Be more eager to use - a MDC. We use a MDC if the keys directly support it, if the keys - list AES (any) or TWOFISH anywhere in the prefs, or if the cipher - chosen does not have a 64 bit blocksize. - -2002-08-08 David Shaw <dshaw@jabberwocky.com> - - * options.skel: Some language tweaks, and remove the - load-extension section for random gatherers. - - * keyring.c (create_tmp_file, rename_tmp_file): Create tmp files - with user-only permissions, but restore the original permissions - if the user has something special set. - - * openfile.c (copy_options_file): Create new options file - (gpg.conf) with user-only permissions. - - * keydb.c (keydb_add_resource): Create new keyrings with user-only - permissions. - - * tdbio.c (tdbio_set_dbname): Create new trustdbs with user-only - permissions. - -2002-08-07 David Shaw <dshaw@jabberwocky.com> - - * sig-check.c (signature_check2): Sanity check that the md has a - context for the hash that the sig is expecting. This can happen - if a onepass sig header does not match the actual sig, and also if - the clearsign "Hash:" header is missing or does not match the - actual sig. - - * keyedit.c (menu_revsig): Properly show a uid is revoked without - restarting gpg. This is Debian bug 124219, though their supplied - patch will not do the right thing. - - * main.h, tdbio.c (tdbio_set_dbname), misc.c (removed - check_permissions), keydb.c (keydb_add_resource), g10.c (main, - check_permissions): Significant reworking of the permission check - mechanism. The new behavior is to check everything in the homedir - by checking the homedir itself. If the user wants to put - (possibly shared) keyrings outside the homedir, they are not - checked. The options file and any extension files are checked - wherever they are, as well as their enclosing directories. This - is Debian bug 147760. - -2002-08-06 Stefan Bellon <sbellon@sbellon.de> - - * g10.c (main): Use of EXTSEP_S in new gpg.conf string. - * openfile.c (copy_options_file): Ditto. - -2002-08-06 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), mainproc.c (proc_encrypted): - --ignore-mdc-error option to turn a MDC check error into a - warning. - - * encode.c (encode_crypt), g10.c (main), sign.c (sign_file, - clearsign_file): Use the same --pgpX warning string everywhere to - ease translations. - - * encode.c (write_pubkey_enc_from_list): Warn when using - --throw-keyid with --pgpX. Noted by Vedaal Nistar. - - * revoke.c (export_minimal_pk, gen_desig_revoke, gen_revoke): - Export a minimal pk along with the revocation cert when in --pgpX - mode so that PGP can import it. - -2002-08-06 Werner Koch <wk@gnupg.org> - - * options.skel: Changed comments. - - * g10.c (main): Try to use "gpg.conf" as default option file. - * openfile.c (copy_options_file): Changed name of created file. - -2002-08-02 Werner Koch <wk@gnupg.org> - - * Makefile.am (LDFLAGS): Removed DYNLINK_LDFLAGS. - -2002-07-30 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), mainproc.c (proc_encrypted): Return a - decryption failed error if a MDC does not verify. Warn if a MDC - is not present (can disable via --no-mdc-warning). - - * exec.c (exec_write), g10.c (main), keyserver.c - (keyserver_spawn): Use new DISABLE_KEYSERVER_PATH rather than - FIXED_EXEC_PATH. - -2002-07-28 David Shaw <dshaw@jabberwocky.com> - - * sig-check.c (do_check): Properly validate v4 sigs with no hashed - section at all. - -2002-07-25 Werner Koch <wk@gnupg.org> - - * delkey.c (do_delete_key): Always allow to delete a key in batch mode - when specified by fingerprint. Suggested by Enzo Michelangeli. - -2002-07-25 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_revsig): Change "revsig" to honor selected uids - so the user can revoke sigs from particular uids only. - - * keylist.c (list_keyblock_print): Don't display expired uids in - --list-keys unless -v and not --list-sigs (just like revoked - uids). - - * exec.c, export.c, import.c, keyedit.c, keyserver.c, misc.c: - "Warning" -> "WARNING" - -2002-07-24 David Shaw <dshaw@jabberwocky.com> - - * main.h, import.c (parse_import_options, fix_hkp_corruption, - import_one, delete_inv_parts), g10.c (main): New import-option - "repair-hkp-subkey-bug", which repairs as much as possible the HKP - mangling multiple subkeys bug. It is on by default for keyserver - receives, and off by default for regular --import. - - * main.h, import.c (import, import_one, delete_inv_parts), hkp.c - (hkp_ask_import), keyserver.c (keyserver_spawn): Use keyserver - import options when doing keyserver receives. - - * options.h, exec.h, exec.c (set_exec_path, exec_write), g10.c - (main), keyserver.c (keyserver_spawn): If the user does not use - "exec-path", completely replace $PATH with GNUPG_LIBEXECDIR before - calling the keyserver helper. If the user does use "exec-path", - append GNUPG_LIBEXECDIR after the specified path. - -2002-07-23 David Shaw <dshaw@jabberwocky.com> - - * import.c (parse_import_options), export.c - (parse_export_options): Fix offset problem with reversed ("no-") - meanings. - - * import.c (delete_inv_parts): Discard subkey signatures (0x18 and - 0x28) if found in the userid section of the key. - - * sig-check.c (signature_check2): Signatures made by invalid - subkeys (bad/missing binding sig) are also invalid. - - * keylist.c (print_fingerprint): Show the primary as well as the - secondary key fingerprint in modes 1 & 2. - -2002-07-22 David Shaw <dshaw@jabberwocky.com> - - * options.h, main.h, g10.c (main), import.c - (parse_import_options, delete_inv_parts), keyserver.c - (parse_keyserver_options): add new --import-options option. The - only current flag is "allow-local-sigs". - - * g10.c (main): Don't disable MDC in pgp7 mode. - - * options.h, g10.c (main), keyserver.c (parse_keyserver_options): - Remove old keyserver-option include-attributes now that there is - an export-option for the same thing. - - * options.h, main.h, export.c (parse_export_options, - do_export_stream), g10.c (main): add new --export-options option. - Current flags are "include-non-rfc", "include-local-sigs", - "include-attributes", and "include-sensitive-revkeys". - - * options.h, hkp.c (hkp_export), keyserver.c - (parse_keyserver_options, keyserver_spawn): try passing unknown - keyserver options to export options, and if successful, use them - when doing a keyserver --send-key. - - * build-packet.c (build_sig_subpkt): We do not generate - SIGSUBPKT_PRIV_VERIFY_CACHE anymore. - - * revoke.c (gen_desig_revoke): Lots more comments about including - sensitive revkeys along with the revocation sig itself. - - * keyserver.c (parse_keyserver_options): Simpler implementation - that can skip one pass over the options. - -2002-07-18 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (keyedit_menu, menu_addrevoker): Allow specifying - "sensitive" as an argument to an addrevoker command. This sets - the 0x40 sensitive revoker flag. - - * revoke.c (gen_desig_revoke): When generating a designated - revocation, include the direct key sig that contains the - designated revoker subpacket. This allows sensitive designated - revocation subpackets to be exported. Also indicate which - revokers are sensitive in the first place. - -2002-07-17 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (show_key_with_all_names_colon): The 0x40 class bit in - a designated revoker means "sensitive", not "local". It's - exportable under the right circumstances. - - * main.h, options.h, export.c (do_export_stream), g10.c (main), - hkp.c (hkp_export), keyserver.c (keyserver_spawn: Add a flag to - skip attribute packets and their signatures while exporting. This - is to accomodate keyservers (pksd again) that choke on attributes. - Use keyserver-option "include-attributes" to control it. This - defaults to ON (i.e. don't skip). - -2002-07-09 David Shaw <dshaw@jabberwocky.com> - - * options.h, keyserver.c (parse_keyserver_uri, keyserver_spawn, - keyserver_work), hkp.c (hkp_ask_import, hkp_export, hkp_search): - Use a much more strict reading of RFC-2396 for the keyserver URIs. - Specifically, don't try and be smart about checking the value of - ":port" so long as it is all digits, and properly handle opaque - data (those scheme specific parts that do not start with "//"). - -2002-07-04 David Shaw <dshaw@jabberwocky.com> - - * photoid.c (get_default_photo_command, show_photos): Honor - FIXED_PHOTO_VIEWER and DISABLE_PHOTO_VIEWER. - - * mainproc.c (check_sig_and_print): Use --show-photos to show - photos when verifying a sig made by a key with a photo. - - * keyserver.c (parse_keyserver_uri): Properly parse a URI with no - :port section and an empty file path, but with a terminating '/'. - (keyserver_work): Honor DISABLE_KEYSERVER_HELPERS. - - * hkp.c (hkp_ask_import): Display keyserver URI as a URI, but only - if verbose. - - * exec.c, g10.c: USE_EXEC_PATH -> FIXED_EXEC_PATH - -2002-07-03 David Shaw <dshaw@jabberwocky.com> - - * exec.h, exec.c (set_exec_path, exec_write), g10.c (main): If - USE_EXEC_PATH is defined at compile time, use it to lock the - exec-path and not allow the user to change it. - -2002-07-02 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), keyserver.c (keyserver_refresh): - Maintain and use the original keyserver URI for cosmetics rather - than trying to recreate it when needed. - - * mainproc.c (check_sig_and_print): Properly disregard expired - uids. Make sure that the first uid listed is a real uid and not - an attribute (attributes should only be listed in the "aka" - section). When there are no valid textual userids, try for an - invalid textual userid before using any attribute uid. - -2002-07-01 David Shaw <dshaw@jabberwocky.com> - - * options.skel: Fix a few typos, clarify "group", and remove - sample photo viewers for Win32 since they are the defaults now. - - * parse-packet.c (make_attribute_uidname), keylist.c - (dump_attribs): Fix two typecast warnings. - - * packet.h, build-packet.c (build_attribute_subpkt), exec.c - (expand_args), mkdtemp.c (mkdtemp), photoid.c - (parse_image_header): Fix some signedness compiler warnings. - -2002-07-01 Werner Koch <wk@gnupg.org> - - * photoid.c (get_default_photo_command): Also use __MINGW32__ - instead of HAVE_DOSISH_SYSTEM. - - * encode.c (encode_symmetric): Do not use the new encryption code. - -2002-06-30 Werner Koch <wk@gnupg.org> - - * photoid.c: Use __MINGW32__ to include windows because - HAVE_DOSISH_SYSTEM is also set for OS/2 and plain DOS. Provide - constant missing in older mingw installations. - -2002-06-21 Stefan Bellon <sbellon@sbellon.de> - - * g10.c [__riscos__]: Moved RISC OS specific stuff to util/riscos.c - and include/util.h. - - * gpgv.c [__riscos__]: Likewise. - -2002-06-20 David Shaw <dshaw@jabberwocky.com> - - * keydb.h, pkclist.c (select_algo_from_prefs): Allow passing a - suggested algorithm which will be used if available. - - * encode.c (encode_crypt, encrypt_filter), sign.c (sign_file): Use - new select_algo_from_prefs feature to check if forcing an - algorithm would violate the recipient preferences. - - * photoid.c (get_default_photo_command, show_photos): Use - different default viewers on different platforms. Currently we - have Win 9x, Win NT (2k, xp), Mac OSX, RISC OS, and "everybody - else". These are #ifdefs as much as possible to avoid clutter. - - * g10.c (strusage, build_list), keyedit.c (show_prefs), main.h, - misc.c (compress_algo_to_string, check_compress_algo), pkclist.c - (algo_available), keygen.c (keygen_set_std_prefs): New - algo_to_string and check functions for compress algorithms. - -2002-06-20 Werner Koch <wk@gnupg.org> - - * misc.c (setsysinfo): Removed a #warning for Alpha's uniligedn - trap disabling - it is quite possible that this is a debug relict. - -2002-06-20 Stefan Bellon <sbellon@sbellon.de> - - * g10.c [__riscos__]: Added image file system feature. - - * gpgv.c [__riscos__]: Added image file system feature. - - * photoid.c (show_photos) [__riscos__]: Set RISC OS filetype of - photo id according to MIME type. - -2002-06-19 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (parse_hkp_index): Don't leak memory when failing out of a - bad HKP keyserver. - - * g10.c (add_notation_data): Relax slightly the rules as to what - can go into a notation name - 2440 allows "@", for example. - -2002-06-17 David Shaw <dshaw@jabberwocky.com> - - * import.c (clean_subkeys, import_one): Only allow at most 1 - binding sig and at most 1 revocation sig on a subkey, as per - 2440:11.1. - - * hkp.c (parse_hkp_index, hkp_search): Error if the keyserver - returns an unparseable HKP response. - -2002-06-15 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (show_key_with_all_names), keylist.c - (list_keyblock_print): Show "[expired]" before expired uids. - - * keyedit.c (show_key_with_all_names_colon), mainproc.c - (list_node), keylist.c (list_keyblock_colon): Show flag 'e' for - expired user ids. Use "uat" for user attribute packets instead of - "uid". Also use '<count> <length>' rather than the fake user id - string on attributes. - - * keygen.c (keygen_add_revkey): Remove unused code. - - * misc.c (check_permissions): Check directory permissions - properly - they are not special files. - - * pkclist.c (expand_id, expand_group, build_pk_list): When - expanding groups before building a pk list, inherit flags from the - original pre-expanded string. - - * pubkey-enc.c (is_algo_in_prefs): Don't use prefs from expired - uids. - -2002-06-14 David Shaw <dshaw@jabberwocky.com> - - * free-packet.c (copy_signature): Properly copy a signature that - carries a revocation key on it. - - * pkclist.c (expand_id, expand_group, build_pk_list): Groups now - work properly when used in the "Enter the user ID" prompt. - -2002-06-14 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (show_key_with_all_names): Display warning if a user - tries to show prefs on a v3 key with a v3 selfsig. - - * kbnode.c (dump_kbnode): Show if a uid is expired. - - * import.c (merge_blocks, import_revoke_cert): Show user ID - receiving a revocation certificate. - - * free-packet.c (cmp_user_ids): Properly compare attribute ids. - - * pkclist.c (expand_groups): Maintain the strlist flags while - expanding. Members of an expansion inherit their flags from the - expansion key. - - * options.h, cipher.c (write_header), g10.c (main), keygen.c - (keygen_set_std_prefs): remove the personal_mdc flag. It no - longer serves a purpose now that the personal preference lists are - split into cipher/digest/zip. - -2002-06-14 Timo Schulz <ts@winpt.org> - - * skclist.c (is_insecure): Implemented. - -2002-06-12 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_spawn): Properly handle PROGRAM responses - when they have a CRLF ending. Noted by Keith Ray. - - * keyserver.c (keyserver_spawn): Handle CRLF endings from - keyserver helpers. Also don't leak the last line worth of memory - from the keyserver response. - - * main.h, misc.c (deprecated_warning): New function to warn about - deprecated options and commands. - - * g10.c (main), keyserver-internal.h, keyserver.c - (parse_keyserver_uri): Use new deprecated function to warn about - honor-http-proxy, auto-key-retrieve, and x-broken-hkp. - -2002-06-11 David Shaw <dshaw@jabberwocky.com> - - * Makefile.am: link gpg with NETLIBS for the built-in HKP access. - -2002-06-10 David Shaw <dshaw@jabberwocky.com> - - * options.h, keyserver.c (keyserver_opts), g10.c (main): New - keyserver option "include-subkeys". This feature already existed, - but now can be turned off. It defaults to on. - - * options.h, keyserver.c (parse_keyserver_options, - keyserver_spawn): There are now enough options to justify making a - structure for the keyserver options rather than a page of - if-then-else-if-then-etc. - - * getkey.c (merge_keys_and_selfsig, merge_selfsigs_main): Fix bug - in calculating key expiration dates. - -2002-06-09 David Shaw <dshaw@jabberwocky.com> - - * keydb.h, getkey.c (get_user_id_native), import.c (import_one): - Display user ID while importing a key. Note this applies to both - --import and keyserver --recv-keys. - - * exec.c (exec_finish): Log unnatural exit (core dump, killed - manually, etc) for fork/exec/pipe child processes. - -2002-06-08 Timo Schulz <ts@winpt.org> - - * encode.c (encode_symmetric): Disable the compat flag - when the expert mode is enabled. - -2002-06-07 David Shaw <dshaw@jabberwocky.com> - - * options.skel, options.h, main.h, keydb.h, pkclist.c - (build_pk_list, expand_groups), g10.c (main, add_group): Add new - "group" command to allow one name to expand into multiple keys. - For simplicity, and to avoid potential loops, we only expand once - - you can't make an alias that points to an alias. - - * main.h, g10.c (main), keygen.c (build_personal_digest_list): - Simplify the default digest list - there is really no need for the - other hashes since they will never be used after SHA-1 in the - list. - - * options.skel, options.h, g10.c (main), hkp.c (hkp_ask_import, - hkp_export, hkp_search), keyserver.c (parse_keyserver_options, - parse_keyserver_uri, keyserver_work, keyserver_refresh): Make the - "x-broken-hkp" keyserver scheme into keyserver-option - "broken-http-proxy". Move honor_http_proxy into - keyserver_options. Canonicalize the three variations of "hkp", - "x-hkp", and "x-broken-hkp" into "hkp". - -2002-06-07 Stefan Bellon <sbellon@sbellon.de> - - * g10.c [__riscos__]: Added --attribute-file to do the same as - --attribute-fd, but with a filename not a fd as argument. - Added magic symbol for RISC OS to use different memory management. - - * gpgv.c [__riscos__]: Added magic symbol for RISC OS to use - different memory management. - -2002-06-06 David Shaw <dshaw@jabberwocky.com> - - * main.h, g10.c (main), keygen.c (build_personal_digest_list): Put - in a default digest preference list consisting of SHA-1, followed - by every other installed digest except MD5. Note this is the same - as having no digest preference at all except for SHA-1 being - favored. - - * options.h, g10.c (main), keygen.c (keygen_set_std_prefs), - pkclist.c (select_algo_from_prefs): Split - --personal-preference-list into three: - --personal-{cipher|digest|compress}-preferences. This allows a - user to set one without affecting another (i.e. setting only a - digest pref doesn't imply an empty cipher pref). - - * exec.c (exec_read): This is a safer way of guessing the return - value of system(). Noted by Stefan Bellon. - -2002-06-05 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (parse_hkp_index): Be more robust with keyservers - returning very unparseable responses. - - * exec.c (exec_read): Catch and display an error when the remote - process exits unnaturally (i.e. segfault) so the user knows what - happened. Also fix exec_write stub which has a different number - of arguments now. - -2002-06-05 Timo Schulz <ts@winpt.org> - - * encode.c (encode_simple): Ignore the new mode for RFC1991. - * mainproc.c (symkey_decrypt_sesskey): Better check for weird - keysizes. - -2002-06-05 Timo Schulz <ts@winpt.org> - - * encode.c (encode_sesskey): New. - (encode_simple): Use it here. But by default we use the compat - mode which supress to generate encrypted session keys. - -2002-06-05 Timo Schulz <ts@winpt.org> - - * mainproc.c (symkey_decrypt_sesskey): New. - (proc_symkey_enc): Support for encrypted session keys. - -2002-06-04 David Shaw <dshaw@jabberwocky.com> - - * sign.c (hash_for, sign_file): When encrypting and signing at the - same time, consult the various hash prefs to pick a hash algorithm - to use. Pass in a 160-bit hint if any of the signing keys are - DSA. - - * keydb.h, pkclist.c (select_algo_from_prefs, algo_available): - Pass a "hints" opaque pointer in to let the caller give hints as - to what algorithms would be acceptable. The only current hint is - for PREFTYPE_HASH to require a 160-bit hash for DSA. Change all - callers in encode.c (encode_crypt, encrypt_filter) and sign.c - (sign_file). If we settle on MD5 as the best algorithm based - solely on recepient keys and SHA1 is also a possibility, use SHA1 - unless the user intentionally chose MD5. This is as per 2440:13. - - * exec.c (make_tempdir): Fix duplicated filename problem. - -2002-06-03 David Shaw <dshaw@jabberwocky.com> - - * packet.h, parse-packet.c (enum_sig_subpkt): Report back from - enum_sig_subpkt when a subpacket is critical and change all - callers in keylist.c (show_policy_url, show_notation), mainproc.c - (print_notation_data), and pkclist.c (do_show_revocation_reason). - - * keylist.c (show_policy_url, show_notation): Display if the - policy or notation is critical. - -2002-06-03 David Shaw <dshaw@jabberwocky.com> - - * main.h, g10.c (main), keylist.c (dump_attribs, set_attrib_fd, - list_keyblock_print, list_keyblock_colon), status.h, status.c - (get_status_string): New --attribute-fd feature to dump the - contents of attribute subpackets for frontends. If --status-fd is - also used, then a new status tag ATTRIBUTE is provided for each - subpacket. - - * packet.h, getkey.c (fixup_uidnode, merge_selfsigs_main, - merge_selfsigs_subkey), parse-packet.c (setup_user_id): Keep track - of the expiration time of a user ID, and while we're at it, use - the expired flag from the selfsig rather than reparsing the - SIG_EXPIRE subpacket. - - * photoid.c (generate_photo_id): When adding a new photo ID, - showing the photo for confirmation is not safe when noninteractive - since the "user" may not be able to dismiss a viewer window. - Noted by Timo Schulz. - -2002-06-03 David Shaw <dshaw@jabberwocky.com> - - * options.skel: Sample photo viewers for Win32. - - * misc.c (pct_expando): Use the seckey for %k/%K if the pubkey is - not available. - - * photoid.h, photoid.c (show_photos): Include the seckey in case a - user tries to view a photo on a secret key, and change all callers - in keyedit.c (menu_showphoto), keylist.c (list_keyblock_print), - and photoid.c (generate_photo_id). - -2002-06-02 David Shaw <dshaw@jabberwocky.com> - - * photoid.c (show_photos): Work properly when not called with a - public key. - -2002-05-31 David Shaw <dshaw@jabberwocky.com> - - * sign.c (mk_notation_and_policy): Free unneeded buffer. - - * hkp.c (parse_hkp_index): Properly handle the '&' character - (i.e. "&amp;") in HKP responses. - - * getkey.c (merge_selfsigs_main): Fix reversed expiration time - check with self-sigs. - - * keyedit.c (sign_uids): When making a new self-sig on a v3 key, - make a v3 self-sig unless it is currently a v3 self-sig being - promoted to v4. - -2002-05-31 Timo Schulz <ts@winpt.org> - - * pkclist.c (do_show_revocation_reason): Don't use capital - letters for non-interactive output. - (show_revocation_reason): Now it is global. - * pubkey-enc.c (get_it): Show if the key has been revoked. - -2002-05-30 David Shaw <dshaw@jabberwocky.com> - - * sign.c (write_signature_packets, sign_file, clearsign_file, - sign_symencrypt_file): Make a v4 signature if a policy URL or - notation is set, unless v3 sigs are forced via rfc1991 or - force-v3-sigs. Also remove some doubled code and clarify an error - message (we don't sign in PGP2 mode - just detach-sign). - - * parse-packet.c (parse_one_sig_subpkt): Add KS_FLAGS to the "any - size" section. - -2002-05-29 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (keygen_set_std_prefs, add_feature_mdc): Use "mdc" and - "no-mdc" in the prefs string to allow switching on and off the MDC - feature. This is needed to properly export a key from GnuPG for - use on PGP which does not support MDC - without this, MDC-capable - implementations will still try and generate MDCs which will break - PGP. - - * keygen.c (keygen_get_std_prefs): Show "[mdc]" in prefs string if - it is enabled. - - * options.h, g10.c (main), cipher.c (write_header), keygen.c - (keygen_set_std_prefs): For consistency, allow the user to specify - mdc/no-mdc in the --personal-preference-list. If disabled, it - acts just like --disable-mdc. - -2002-05-29 David Shaw <dshaw@jabberwocky.com> - - * options.h, exec.c: Add some debugging info, using the 1024 debug - flag. - - * exec.c (win_system): New system()-like function for win32 that - does not return until the child process terminates. Of course, - this doesn't help if the process itself exits before it is - finished. - -2002-05-29 Werner Koch <wk@gnupg.org> - - * encode.c (encode_simple): Intialize PKT when --no-literal is used. - - * keyedit.c (show_key_with_all_names_colon): Renamed the record - for revocation keys to "rvk". - -2002-05-27 Werner Koch <wk@gnupg.org> - - * keyedit.c (show_key_with_all_names_colon): New. - (show_key_with_all_names): Divert to new function when required. - Sanitize printing of revoker name. - -2002-05-27 David Shaw <dshaw@jabberwocky.com> - - * build-packet.c (build_sig_subpkt): Handle setting sig flags for - certain subpacket types (notation, policy url, exportable, - revocable). keyedit.c (sign_mk_attrib): Flags no longer need to - be set here. - - * packet.h, parse-packet.c (parse_one_sig_subpkt), build-packet.c - (build_sig_subpkt): Call parse_one_sig_subpkt to sanity check - buffer lengths before building a sig subpacket. - -2002-05-26 David Shaw <dshaw@jabberwocky.com> - - * sign.c (mk_notation_and_policy): Include secret key to enable %s - expandos, and pass notations through pct_expando as well. - - * main.h, misc.c (pct_expando): Add %s and %S expandos for - signer's keyid. - -2002-05-25 David Shaw <dshaw@jabberwocky.com> - - * g10.c (strusage, build_list): Add compress algorithms to - --version list. Show algorithm numbers when --verbose --version - is done. - -2002-05-22 David Shaw <dshaw@jabberwocky.com> - - * options.h, main.h, keygen.c (keygen_set_set_prefs, - keygen_get_std_prefs, keygen_upd_std_prefs), keyedit.c - (keyedit_menu), g10.c (main), pkclist.c (select_algo_from_prefs): - Add --personal-preference-list which allows the user to factor in - their own preferred algorithms when the preference lists are - consulted. Obviously, this does not let the user violate a - recepient's preferences (and the RFC) - this only influences the - ranking of the agreed-on (and available) algorithms from the - recepients. Suggested by David Hollenberg. - - * options.h, keygen.c (keygen_set_std_prefs), g10.c (main): Rename - --preference-list to --default-preference-list (as that is what it - really is), and make it a true default in that if the user selects - "default" they get this list and not the compiled-in list. - -2002-05-22 Werner Koch <wk@gnupg.org> - - * g10.c (main): Add missing LF in a info printout and made it - translatable. Noted by Michael Tokarev. - -2002-05-21 Werner Koch <wk@gnupg.org> - - * g10.c (main): Removed the undef of USE_SHM_COPROCESSING which - was erroneously introduced on 2002-01-09. - - * signal.c (got_fatal_signal): Don't write the Nul to stderr. - Reported by David Hollenberg. - -2002-05-18 David Shaw <dshaw@jabberwocky.com> - - * main.h, g10.c (main), revoke.c (gen_desig_revoke): Generate a - designated revocation via --desig-revoke - - * keyedit.c (keyedit_menu, menu_addrevoker): New "addrevoker" - command to add a designated revoker to a key. - -2002-05-17 David Shaw <dshaw@jabberwocky.com> - - * gpgv.c: Add stub for get_ownertrust(). - - * g10.c (main): --allow-freeform-uid should be implied by - OpenPGP. Add --no-allow-freeform-uid. - - * keyedit.c (sign_uids): Issue a warning when signing a - non-selfsigned uid. - - * getkey.c (merge_selfsigs_main): If a key has no selfsigs, and - allow-non-selfsigned-uid is not set, still try and make the key - valid by checking all uids for a signature from an ultimately - trusted key. - -2002-05-16 David Shaw <dshaw@jabberwocky.com> - - * main.h, keygen.c (keygen_add_revkey): Add revocation key - subpackets to a signature (callable by - make_keysig_packet). (write_direct_sig): Write a 1F direct key - signature. (parse_revocation_key): Parse a string in - algo:fpr:sensitive format into a revocation - key. (get_parameter_revkey, do_generate_keypair): Call above - functions when prompted from a batch key generation file. - - * build-packet.c (build_sig_subpkt): Allow multiple revocation key - subpackets in a single sig. - - * keydb.h, getkey.c (get_seckey_byfprint): Same as - get_pubkey_byfprint, except for secret keys. We only know the - fingerprint of a revocation key, so this is needed to retrieve the - secret key needed to issue a revokation. - - * packet.h, parse-packet.c (parse_signature, parse_revkeys): Split - revkey parsing off into a new function that can be used to reparse - after manipulating the revkey list. - - * sign.c (make_keysig_packet): Ability to make 1F direct key - signatures. - -2002-05-15 David Shaw <dshaw@jabberwocky.com> - - * options.skel: keyserver.pgp.com is gone, so list pgp.surfnet.nl - as a sample LDAP server instead. - - * getkey.c (merge_selfsigs_main): Properly handle multiple - revocation keys in a single packet. Properly handle revocation - keys that are in out-of-order packets. Remove duplicates in - revocation key list. - -2002-05-14 Timo Schulz <ts@winpt.org> - - * exec.c (make_tempdir) [MINGW32]: Added missing '\'. - -2002-05-14 Stefan Bellon <sbellon@sbellon.de> - - * exec.c (make_tempdir): Make use of EXTSEP_S instead of hardcoded - dot as extension separator. - -2002-05-13 David Shaw <dshaw@jabberwocky.com> - - * photoid.c (show_photos): Use the long keyid as the filename for - the photo. Use the short keyid as the filename on 8.3 systems. - - * exec.h, exec.c (make_tempdir, exec_write, exec_finish): Allow - caller to specify filename. This should make things easier on - windows and macs where the file extension is required, but a whole - filename is even better. - - * keyedit.c (show_key_with_all_names, show_prefs): Show proper - prefs for a v4 key uid with no selfsig at all. - - * misc.c (check_permissions): Don't check permissions on - non-normal files (pipes, character devices, etc.) - -2002-05-11 Werner Koch <wk@gnupg.org> - - * mainproc.c (proc_symkey_enc): Avoid segv in case the parser - encountered an invalid packet. - - * keyserver.c (keyserver_export): Get confirmation before sending - all keys. - -2002-05-10 Stefan Bellon <sbellon@sbellon.de> - - * g10.c, hkp.c, keyedit.c, keyserver.c: Replaced all occurrances - of strcasecmp with ascii_strcasecmp and all occurrances of - strncasecmp with ascii_memcasecmp. - -2002-05-10 David Shaw <dshaw@jabberwocky.com> - - * packet.h, getkey.c (fixup_uidnode), keyedit.c (show_prefs): Show - assumed prefs for hash and compression as well as the cipher pref. - Show assumed prefs if there are no prefs at all on a v4 - self-signed key. - - * options.h, g10.c (main), sign.c (make_keysig_packet): New - --cert-digest-algo function to override the default key signing - hash algorithm. - -2002-05-09 David Shaw <dshaw@jabberwocky.com> - - * getkey.c (merge_selfsigs_main): Make sure the revocation key - list starts clean as this function may be called more than once - (e.g. from functions in --edit). - - * g10.c, encode.c (encode_crypt), sign.c (sign_file, - sign_symencrypt_file): Make --compress-algo work like the - documentation says. It should be like --cipher-algo and - --digest-algo in that it can override the preferences calculation - and impose the setting the user wants. No --compress-algo setting - allows the usual preferences calculation to take place. - - * main.h, compress.c (compress_filter): use new - DEFAULT_COMPRESS_ALGO define, and add a sanity check for compress - algo value. - -2002-05-08 David Shaw <dshaw@jabberwocky.com> - - * pkclist.c (select_algo_from_prefs): There is an assumed - compression preference for uncompressed data. - -2002-05-07 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), getkey.c (finish_lookup), pkclist.c - (algo_available): --pgp7, identical to --pgp6 except that it - permits a few algorithms that PGP 7 added: AES128, AES192, AES256, - and TWOFISH. Any more of these --pgpX flags, and it'll be time to - start looking at a generic --emulate-pgp X option. - - * export.c (do_export_stream): Warn the user when exporting a - secret key if it or any of its secret subkeys are protected with - SHA1 while simple_sk_checksum is set. - - * parse-packet.c (parse_key): Show when the SHA1 protection is - used in --list-packets. - - * options.h, build-packet.c (do_comment), g10.c (main): Rename - --no-comment as --sk-comments/--no-sk-comments (--no-comment still - works) and make the default be --no-sk-comments. - -2002-05-07 Werner Koch <wk@gnupg.org> - - * keygen.c (get_parameter_algo): Never allow generation of the - deprecated RSA-E or RSA-S flavors of PGP RSA. - (ask_algo): Allow generation of RSA sign and encrypt in expert - mode. Don't allow ElGamal S+E unless in expert mode. - * helptext.c: Added entry keygen.algo.rsa_se. - -2002-05-07 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (sign_uids): If --expert is set, allow re-signing a - uid to promote a v3 self-sig to a v4 one. This essentially - deletes the old v3 self-sig and replaces it with a v4 one. - - * packet.h, parse-packet.c (parse_key), getkey.c - (merge_keys_and_selfsig, merge_selfsigs_main): a v3 key with a v4 - self-sig must never let the v4 self-sig express a key expiration - time that extends beyond the original v3 expiration time. - -2002-05-06 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (sign_uids): When making a self-signature via "sign" - don't ask about sig level or expiration, and include the usual - preferences and such for v4 self-sigs. (menu_set_preferences): - Convert uids from UTF8 to native before printing. - - * keyedit.c (sign_uids): Convert uids from UTF8 to native before - printing. (menu_set_primary_uid): Show error if the user tries to - make a uid with a v3 self-sig primary. - -2002-05-05 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_one): When merging with a key we already have, - don't let a key conflict (same keyid but different key) stop the - import: just skip the bad key and continue. - - * exec.c (make_tempdir): Under Win32, don't try environment - variables for temp directories - GetTempDir tries environment - variables internally, and it's better not to second-guess it in - case MS adds some sort of temp dir handling to Windows at some - point. - -2002-05-05 Timo Schulz <ts@winpt.org> - - * mainproc.c (proc_symkey_enc): Don't ask for a passphrase - in the list only mode. - -2002-05-05 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_refresh): --refresh-keys implies - --merge-only so as not to import keys with keyids that match the - ones being refreshed. Noted by Florian Weimer. - -2002-05-04 Stefan Bellon <sbellon@sbellon.de> - - * free-packet.c (copy_public_key): Don't call m_alloc(0), therefore - added consistency check for revkey and numrefkeys. - - * getkey.c (check_revocation_keys): Added consistency check for - revkey and numrefkeys. - - * keyedit.c (show_key_with_all_names): Likewise. - -2002-05-03 David Shaw <dshaw@jabberwocky.com> - - * photoid.c: Provide default image viewer for Win32. - - * misc.c (pct_expando): %t means extension, not name ("jpg", not - "jpeg"). - - * keyserver.c (keyserver_spawn), photoid.c (show_photos), exec.h, - exec.c: Allow the caller to determine the temp file extension when - starting an exec_write and change all callers. - - * keyedit.c (sign_uids): Nonrevocable key signatures cause an - automatic promotion to v4. - - * exec.c: Provide stubs for exec_ functions when NO_EXEC is - defined. - -2002-05-02 David Shaw <dshaw@jabberwocky.com> - - * photoid.h, photoid.c (parse_image_header, image_type_to_string): - Useful functions to return data about an image. - - * packet.h, parse-packet.c (make_attribute_uidname, - parse_attribute_subpkts, parse_attribute), photoid.h, photoid.c - (show_photos): Handle multiple images in a single attribute - packet. - - * main.h, misc.c (pct_expando), sign.c (mk_notation_and_policy), - photoid.c (show_photos): Simpler expando code that does not - require using compile-time string sizes. Call - image_type_to_string to get image strings (i.e. "jpg", - "image/jpeg"). Change all callers. - - * keyedit.c (menu_showphoto), keylist.c (list_keyblock_print): - Allow viewing multiple images within a single attribute packet. - - * gpgv.c: Various stubs for link happiness. - -2002-05-02 David Shaw <dshaw@jabberwocky.com> - - * build-packet.c (build_sig_subpkt), keyedit.c (sign_uids), - options.h, sign.c (mk_notation_and_policy), g10.c (main, - add_notation_data, add_policy_url (new), check_policy_url - (removed)): Allow multiple policy URLs on a given signature. - Split "--notation-data" into "--cert-notation" and - "--sig-notation" so the user can set different policies for key - and data signing. For backwards compatibility, "--notation-data" - sets both, as before. - -2002-05-02 Werner Koch <wk@gnupg.org> - - * options.skel: Removed the comment on trusted-keys because this - option is now deprecated. - -2002-05-01 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_adduid): 2440bis04 says that multiple attribute - packets on a given key are legal. - - * keyserver.c (keyserver_refresh): the fake v3 keyid hack applies - to "mailto" URLs as well since they are also served by pksd. - -2002-04-29 Werner Koch <wk@gnupg.org> - - Added a copyright year for files changed this year. - -2002-04-25 Werner Koch <wk@gnupg.org> - - * g10.c, options.h: New options --display, --ttyname, --ttytype, - --lc-ctype, --lc-messages to be used with future versions of the - gpg-agent. - * passphrase.c (agent_send_option,agent_send_all_options): New. - (agent_open): Send options to the agent. - - * trustdb.c (update_ownertrust, clear_ownertrust): Do an explicit - do_sync because revalidation_mark does it only if when the - timestamp actually changes. - -2002-04-23 David Shaw <dshaw@jabberwocky.com> - - * main.h, keygen.c (do_generate_keypair), keylist.c - (print_signature_stats, list_all, list_one, list_keyblock, - list_keyblock_print, list_keyblock_colon): After generating a new - key, show the key information (name, keyid, fingerprint, etc.) - Also do not print uncheckable signatures (missing key..) in - --check-sigs. Print statistics (N missing keys, etc.) after - --check-sigs. - - * keyedit.c (sign_uids): When signing a key with an expiration - date on it, the "Do you want your signature to expire at the same - time?" question should default to YES. - -2002-04-22 David Shaw <dshaw@jabberwocky.com> - - * parse-packet.c (parse_plaintext), packet.h, plaintext.c - (handle_plaintext): Fix bug in handling literal packets with - zero-length data (no data was being confused with partial body - length). - - * misc.c (pct_expando), options.skel: %t means extension ("jpg"). - %T means MIME type ("image/jpeg"). - - * import.c (import_one): Only trigger trust update if the keyring - is actually changed. - - * export.c (do_export_stream): Missing a m_free. - -2002-04-22 Stefan Bellon <sbellon@sbellon.de> - - * keyid.c (expirestr_from_sk, expirestr_from_sig): Added _() to - string constant. - - * exec.c (make_tempdir) [__riscos__]: Better placement of - temporary file. - -2002-04-20 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (generate_subkeypair): 2440bis04 adds that creating - subkeys on v3 keys is a MUST NOT. - - * getkey.c (finish_lookup): The --pgp6 "use the primary key" - behavior should only apply while data signing and not encryption. - Noted by Roger Sondermann. - -2002-04-19 Werner Koch <wk@gnupg.org> - - * keygen.c (keygen_set_std_prefs): Put back 3DES because the RFC - says it is good form to do so. - -2002-04-19 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_deluid): Only cause a trust update if we delete - a non-revoked user id. - - * hkp.c (hkp_ask_import), keyserver.c (parse_keyserver_options, - keyserver_spawn), options.h: Remove fast-import keyserver option - (no longer meaningful). - - * g10.c (main), keyedit.c (sign_uids), options.h: Change - --default-check-level to --default-cert-check-level as it makes - clear what it operates on. - - * g10.c (main): --pgp6 also implies --no-ask-sig-expire. - - * delkey.c (do_delete_key): Comment. - - * keyedit.c (sign_uids, keyedit_menu, menu_deluid, menu_delsig, - menu_expire, menu_revsig, menu_revkey): Only force a trustdb check - if we did something that changes it. - - * g10.c: add "--auto-check-trustdb" to override a - "--no-auto-check-trustdb" - -2002-04-19 Werner Koch <wk@gnupg.org> - - * tdbio.c (tdbio_write_nextcheck): Return a status whether the - stamp was actually changed. - * trustdb.c (revalidation_mark): Sync the changes. Removed the - sync operation done by its callers. - (get_validity): Add logic for maintaining a pending_check flag. - (clear_ownertrust): New. - - * keyedit.c (sign_uids): Don't call revalidation_mark depending on - primary_pk. - (keyedit_menu): Call revalidation_mark after "trust". - (show_key_with_all_names): Print a warning on the wrong listed key - validity. - - * delkey.c (do_delete_key): Clear the owenertrust information when - deleting a public key. - -2002-04-18 Werner Koch <wk@gnupg.org> - - * seskey.c (encode_md_value): Print an error message if a wrong - digest algorithm is used with DSA. Changed all callers to cope - with a NULL return. Problem noted by Imad R. Faiad. - -2002-04-18 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (mark_usable_uid_certs): Properly handle nonrevocable - signatures that can expire. In short, the only thing that can - override an unexpired nonrevocable signature is another unexpired - nonrevocable signature. - - * getkey.c (finish_lookup): Always use primary signing key for - signatures when --pgp6 is on since pgp6 and 7 do not understand - signatures made by signing subkeys. - -2002-04-18 Werner Koch <wk@gnupg.org> - - * trustdb.c (validate_keys): Never schedule a nextcheck into the - past. - (validate_key_list): New arg curtime use it to set next_expire. - (validate_one_keyblock): Take the current time from the caller. - (clear_validity, reset_unconnected_keys): New. - (validate_keys): Reset all unconnected keys. - - * getkey.c (premerge_public_with_secret): Fixed 0x12345678! syntax - for use with secret keys. - (lookup): Advance the searchmode after a search FIRST. - - * seckey-cert.c (do_check): Always calculate the old checksum for - use after unprotection. - - * g10.c, options.skel: New option --no-escape-from. Made - --escape-from and --force-v3-sigs the default and removed them - from the options skeleton. - -2002-04-16 Werner Koch <wk@gnupg.org> - - * parse-packet.c (parse_key): Support a SHA1 checksum as per - draft-rfc2440-bis04. - * packet.h (PKT_secret_key): Add field sha1chk. - * seckey-cert.c (do_check): Check the SHA1 checksum - (protect_secret_key): And create it. - * build-packet.c (do_secret_key): Mark it as sha-1 protected. - * g10.c, options.h: New option --simple-sk-checksum. - -2002-04-13 David Shaw <dshaw@jabberwocky.com> - - * parse-packet.c (parse_signature): Minor fix - signatures should - expire at their expiration time and not one second later. - - * keygen.c (proc_parameter_file): Allow specifying preferences - string (i.e. "s5 s2 z1 z2", etc) in a batchmode key generation - file. - - * keyedit.c (keyedit_menu): Print standard error message when - signing a revoked key (no new translation). - - * getkey.c (merge_selfsigs): Get the default set of key prefs from - the real (not attribute) primary uid. - -2002-04-12 David Shaw <dshaw@jabberwocky.com> - - * pkclist.c (build_pk_list): Fix bug that allowed a key to be - selected twice in batch mode if one instance was the default - recipient and the other was an encrypt-to. Noted by Stefan - Bellon. - - * parse-packet.c (dump_sig_subpkt): Show data in trust and regexp - sig subpackets. - - * keyedit.c (keyedit_menu): Use new function real_uids_left to - prevent deleting the last real (i.e. non-attribute) uid. Again, - according to the attribute draft. (menu_showphoto): Make another - string translatable. - -2002-04-11 David Shaw <dshaw@jabberwocky.com> - - * build-packet.c (build_sig_subpkt): Delete subpackets from both - hashed and unhashed area on update. (find_subpkt): No longer - needed. - - * keyedit.c (sign_uids): With --pgp2 on, refuse to sign a v3 key - with a v4 signature. As usual, --expert overrides. Try to tweak - some strings to a closer match so they can all be translated in - one place. Use different helptext keys to allow different help - text for different questions. - - * keygen.c (keygen_upd_std_prefs): Remove preferences from both - hashed and unhashed areas if they are not going to be used. - -2002-04-10 David Shaw <dshaw@jabberwocky.com> - - * misc.c (pct_expando), options.skel: Use %t to indicate type of a - photo ID (in this version, it's always "jpeg"). Also tweak string - expansion loop to minimize reallocs. - - * mainproc.c (do_check_sig): Variable type fix. - - * keyedit.c (menu_set_primary_uid): Differentiate between true - user IDs and attribute user IDs when making one of them primary. - That is, if we are making a user ID primary, we alter user IDs. - If we are making an attribute packet primary, we alter attribute - packets. This matches the language in the latest attribute packet - draft. - - * keyedit.c (sign_uids): No need for the empty string hack. - - * getkey.c (fixup_uidnode): Only accept preferences from the - hashed segment of the self-sig. - -2002-04-10 Werner Koch <wk@gnupg.org> - - * tdbio.c (migrate_from_v2): Fixed the offset to read the old - ownertrust value and only add entries to the table if we really - have a value. - -2002-04-08 David Shaw <dshaw@jabberwocky.com> - - * status.h, status.c (get_status_string): Add KEYEXPIRED, EXPSIG, - and EXPKEYSIG. Add "deprecated-use-keyexpired-instead" to - SIGEXPIRED. - - * sig-check.c (do_check): Start transition from SIGEXPIRED to - KEYEXPIRED, since the actual event is signature verification by an - expired key and not an expired signature. (do_signature_check, - packet.h): Rename as signature_check2, make public, and change all - callers. - - * mainproc.c (check_sig_and_print, do_check_sig): Use status - EXPSIG for an expired, but good, signature. Add the expiration - time (or 0) to the VALIDSIG status line. Use status KEYEXPSIG for - a good signature from an expired key. - - * g10.c (main): remove checks for no arguments now that argparse - does it. - -2002-04-06 Werner Koch <wk@gnupg.org> - - * keyring.c (keyring_get_keyblock): Disable the keylist mode here. - - * encode.c (encode_simple, encode_crypt): Only test on compressed - files if a compress level was not explicity set. - - * keygen.c (keygen_set_std_prefs): Removed Blowfish and Twofish - from the list of default preferences, swapped the preferences of - RMD160 and SHA1. Don't include a preference to 3DES unless the - IDEA kludge gets used. - - * free-packet.c (free_packet): call free_encrypted also for - PKT_ENCRYPTED_MDC. - - * compress.c (release_context): New. - (handle_compressed): Allocate the context and setup a closure to - release the context. This is required because there is no - guarabntee that the filter gets popped from the chain at the end - of the function. Problem noted by Timo and probably also the - cause for a couple of other reports. - (compress_filter): Use the release function if set. - - * tdbio.c [__CYGWIN32__]: Don't rename ftruncate. Noted by - Disastry. - - * parse-packet.c (parse_signature): Put parens around a bit test. - - * exec.c (make_tempdir): Double backslash for TMP directory - creation under Windows. Better strlen the DIRSEP_S constants for - allocation measurements. - - * decrypt.c (decrypt_messages): Release the passphrase aquired - by get_last_passphrase. - -2002-04-02 Werner Koch <wk@gnupg.org> - - * Makefile.am (EXTRA_DIST): Removed OPTIONS an pubring.asc - they - are no longer of any use. - -2002-04-03 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (parse_keyserver_options): fix auto-key-retrieve to - actually work as a keyserver-option (noted by Roger Sondermann). - - * keylist.c (reorder_keyblock): do not reorder the primary - attribute packet - the first user ID must be a genuine one. - -2002-03-31 David Shaw <dshaw@jabberwocky.com> - - * keylist.c (list_keyblock_colon): Fix ownertrust display with - --with-colons. - - * keygen.c (generate_user_id), photoid.c (generate_photo_id): - Properly initialize the user ID refcount. A few more "y/n" -> - "y/N" in photoid.c. - - * keyedit.c (ask_revoke_sig): Warn the user if they are about to - revoke an expired sig (not a problem, but they should know). Also - tweak a few prompts to change "y/n" to "y/N", which is how most - other prompts are written. - - * keyserver.c (keyserver_search_prompt): Control-d escapes the - keyserver search prompt. - - * pkclist.c (show_revocation_reason & callers): If a subkey is - considered revoked solely because the parent key is revoked, print - the revocation reason from the parent key. - - * trustdb.c (get_validity): Allow revocation/expiration to apply - to a uid/key with no entry in the trustdb. - -2002-03-29 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (printunquoted): unquote backslashes from keyserver - searches - - * hkp.c (write_quoted): quote backslashes from keyserver searches - -2002-03-26 Werner Koch <wk@gnupg.org> - - * keygen.c (ask_keysize): Removed the warning for key sizes > 1536. - -2002-03-25 Werner Koch <wk@gnupg.org> - - * keyedit.c (sign_uids): Use 2 strings and not a %s so that - translations can be done the right way. - * helptext.c: Fixed small typo. - -2002-03-23 David Shaw <dshaw@jabberwocky.com> - - * import.c (append_uid, merge_sigs): it is okay to import - completely non-signed uids now (with --allow-non-selfsigned-uid). - - * getkey.c (get_primary_uid, merge_selfsigs_main): do not choose - an attribute packet (i.e. photo) as primary uid. This prevents - oddities like "Good signature from [image of size 2671]". This is - still not perfect (one can still select an attribute packet as - primary in --edit), but is closer to the way the draft is going. - - * g10.c (build_list): algorithms should include 110. - - * g10.c (main): --pgp2 implies --no-ask-sig-expire and - --no-ask-cert-expire as those would cause a v4 sig/cert. - - * armor.c (is_armor_header): be more lenient in what constitutes a - valid armor header (i.e. -----BEGIN blah blah-----) as some - Windows programs seem to add spaces at the end. --openpgp makes - it strict again. - -2002-03-18 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_search_prompt): Properly handle a "no - keys found" case from the internal HKP code (external HKP is ok). - Also, make a COUNT -1 (i.e. streamed) keyserver response a little - more efficient. - - * g10.c (main): Add --no-allow-non-selfsigned-uid - -2002-03-17 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): --openpgp implies --allow-non-selfsigned-uid. - - * getkey.c (merge_selfsigs_main): If none of the uids are primary - (because none are valid) then pick the first to be primary (but - still invalid). This is for cosmetics in case some display needs - to print a user ID from a non-selfsigned key. Also use - --allow-non-selfsigned-uid to make such a key valid and not - --always-trust. The key is *not* automatically trusted via - --allow-non-selfsigned-uid. - - * mainproc.c (check_sig_and_print): Make sure non-selfsigned uids - print [uncertain] on verification even though one is primary now. - - * getkey.c (merge_selfsigs): If the main key is not valid, then - neither are the subkeys. - - * import.c (import_one): Allow --allow-non-selfsigned-uid to work - on completely unsigned keys. Print the uids in UTF8. Remove - mark_non_selfsigned_uids_valid(). - - * keyedit.c (show_key_with_all_names): Show revocation key as - UTF8. - - * sign.c (clearsign_file): Allow --not-dash-escaped to work with - v3 keys. - -2002-03-14 Werner Koch <wk@gnupg.org> - - * main.h: Changed the default algorithms to CAST5 and SHA1. - -2002-03-13 David Shaw <dshaw@jabberwocky.com> - - * import.c (chk_self_sigs): Show which user ID a bad self-sig - (invald sig or unsupported public key algorithm) resides on. - - * import.c (chk_self_sigs): any valid self-sig should mark a user - ID or subkey as valid - otherwise, an attacker could DoS the user - by inventing a bogus invalid self-signature. - -2002-03-07 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): make a few more strings translatable. - - * options.h, options.skel, g10.c (main), gpgv.c, mainproc.c - (check_sig_and_print), keyserver.c (parse_keyserver_options): - --auto-key-retrieve should really be a keyserver-option variable. - - * import.c (revocation_present): new function to print a warning - if a key is imported that has been revoked by designated revoker, - but the designated revoker is not present to verify the - revocation. If keyserver-options auto-key-retrieve is set, try - and fetch the designated revoker from the keyserver. - - * import.c (import_one): call revocation_present after importing a - new key. Note that this applies to --import, --recv-keys, and - --search-keys. - - * keyserver-internal.h, keyserver.c (keyserver_import_fprint): - import via fingerprint (for revocation keys). - - * keyserver.c (keyserver_import_keyid): much simpler - implementation now that we're using KEYDB_SEARCH_DESC internally. - -2002-03-04 David Shaw <dshaw@jabberwocky.com> - - * revoke.c (gen_revoke): do not prompt for revocation reason for - v3 revocations (unless force-v4-certs is on) since they wouldn't - be used anyway. - - * keyedit.c (menu_revsig): show the status of the sigs - (exportable? revocable?) to the user before prompting for which - sig to revoke. Also, make sure that local signatures get local - revocations. - - * keyedit.c (ask_revoke_sig): remind the user which sigs are - local. - - * g10.c (main): Add "exec-path" variable to override PATH for - execing programs. - - * export.c (do_export_stream): properly check return code from - classify_user_id to catch unclassifiable keys. - -2002-03-03 David Shaw <dshaw@jabberwocky.com> - - * parse-packet.c (parse_signature): variable type tweak for RISC - OS (from Stefan) - -2002-02-28 David Shaw <dshaw@jabberwocky.com> - - * getkey.c (check_revocation_keys): New function to check a - revocation against a list of potential revocation keys. Note the - loop-breaking code here. This is to prevent blowing up if A is - B's revocation key, while B is also A's. Note also that this is - written so that a revoked revoker can still issue revocations: - i.e. If A revokes B, but A is revoked, B is still revoked. I'm - not completely convinced this is the proper behavior, but it - matches how PGP does it. It does at least have the advantage of - much simpler code - my first version of this had lots of loop - maintaining code so you could chain revokers many levels deep and - if D was revoked, C was not, which meant that B was, and so on. - It was sort of scary, actually. - - * getkey.c (merge_selfsigs_main): Add any revocation keys onto the - pk. This is particularly interesting since we normally only get - data from the most recent 1F signature, but you need multiple 1F - sigs to properly handle revocation keys (PGP does it this way, and - a revocation key could be marked "sensitive" and hence in a - different signature). Also, if a pk has a revocation key set, - check for revocation sigs that were not made by us - if made by a - valid revocation key, mark the pk revoked. - - * packet.h, getkey.c (cache_public_key): do not cache key if - "dont_cache" is set. This allows the revocation key code to look - up a key and return information that may be inaccurate to prevent - loops without caching the fake data. - - * packet.h, sig-check.c (do_signature_check): Record if a - signature was made by a revoked pk. - - * packet.h, parse-packet.c (parse_one_sig_subpkt, - can_handle_critical, parse_signature): Get revocation key - information out of direct sigs. - - * keylist.c (list_keyblock_print): don't assume that the presence - of a 0x20 signature means the key is revoked. With revocation - keys, this may not be true if the revocation key is not around to - verify it or if verification failed. Also, 0x1F should get listed - as "sig", and not "unexpected signature class". - - * keyedit.c (show_key_with_all_names): Add a flag for printing - revoker information and change all callers. - - * import.c (merge_blocks): merge in any new direct key (0x1F) - sigs. - - * import.c (import_revoke_cert): don't keep processing after a - revocation is rejected. - - * import.c (delete_inv_parts): Allow importing a revocation - signature even if it was not issued by the key. This allows a - revocation key to issue it. Of course, the sig still needs to be - checked before we trust it. - - * free-packet.c (copy_public_key): Include a new copy of the - revocation keys when duping a pk. - - * free-packet.c (free_seckey_enc, release_public_key_parts): Free - any revocation keys that are attached to a sig or pk. - - * export.c (do_export_stream): Do not export signatures with - "sensitive" revocation keys in them. - -2002-02-27 David Shaw <dshaw@jabberwocky.com> - - * export.c (do_export_stream): Do not include v3 keys in a - --export-secret-subkeys export. - - * getkey.c (merge_selfsigs_main): If a key isn't valid (say, - because of no self-signature), allow --always-trust to force it - valid so it can be trusted. - -2002-02-25 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (hkp_ask_import), hkp.h, keyserver.c (all): treat key - lists internally as fingerprints when possible. All this is via - KEYDB_SEARCH_DESC - no point in reinventing the wheel. This allows - the helper program to search the keyserver by fingerprint if - desired (and the keyserver supports it). Note that automatic - fingerprint promotion during refresh only applies to v4 keys as a - v4 fingerprint can be easily changed into a long or short key id, - and a v3 cannot. - - * pubkey-enc.c, getkey.c, misc.c, main.h: Take two copies of - hextobyte() from pubkey-enc.c and getkey.c and make them into one - copy in misc.c. - -2002-02-22 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_search_prompt): Detect a "no keys found" - case even if the helper program does not explicitly say how many - keys were found. - - * hkp.c (parse_hkp_index): Bug fix - don't report non-revoked keys - as revoked in HKP key searches. - -2002-02-19 Werner Koch <wk@gnupg.org> - - * parse-packet.c (parse_trust): Made parsing more robust. - -2002-02-19 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (parse_hkp_index): Catch corruption in HKP index lines - (can be caused by broken or malicious keyservers). - - * keyserver.c (keyserver_work): Add KEYSERVER_NOT_SUPPORTED for - unsupported actions (say, a keyserver that has no way to search, - or a readonly keyserver that has no way to add). Also add a - USE_EXTERNAL_HKP define to disable the internal HKP keyserver - code. - -2002-02-14 Werner Koch <wk@gnupg.org> - - * g10.c: New option --no-use-agent. - - * pkclist.c (check_signatures_trust): Always print the warning for - unknown and undefined trust. Removed the did_add cruft. Reported - by Janusz A. Urbanowicz. - -2002-02-11 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (parse_hkp_index): Bug fix - properly handle user IDs with - colons (":") in them while HKP searching. - -2002-02-09 David Shaw <dshaw@jabberwocky.com> - - * misc.c (pct_expando): More comments. - - * keydb.h, sign.c (mk_notation_and_policy): Clarify what is a sig - and what is a cert. A sig has sigclass 0x00, 0x01, 0x02, or 0x40, - and everything else is a cert. - - * g10.c (main), keyedit.c (keyedit_menu): Add a "nrlsign" for - nonrevocable and local key signatures. - - * g10.c (main): Add a --no-force-mdc to undo --force-mdc. - - * options.h, g10.c (main), cipher.c (write_header): Add a knob to - --disable-mdc/--no-disable-mdc. Off by default, of course, but is - used in --pgp2 and --pgp6 modes. - - * pkclist.c (build_pk_list): Allow specifying multiple users in - the "Enter the user ID" loop. Enter a blank line to stop. Show - each key+id as it is added. - - * keylist.c (show_policy_url), mainproc.c (print_notation_data): - It is not illegal (though possibly silly) to have multiple policy - URLs in a given signature, so print all that are present. - - * hkp.c (hkp_search): More efficient implementation of URL-ifying - code. - -2002-02-04 David Shaw <dshaw@jabberwocky.com> - - * main.h, misc.c (pct_expando): New function to generalize - %-expando processing in any arbitrary string. - - * photoid.c (show_photo): Call the new pct_expando function rather - than expand strings internally. - - * sign.c (mk_notation_and_policy): Show policy URLs and notations - when making a signature if show-policy/show-notation is on. - %-expand policy URLs during generation. This lets the user have - policy URLs of the form "http://notary.jabberwocky.com/keysign/%K" - which will generate a per-signature policy URL. - - * main.h, keylist.c (show_policy_url, show_notation): Add amount - to indent so the same function can be used in key listings as well - as during sig generation. Change all callers. - -2002-02-04 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c, options.h (parse_keyserver_options, keyidlist): - Workaround for the pksd and OKS keyserver bug that calculates v4 - RSA keyids as if they were v3. The workaround/hack is to fetch - both the v4 (e.g. 99242560) and v3 (e.g. 68FDDBC7) keyids. This - only happens for key refresh while using the HKP scheme and the - refresh-add-fake-v3-keyids keyserver option must be set. This - should stay off by default. - -2002-02-03 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_spawn): Bug fix - do not append keys to - each other when --sending more than one. - -2002-02-02 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), keyedit.c (sign_uids), sign.c - (mk_notation_and_policy): Split "--set-policy-url" into - "--cert-policy-url" and "--sig-policy-url" so the user can set - different policies for key and data signing. For backwards - compatibility, "--set-policy-url" sets both, as before. - -2002-01-30 Werner Koch <wk@gnupg.org> - - * g10.c (main): --gen-random --armor does now output a base64 - encoded string. - -2002-01-28 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main), options.h, pkclist.c (algo_available): --pgp6 - flag. This is not nearly as involved as --pgp2. In short, it - turns off force_mdc, turns on no_comment, escape_from, and - force_v3_sigs, and sets compression to 1. It also restricts the - user to IDEA (if present), 3DES, CAST5, MD5, SHA1, and RIPEMD160. - See the comments above algo_available() for lots of discussion on - why you would want to do this. - -2002-01-27 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (keygen_set_std_prefs): Comment - - * keyedit.c (sign_uids): Bug fix - when signing with multiple - secret keys at the same time, make sure each key gets the sigclass - prompt. - - * exec.c (exec_finish): Close the iobuf and FILE before trying to - waitpid, so the remote process will get a SIGPIPE and exit. This - is only a factor when using a pipe to communicate. - - * exec.c (exec_write): Disable cache-on-close of the fd iobuf (is - this right? Why is a fd iobuf cached at all?) - -2002-01-26 Werner Koch <wk@gnupg.org> - - * g10.c, options.h: New option --gpg-agent-info - * passphrase.c (agent_open): Let it override the environment info. - * seckey-cert.c (check_secret_key): Always try 3 times when the - agent is enabled. - * options.skel: Describe --use-agent. - -2002-01-24 David Shaw <dshaw@jabberwocky.com> - - * pubkey-enc.c (is_algo_in_prefs, get_it): Only check preferences - against keys with v4 self sigs - there is really little point in - warning for every single non-IDEA message encrypted to an old key. - - * pkclist.c (select_algo_from_prefs): Only put in the fake IDEA - preference if --pgp2 is on. - - * mainproc.c (check_sig_and_print): Print "Expired" for expired - but good signatures (this still prints "BAD" for expired but bad - signatures). - -2002-01-23 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (ask_keysize): Cosmetic: don't present a RSA signing - key as a "keypair" which can be 768 bits long (as RSA minimum is - 1024). - - * pubkey-enc.c (is_algo_in_prefs): Allow IDEA as a fake preference - for v3 keys with v3 selfsigs. - -2002-01-22 David Shaw <dshaw@jabberwocky.com> - - * packet.h, getkey.c (merge_selfsigs_main), pkclist.c - (select_algo_from_prefs): Implement the fake IDEA preference as - per RFC2440:12.1. This doesn't mean that IDEA will be used (the - plugin may not be present), but it does mean that a v3 key with a - v3 selfsig has an implicit IDEA preference instead of 3DES. v3 - keys with v4 selfsigs use preferences as normal. - - * encode.c (encode_crypt): if select_algo_from_prefs fails, this - means that we could not find a cipher that both keys like. Since - all v4 keys have an implicit 3DES preference, this means there is - a v3 key with a v3 selfsig in the list. Use 3DES in this case as - it is the safest option (we know the v4 key can handle it, and - we'll just hope the v3 key is being used in an implementation that - can handle it). If --pgp2 is on, warn the user what we're doing - since it'll probably break PGP2 compatibility. - - * g10.c (main): Do not force using IDEA for encrypted files in - --pgp2 mode - let the fake IDEA preference choose this for us for - better compatibility when encrypting to multiple keys, only some - of which are v3. - - * keygen.c (keygen_set_std_prefs): Put 3DES on the end of the - default cipher pref list (RFC2440: "...it is good form to place it - there explicitly."). If the user has the IDEA plugin installed, - put a preference for IDEA *after* 3DES to effectively disable its - use for everything except encrypting along with v3 keys. - - * encode.c, g10.c, sign.c: Change the PGP2 warning line from - "... will not be usable ..." to "... may not be usable ..." as the - user could be using one of the enhanced PGP2 variations. - - * helptext.c: Revise the sign_uid.class help text as suggested by - Stefan. - -2002-01-20 Werner Koch <wk@gnupg.org> - - * passphrase.c (passphrase_to_dek): Add tryagain_text arg to be - used with the agent. Changed all callers. - (agent_get_passphrase): Likewise and send it to the agent - * seckey-cert.c (do_check): New arg tryagain_text. - (check_secret_key): Pass the string to do_check. - * keygen.c (ask_passphrase): Set the error text is required. - * keyedit.c (change_passphrase): Ditto. - - * passphrase.c (agent_open): Disable opt.use_agent in case of a - problem with the agent. - (agent_get_passphrase): Ditto. - (passphrase_clear_cache): Ditto. - -2002-01-19 Werner Koch <wk@gnupg.org> - - * passphrase.c (agent_open): Add support for the new Assuan based - gpg-agent. New arg to return the used protocol version. - (agent_get_passphrase): Implemented new protocol here. - (passphrase_clear_cache): Ditto. - (readline): New. - -2002-01-15 Timo Schulz <ts@winpt.org> - - * encode.c (encode_crypt_files): Fail if --output is used. - - * g10.c: New command --decrypt-files. - - * decrypt.c (decrypt_messages): New. - -2002-01-09 David Shaw <dshaw@jabberwocky.com> - - * g10.c, misc.c, gpgv.c: move idea_cipher_warn to misc.c so gpgv.c - doesn't need a stub for it any longer. - - * g10.c (get_temp_dir), main.h: no longer used (it's in exec.c now) - - * g10.c (main), delkey.c (delete_keys), main.h : Allow - --delete-key (now --delete-keys, though --delete-key still works, - of course) to delete multiple keys in one go. This applies to - --delete-secret-key(s) and --delete-secret-and-public-key(s) as - well. - -2002-01-09 Timo Schulz <ts@winpt.org> - - * encode.c (encode_crypt_files): Now it behaves like verify_files. - - * g10.c (main): We don't need to check argc for encode_crypt_files - any longer. - -2002-01-09 Timo Schulz <ts@winpt.org> - - * exec.c: Include windows.h for dosish systems. - -2002-01-08 Timo Schulz <ts@winpt.org> - - * g10.c (main): New description for --encrypt-files. - -2002-01-08 Werner Koch <wk@gnupg.org> - - * g10.c (main): Must register the secring for encryption because - it is needed to figure out the default recipient. Reported by - Roger Sondermann. - -2002-01-05 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_adduid): Require --expert before adding a photo - ID to a v3 key, and before adding a second photo ID to any key. - - * keyedit.c (keyedit_menu): Don't allow adding photo IDs in - rfc1991 or pgp2 mode. - - * getkey.c (merge_selfsigs_subkey): Permit v3 subkeys. Believe it - or not, this is allowed by rfc 2440, and both PGP 6 and PGP 7 work - fine with them. - - * g10.c, options.h, keyedit.c, sign.c: Move the "ask for - expiration" switch off of --expert, which was getting quite - overloaded, and onto ask-sig-expire and ask-cert-expire. Both - default to off. - - * g10.c (main): Change the default compression algo to 1, to be - more OpenPGP compliant (PGP also uses this, so it'll help with - interoperability problems as well). - - * encode.c (encode_crypt): Handle compression algo 2, since the - default is now 1. - - * build-packet.c (build_attribute_subpkt): Fix off-by-one error. - -2002-01-05 Werner Koch <wk@gnupg.org> - - * g10.c (main): Do not register the secret keyrings for certain - commands. - - * keydb.c (keydb_add_resource): Use access to test for keyring - existence. This avoids cached opened files which are bad under - RISC OS. - -2002-01-04 David Shaw <dshaw@jabberwocky.com> - - * sign.c (sign_file, sign_symencrypt_file): always use one-pass - packets unless rfc1991 is enabled. This allows a signature made - with a v3 key to work in PGP 6 and 7. Signatures made with v4 - keys are unchanged. - - * g10.c (main): Disallow non-detached signatures in PGP2 mode. - Move the "you must use files and not pipes" PGP2 warning up so all - the PGP2 stuff is together. - - * encode.c (encode_simple): Use the actual filesize instead of - partial length packets in the internal literal packet from a - symmetric message. This breaks PGP5(?), but fixes PGP2, 6, and 7. - It's a decent tradeoff. Note there was only an issue with - old-style RFC1991 symmetric messages. 2440-style messages in 6 - and 7 work with or without partial length packets. - -2002-01-03 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Removed --no-default-check-level option, as it is - not consistent with other "default" options. Plus, it is the same - as saying --default-check-level 0. - - * exec.c (exec_read): Disallow caching tempfile from child - process, as this keeps the file handle open and can cause unlink - problems on some platforms. - - * keyserver.c (keyserver_search_prompt): Minor tweak - don't - bother to transform keyids into textual form if they're just going - to be transformed back to numbers. - -2002-01-03 Timo Schulz <ts@winpt.org> - - * g10.c: New command --encrypt-files. - - * verify.c (print_file_status): Removed the static because - encode_crypt_files also uses this function. - - * main.h (print_files_status): New. - (encode_crypt_files): New. - - * encode.c (encode_crypt_files): New. - -2002-01-02 Stefan Bellon <sbellon@sbellon.de> - - * keyserver.c: Moved util.h include down in order to avoid - redefinition problems on RISC OS. - - * keyring.c (keyring_lock): Only lock keyrings that are writable. - - * keyring.c (keyring_update_keyblock): Close unused iobuf. - - * hkp.c (parse_hkp_index, hkp_search) [__riscos__]: Changed - unsigned char* to char* because of compiler issues. - - * exec.c (exec_finish) [__riscos__]: Invalidate close cache so - that file can be unlinked. - -2001-12-28 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Use a different strlist to check extensions since - they need to be handled seperately now. - - * misc.c,main.h (check_permissions): Properly handle permission - and ownership checks on files in the lib directory - (e.g. /usr/local/lib/gnupg), which are owned by root and are - world-readable, and change all callers to specify extension or - per-user file. - - * photoid.c (show_photo), keyserver.c (keyserver_spawn): Bug fix - - don't call exec_finish if exec_write fails. - - * keyserver.c (keyserver_spawn): Look for OPTIONS from the - keyserver helper - specifically, a "OUTOFBAND" option for the - email keyserver. - - * mainproc.c (list_node), keylist.c (list_keyblock_colon), - import.c (delete_inv_parts), export.c (do_export_stream): Use - signature flags for exportability check rather than re-parsing the - subpacket. - - * keyid.c, keydb.h (get_lsign_letter): No longer needed. - -2001-12-27 David Shaw <dshaw@jabberwocky.com> - - * exec.c (exec_finish): Show errors when temp files cannot be - deleted for whatever reason. - - * exec.c (exec_read): Don't rely on WEXITSTATUS being present. - - * exec.c (make_tempdir): Add temp file creator for win32. Don't - create an incoming temp file if the exec is write-only. - - * keyserver.c (keyserver_spawn): Clean up error handling, for when - the spawn fails. - - * photoid.c (show_photo): Clean up error handling. - - * misc.c (check_permissions): Neaten. - -2001-12-25 David Shaw <dshaw@jabberwocky.com> - - * mkdtemp.c (mkdtemp): Add copyleft info and tweak the 'X' counter - to be a bit simpler. - - * keyserver.c, photoid.c: Remove unused headers left over from - when the exec functions lived there. - -2001-12-23 Timo Schulz <ts@winpt.org> - - * misc.c (check_permissions): Do not use it for W32 systems. - - * tdbio.c (migrate_from_v2): Define ftruncate as chsize() for W32. - - * mkdtemp.c: W32 support. - - * photoid.c: Ditto. - - * exec.c: Ditto. - -2001-12-22 David Shaw <dshaw@jabberwocky.com> - - * exec.c (make_tempdir): avoid compiler warning with const - - * mkdtemp.c (mkdtemp): catch the empty ("") string case in case - someone repurposes mkdtemp at some point. - - * photoid.c (generate_photo_id, show_photo): some type changes - from Stefan Bellon. - - * exec.c (make_tempdir): handle Win32 systems, suggested by Timo - Schulz. - -2001-12-22 Werner Koch <wk@gnupg.org> - - * encode.c (encode_simple, encode_crypt): i18n 2 strings. - -2001-12-22 Timo Schulz <ts@winpt.org> - - * encode.c (encode_simple, encode_crypt): Use is_file_compressed - to avoid to compress compressed files. - -2001-12-22 Werner Koch <wk@gnupg.org> - - * keyserver.c (keyserver_spawn): Removed some variables - declaration due to shadowing warnings. - - * build-packet.c (build_attribute_subpkt): s/index/idx/ to avoid - compiler warnig due to index(3). - - * getkey.c (get_ctx_handle): Use KEYDB_HANDLE as return value. - * keylist.c (list_one): Made resname const. - - * keyedit.c (keyedit_menu): Allow "addphoto" only when --openpgp is - not used. - - * options.skel: Changed one example photo viewer to qiv. - -2001-12-21 David Shaw <dshaw@jabberwocky.com> - - * Makefile.am: add exec.c, exec.h, photoid.c, and photoid.h - - * build-packet.c (build_attribute_subpkt): new function to build - the raw attribute subpacket. Note that attribute subpackets have - the same format as signature subpackets. - - * exec.c: new file with generic exec-a-program functionality. - Used by both photo IDs and keyserver helpers. This is pretty much - the same code that used to be keyserver specific, with some - changes to be usable generically. - - * free-packet.c (free_attributes (new)): function to free an - attribute packet. - - * gpgv.c: added stub show_photo - - * keyedit.c (keyedit_menu, menu_adduid, menu_showphoto): can add a - photo (calls generate_photo_id), or display a photo (calls - show_photo) from the --edit menu. New commands are "addphoto", - and "delphoto" (same as "deluid"). - - * keylist.c (list_keyblock_print): show photos during key list if - --show-photos enabled. - - * keyserver.c (keyserver_spawn): use the generic exec_xxx - functions to call keyserver helper. - - * g10.c, options.h: three new options - --{no-}show-photos, and - --photo-viewer to give the command line to display a picture. - - * options.skel: instructions for the photo viewer - - * parse-packet.c (parse_user_id, setup_user_id (new)): common code - for both user IDs and attribute IDs moved to setup_user_id. - - * parse-packet.c (make_attribute_uidname (new)): constructs a fake - "name" for attribute packets (e.g. "[image of size ...]") - - * parse-packet.c (parse_attribute (replaces parse_photo_id), - parse_attribute_subpkts): Builds an array of individual - attributes. Currently only handles attribute image / type jpeg - subpackets. - - * sign.c (hash_uid): Fix bug in signing attribute (formerly - photo_id) packets. - - * packet.h, and callers: globally change "photo_id" to "attribute" - and add structures for attributes. The packet format is generic - attributes, even though the only attribute type thus far defined - is jpeg. - -2001-12-21 David Shaw <dshaw@jabberwocky.com> - - * parse-packet.c (can_handle_critical): Can handle critical - revocation subpackets now. - - * trustdb.c (mark_usable_uid_certs): Disregard revocations for - nonrevocable sigs. Note that this allows a newer revocable - signature to override an older nonrevocable signature. - - * sign.c (make_keysig_packet): add a duration field and change all - callers. This makes make_keysig_packet closer to - write_signature_packets and removes some duplicated expiration - code. - - * keyedit.c (keyedit_menu, menu_revsig, sign_uids, - sign_mk_attrib): Add nrsign command, don't allow revoking a - nonrevocable signature, - - * g10.c (main): Add --nrsign option to nonrevocably sign a key - from the command line. - - * build-packet.c (build_sig_subpkt_from_sig): Comment to explain - the use of CRITICAL. - -2001-12-21 Werner Koch <wk@gnupg.org> - - * g10.c. options.h : New option --show-keyring - * getkey.c (get_ctx_handle): New. - * keylist.c (list_one): Implement option here. By David Champion. - -2001-12-20 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_spawn): Use mkdtemp() to make temp - directory. - - * mkdtemp.c: replacement function for those platforms that don't - have mkdtemp (make a temp directory securely). - -2001-12-19 David Shaw <dshaw@jabberwocky.com> - - * misc.c (check_permissions): New function to stat() and ensure - the permissions of GNUPGHOME and the files have safe permissions. - - * keydb.c (keydb_add_resource): Check keyring permissions. - - * tdbio.c (tdbio_set_dbname): Check permissions of trustdb.gpg - - * keyserver.c (keyserver_spawn): Disable keyserver schemes that - involve running external programs if the options file has unsafe - permissions or ownership. - - * g10.c, options.h: New option --no-permission-warning to disable - the permission warning message(s). This also permits use of the - keyserver if it had been disabled (see above). Also check the - permissions/ownership of random_seed. - - * keyserver.c (keyserver_spawn): The new glibc prints a warning - when using mktemp() (the code was already secure, but the warning - was bound to cause confusion). Use a different implementation - based on get_random_bits() instead. Also try a few times to get - the temp dir before giving up. - -2001-12-19 Werner Koch <wk@gnupg.org> - - * g10.c, passphrase.c [CYGWIN32]: Allow this as an alias for MINGW32. - -2001-12-18 David Shaw <dshaw@jabberwocky.com> - - * g10.c (idea_cipher_warn): Add a flag to show the warning always - or once per session and change all callers (show always except for - the secret key protection and unknown cipher from an encrypted - message errors). Also make the strings translatable. - - * pubkey-enc.c (get_it): Add the IDEA cipher warning if the user - tries to decrypt an IDEA encrypted message without the IDEA - plugin. - - * keyserver.c (parse_keyserver_uri): More strict checking of the - keyserver URI. Specifically, fail if the ":port" section is - anything except a number between 1 and 65535. - -2001-12-17 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (print_keyinfo): No need to check for - control/illegal characters, as utf8_to_native does this for us. - - * mainproc.c (proc_encrypted): Use generic IDEA warning. - - * gpgv.c: add stub for idea_cipher_warn - - * g10.c, hkp.c, keyserver.c: Fix capitalization and plural issues. - - * encode.c (encode_crypt), sign.c (sign_file, clearsign_file): - disable pgp2 mode after the message is no longer pgp2 compatible. - - * g10.c (main): Tweak the PGP2.x IDEA warning to use the generic - warning, and not merely fail if the IDEA plugin isn't there. - - * g10.c (main, idea_cipher_warn), keygen.c (set_one_pref), - seckey-cert.c (do_check): Add a generic IDEA warning for when the - IDEA plugin is not present. This pops up when the user uses - "--cipher-algo idea", when setpref is used to set a "S1" - preference, and when a secret key protected with IDEA is used. - -2001-12-15 Werner Koch <wk@gnupg.org> - - * keyserver.c (keyserver_spawn): Assert that we have dropped privs. - -2001-12-13 Werner Koch <wk@gnupg.org> - - * pubkey-enc.c (get_session_key): Check that the public key - algorithm is indeed usable for en/decryption. This avoid a - strange error message from pubkey_decrypt if for some reasons a - bad algorithm indentifier is passed. - -2001-12-12 David Shaw <dshaw@jabberwocky.com> - - * Fixed some types for portability. Noted by Stefan Bellon. - -2001-12-11 Werner Koch <wk@gnupg.org> - - * hkp.c (hkp_export): Do not print possible control characters - from a keyserver response. - (parse_hkp_index): Made uid an unsigned char* because it is passed to - isspace(). - (hkp_search): Ditto for the char* vars. - - * g10.c (main): Print the IDEA warning also for -c and -se. - - * g10.c (get_temp_dir): Assert that we have dropped privs - - * encode.c (encode_crypt): Include the first key into the --pgp2 - check. - -2001-12-07 David Shaw <dshaw@jabberwocky.com> - - * g10.c, options.h: New option --pgp2. This is identical to - "--rfc1991 --cipher-algo idea --compress-algo 1 --digest-algo md5 - --force_v3_sigs" with the addition of an warning to advise the - user not to use a pipe (which would break pgp2 compatibility). - - * encode.c (encode_crypt): warn if the user tries to encrypt to - any key that is not RSA and <= 2048 bits when the --pgp2 option is - used. - - * sign.c (sign_file, clearsign_file): When using --pgp2, make a v3 - sig, and warn if the signature is made with a non-v3 key. - -2001-12-05 David Shaw <dshaw@jabberwocky.com> - - * sign.c (sign_file, clearsign_file, sign_symencrypt_file): Prompt - for sig expiration if --expert is set and --force-v3-sigs is not - set (v3 sigs cannot expire). - - * mainproc.c (check_sig_and_print): After checking a sig, print - expiration status. This causes a error return if the sig is - expired. - - * build-packet.c (build_sig_subpkt_from_sig): Include a critical - sig expiration subpacket if the sig is to expire. - - * keyedit.c (sign_uids): Do not sign an expired key unless - --expert is set, in which case prompt. Also, offer to expire a - signature when the key the user is signing expires. - - * keygen.c (ask_expire_interval): Add a value to determine whether - to prompt for a key or sig expiration and change all callers. - - * keyid.c: New functions: expirestr_from_sig and - colon_expirestr_from_sig. - - * keylist.c (list_keyblock_colon): Show sig expiration date in the - --with-colons listing. - - * sign.c (make_keysig_packet, write_signature_packets): Pass in an - optional timestamp for the signature packet, and change all - callers. - - * keyedit.c (sign_mk_attrib): Include a critical expiration - subpacket in the signature if an expiration date is given. - -2001-12-04 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (sign_uids): If the user tries to sign a - locally-signed key, allow the cert to be promoted to a full - exportable signature. This essentially deletes the old - non-exportable sig, and replaces it with a new exportable one. - -2001-12-04 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (keyedit_menu): Do not allow signing a revoked key - unless --expert is set, and ask even then. - - * keyedit.c (sign_uids): Do not allow signing a revoked UID unless - --expert is set, and ask even then. - - * g10.c, options.h : New option --expert - -2001-11-16 David Shaw <dshaw@jabberwocky.com> - - * Allow the user to select no compression via "--compress-algo 0" - on the command line. - - * keyedit.c (show_prefs): Show compression preferences in the - long-form "showpref" style. - - * keygen.c (set_one_pref): Permit setting a no-compression ("Z0") - preference. - - * getkey.c (fixup_uidnode): Fix compression preference corruption - bug. - -2001-12-02 David Shaw <dshaw@jabberwocky.com> - - * g10.c: Add advisory --for-your-eyes-only option as per section - 5.9 of 2440. - -2001-12-05 David Shaw <dshaw@jabberwocky.com> - - * Force a V4 sig if the user has a notation or policy URL set. - -2001-12-04 David Shaw <dshaw@jabberwocky.com> - - * g10.c: Add options --keyserver-options, --temp-directory, and - auto-key-retrieve (the opposite of no-auto-key-retrieve). - - * hkp.c (hkp_search): New function to handle searching a HKP - keyserver for a key - - * hkp.c (hkp_ask_import, hkp_export): Pretty large changes to make - them communicate via the generic functions in keyserver.c - - * keyserver.c: new file with generic keyserver routines for - getting keys from a keyserver, sending keys to a keyserver, and - searching for keys on a keyserver. Calls the internal HKP stuff - in hkp.c for HKP keyserver functions. Other calls are handled by - an external program which is spawned and written to and read from - via pipes. Platforms that don't have pipes use temp files. - -2001-11-20 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c: New options show-notation, no-show-notation, - default-check-level, no-default-check-level, show-policy-url, - no-show-policy-url. - - * packet.h, sign.c (make_keysig_packet), parse-packet.c - (parse_signature), free-packet.c (free_seckey_enc): Fill in - structures for notation, policy, sig class, exportability, etc. - - * keyedit.c, keylist.c (print_and_check_one_sig, - list_keyblock_print): Show flags in signature display for cert - details (class, local, notation, policy, revocable). If selected, - show the notation and policy url. - - * keyedit.c (sign_uids): Prompt for and use different key sig - classes. - - * helptext.c (helptexts): Add help text to explain different - key signature classes - -2001-11-26 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (mark_usable_uid_certs): Fix segfault from bad - initialization and fix reversed key signature expiration check. - -2001-11-09 Werner Koch <wk@gnupg.org> - - * export.c (do_export_stream): Put all given names into a search - description and change the loop so that all matching names are - returned. - -2001-11-08 Werner Koch <wk@gnupg.org> - - * pubkey-enc.c (get_it): To reduce the number of questions on the - MLs print the the name of cipher algorithm 1 with the error message. - - * mainproc.c: Changed the way old rfc1991 encryption cipher is - selected. Based on a patch by W Lewis. - - * pkclist.c (do_edit_ownertrust): Allow to skip over keys, the non - working "show info" is now assigned to "i" - * trustdb.c (ask_ownertrust, validate_keys): Implement a real quit - here. Both are by David Shaw. - - * trustdb.c (validate_keys): Make sure next_exipire is initialized. - - * sign.c (make_keysig_packet): Use SHA-1 with v4 RSA keys. - - * g10.c, options.h : New option --[no-]froce-v4-certs. - * sign.c (make_keysig_packet): Create v4 sigs on v4 keys even with - a v3 key. Use that new option. By David Shaw - - * revoke.c (ask_revocation_reason): Allow to select "no reason". - By David Shaw. - - * keyid.c (fingerprint_from_sk): Calculation of an v3 fpr was - plain wrong - nearly the same code in fingerprint_from_pk is correct. - - * build-packet.c (do_secret_key): Added a few comments to the code. - -2001-11-07 Werner Koch <wk@gnupg.org> - - * g10.c (main): Print a warning when -r is used w/o encryption. - Suggested by Pascal Scheffers. - -2001-10-23 Werner Koch <wk@gnupg.org> - - * keyedit.c (keyedit_menu): Changed helptext for showpref - command. Suggested by Reinhard Wobst. - - * keyring.c (keyring_search): When marking the offtbl ready, take - into account that we may have more than one keyring. - -2001-10-22 Werner Koch <wk@gnupg.org> - - * Makefile.am: Do not use OMIT_DEPENDENCIES - - * build-packet.c (build_sig_subpkt): Default is now to put all - types of subpackets into the hashed area and only list those which - should go into the unhashed area. - -2001-10-18 Werner Koch <wk@gnupg.org> - - * keydb.c (keydb_add_resource): Rearranged the way we keep track - of the resource. There will now be an entry for each keyring here - and not in keyring.c itself. Store a token to allow creation of a - keyring handle. Changed all functions to utilize this new design. - (keydb_locate_writable): Make a real implementation. - * keyring.c (next_kr): Removed and changed all callers to set the - resource directly from the one given with the handle. - (keyring_is_writable): New. - (keyring_rebuild_cache): Add an arg to pass the token from keydb. - -2001-10-17 Werner Koch <wk@gnupg.org> - - * keyring.c (keyring_search): Enabled word search mode but print a - warning that it is buggy. - -2001-10-11 Werner Koch <wk@gnupg.org> - - * hkp.c (hkp_ask_import): No more need to set the port number for - the x-hkp scheme. - (hkp_export): Ditto. - -2001-10-06 Stefan Bellon <sbellon@sbellon.de> - - * passphrase.c [__riscos__]: Disabled agent specific stuff. - * g10.c: New option --no-force-v3-sigs. - -2001-10-04 Werner Koch <wk@gnupg.org> - - * export.c (do_export_stream): Do not push the compress filter - here because the context would run out of scope due to the - iobuf_close done by the caller. - (do_export): Do it here instead. - -2001-09-28 Werner Koch <wk@gnupg.org> - - * keyedit.c (sign_uids): Always use the primary key to sign keys. - * getkey.c (finish_lookup): Hack to return only the primary key if - a certification key has been requested. - - * trustdb.c (cmp_kid_for_make_key_array): Renamed to - (validate_one_keyblock): this and changed arg for direct calling. - (make_key_array): Renamed to - (validate_one_keyblock): this and changed args for direct calling. - (mark_usable_uid_certs, validate_one_keyblock) - (validate_key_list): Add next_expire arg to keep track of - expiration times. - (validate_keys): Ditto for UTKs and write the stamp. - - * tdbio.c (migrate_from_v2): Check return code of tbdio_sync. - - * tdbdump.c (import_ownertrust): Do a tdbio_sync(). - - * keyring.c: Made the offtbl an global object. - -2001-09-27 Werner Koch <wk@gnupg.org> - - * pkclist.c (do_edit_ownertrust): Allow settin of ultimate trust. - - * trustdb.c (mark_keyblock_seen): New. - (make_key_array): Use it to mark the subkeys too. - (validate_keys): Store validity for ultimatly trusted keys. - -2001-09-26 Werner Koch <wk@gnupg.org> - - * pkclist.c (check_signatures_trust, do_we_trust): Removed the - invocation of add_ownertrust. Minor changes to the wording. - (add_ownertrust, add_ownertrust_cb): Removed. - - * trustdb.c (get_validity): Allow to lookup the validity using a - subkey. - - * trustdb.c (new_key_hash_table): Increased the table size to 1024 - and changed the masks accordingly. - (validate): Changed stats printing. - (mark_usable_uid_certs): New. - (cmp_kid_for_make_key_array): Does now check the signatures and - figures out a usable one. - -2001-09-25 Werner Koch <wk@gnupg.org> - - * keyring.c (new_offset_item,release_offset_items) - (new_offset_hash_table, lookup_offset_hash_table) - (update_offset_hash_table, update_offset_hash_table_from_kb): New. - (keyring_search): Use a offset table to optimize search for - unknown keys. - (keyring_update_keyblock, keyring_insert_keyblock): Insert new - offsets. - * getkey.c (MAX_UNK_CACHE_ENTRIES): Removed the unknown keys - caching code. - - * g10.c, options.h, import.c: Removed the entire - allow-secret-key-import stuff because the validity is now - controlled by other means. - - * g10.c: New command --rebuild-keydb-caches. - * keydb.c (keydb_rebuild_caches): New. - * keyring.c (do_copy): Moved some code to - (create_tmp_file, rename_tmp_file, write_keyblock): new functions. - (keyring_rebuild_cache): New. - - * packet.h (PKT_ring_trust): Add sigcache field. - * parse-packet.c (parse_trust): Parse sigcache. - * keyring.c (do_copy): Always insert a sigcache packet. - (keyring_get_keyblock): Copy the sigcache packet to the signature. - * sig-check.c (cache_sig_result): Renamed from - cache_selfsig_result. Changed implementation to use the flag bits - and changed all callers. - (mdc_kludge_check): Removed this unused code. - (do_check): Do not set the sig flags here. - - * import.c (read_block): Make sure that ring_trust packets are - never imported. - * export.c (do_export_stream): and never export them. - - * trustdb.c (make_key_array): Skip revoked and expired keys. - -2001-09-24 Werner Koch <wk@gnupg.org> - - * g10.c, options.h: New option --no-auto-check-trustdb. - - * keygen.c (do_generate_keypair): Set newly created keys to - ultimately trusted. - - * tdbio.h, tdbio.c: Removed all support for records DIR, KEY, UID, - PREF, SIG, SDIR and CACH. Changed migration function to work - direct on the file. - (tdbio_read_nextcheck): New. - (tdbio_write_nextcheck): New. - -2001-09-21 Werner Koch <wk@gnupg.org> - - Revamped the entire key validation system. - * trustdb.c: Complete rewrite. No more validation on demand, - removed some functions, adjusted to all callers to use the new - and much simpler interface. Does not use the LID anymore. - * tdbio.c, tdbio.h: Add new record types trust and valid. Wrote a - migration function to convert to the new trustdb layout. - * getkey.c (classify_user_id2): Do not allow the use of the "#" - prefix. - * keydb.h: Removed the TDBIDX mode add a skipfnc to the - descriptor. - * keyring.c (keyring_search): Implemented skipfnc. - - * passphrase.c (agent_open): Add missing bracket. Include windows.h. - -2001-09-19 Werner Koch <wk@gnupg.org> - - * keylist.c (print_fingerprint): Renamed from fingerprint, made - global available. Added new arg to control the print style. - * mainproc.c (print_fingerprint): Removed. - * pkclist.c (print_fpr, fpr_info): Removed and changed callers to - use print_fingerprint. - * keyedit.c (show_fingerprint): Ditto. - - * passphrase.c (writen, readn) - (agent_open, agent_close) - (agent_get_passphrase) - (passphrase_clear_cache): Support for W32. Contributed by Timo. - - * import.c (import_one): Release keydb handles at 2 more places. - - * keyring.c (keyring_release): Close the iobuf. - (keyring_get_keyblock): Init ret_kb to NULL and store error contidion. - - * import.c (import_new_stats_handle): New. - (import_release_stats_handle): New. - (import_print_stats): Renamed from static fnc print_stats. - (import_keys, import_keys_stream): Add an optional status handle - arg and changed all callers. - * hkp.c (hkp_ask_import): Add an stats_handle arg and changed all - callers. - - * mainproc.c (print_pkenc_list): Use print_utf8_string2(). - -2001-09-18 Werner Koch <wk@gnupg.org> - - * g10.c: New command --refresh-keys. - * hkp.c (hkp_refresh_keys): New. Contributed by Timo Schulz. - - * parse-packet.c (parse): Stop on impossible packet lengths. - -2001-09-17 Werner Koch <wk@gnupg.org> - - * mainproc.c (print_notation_data): Wrap notation data status lines - after 50 chars. - - * mainproc.c (proc_pubkey_enc): Make option try-all-secrets work. - By disastry@saiknes.lv. - -2001-09-14 Werner Koch <wk@gnupg.org> - - * parse-packet.c (dump_sig_subpkt): List key server preferences - and show the revocable flag correctly. Contributed by David Shaw. - -2001-09-09 Werner Koch <wk@gnupg.org> - - * keyedit.c (keyedit_menu): No need to define another p. - - * keylist.c (print_capabilities): s/used/use/ so that it - does not shadow a global. - * sign.c (sign_file): Renamed arg encrypt to encryptflag - * keygen.c: Replaced all "usage" by "use". - * misc.c (openpgp_pk_algo_usage): Ditto. - - * pubkey-enc.c (get_it): Renamed arg k to enc so that the later - defined k does not shadow it. - - * parse-packet.c (parse_gpg_control): No need to define another i. - - * getkey.c (get_pubkey_byfprint): Must use the enum values and not - the fprint_len. - * keyring.c (keyring_search): Removed a non-sense break. Both - bugs pointed out by Stefan. - -2001-09-07 Werner Koch <wk@gnupg.org> - - * status.c, status.h: Added NO_RECP and ALREADY_SIGNED. - * pkclist.c (build_pk_list): Issue NO_RECP. - * keyedit.c (sign_uids): Added experimental ALREADY_SIGNED - - * hkp.c (hkp_import): Use log_error. Bug reported by Neal H - Walfield. - - * getkey.c (classify_user_id2): Change args to take the desc union - direct. It was a stupid idea to pass the individual fields of an - union to this function. Changed all callers. - (classify_user_id): Ditto and allow to pass NULL as the description. - -2001-09-06 Werner Koch <wk@gnupg.org> - - * getkey.c (fixup_uidnode): Features flag is now a bit vector. - * keygen.c (add_feature_mdc): Ditto. - - Revamped the entire key I/O code to be prepared for other ways of - key storages and to get rid of the existing shit. GDBM support has - gone. - * keydb.c: New - * keyring.c, keyring.h: New. - * ringedit.c: Removed. Moved some stuff to keyring.c - * getkey.c: Changed everything related to the key retrieving - functions which are now using the keydb_ functions. - (prepare_search, word_match_chars, word_match) - (prepare_word_match, compare_name): Moved to keyring.c - (get_pubkey_byname): Removed ctx arg and add ret_kdbhd - arg. Changed all callers. - (key_byname): Use get_pubkey_end to release the context and take - new ret_kbdhd arg. Changed all callers. - (classify_user_id2): Fill the 16 byte fingerprint up with 4 null - bytes not with zero bytes of value 4, tsss. - * import.c (import_one): Updated to use the new keydb interface. - (import_secret_one): Ditto. - (import_revoke_cert): Ditto. - * delkey.c (do_delete_key): Ditto. - * keyedit.c (keyedit_menu): Ditto. - (get_keyblock_byname): Removed. - * revoke.c (gen_revoke): Ditto. - * export.c (do_export_stream): Ditto. - * trustdb.c (update_trustdb): Ditto. - * g10.c, gpgv.c (main): Renamed add_keyblock_resource to - keydb_add_resource. - * Makefile.am: Added and removed files. - - * keydb.h: Moved KBNODE typedef and MAX_FINGERPRINT_LEN to - * global.h: this new header. - -2001-09-03 Werner Koch <wk@gnupg.org> - - * passphrase.c (agent_get_passphrase): Changed nread to size_t. - (passphrase_clear_cache): Ditto. - - * keyid.c (mk_datestr): Avoid trigraphs. - (fingerprint_from_pk): Cache the keyid in the pk. - - * options.h: Add opt.with_fingerprint so that we know whether the - corresponding options was used. - * g10.c (main): Set it here. - * pkclist.c (check_signatures_trust): Always print fingerprint - when this option is used. Mixed a minor memory leak. - - * status.c, status.h: New status INV_RECP. - * pkclist.c (build_pk_list): Issue this status. - -2001-08-31 Werner Koch <wk@gnupg.org> - - * parse-packet.c (parse_key,parse_pubkeyenc) - (parse_signature): Return error on reading bad MPIs. - - * mainproc.c (check_sig_and_print): Always print the user ID even - if it is not bound by a signature. Use the primary UID in the - status messages and encode them in UTF-8 - * status.c (write_status_text_and_buffer): New. - -2001-08-30 Werner Koch <wk@gnupg.org> - - * packet.h (sigsubpkttype_t): Add SIGSUBPKT_FEATURES. - (PKT_public_key, PKT_user_id): Add a flag for it. - * parse-packet.c, build-packet.c: Add support for them. - * getkey.c (fixup_uidnode, merge_selfsigs): Set the MDC flags. - * keygen.c (add_feature_mdc): New. - (keygen_upd_std_prefs): Always set the MDC feature. - * keyedit.c (show_prefs): List the MDC flag - * pkclist.c (select_mdc_from_pklist): New. - * encode.c (encode_crypt, encrypt_filter): Test whether MDC - should be used. - * cipher.c (write_header): Set MDC use depending on the above test. - Print more status info. - - * delkey.c (do_delete_key): Kludge to delete a secret key with no - public key available. - - * ringedit.c (find_secret_keyblock_direct): New. - * getkey.c (seckey_available): Simplified. - - * ringedit.c (cmp_seckey): Now compares the secret key against the - public key while ignoring all secret parts. - (keyring_search): Use a public key packet as arg. Allow to search - for subnkeys - (search): Likewise. Changed all callers. - (find_secret_keyblock_bypk): New. - (find_secret_keyblock_byname): First locate the pubkey and then - find the correponding secret key. - * parse-packet.c (parse): Renamed pkttype arg to onlykeypkts and - changed code accordingly. Changed all callers. - (search_packet): Removed pkttype arg. - * keyedit.c (keyedit_menu): First locate the public key and then - try to locate a secret key. - - * ringedit.c (locate_keyblock_by_fpr): Removed. - (locate_keyblock_by_keyid): Removed. - (find_keyblock_bysk): Removed. - - * sig-check.c (check_key_signature2): Print the keyid along with - the wrong sig class errors. - -2001-08-24 Werner Koch <wk@gnupg.org> - - * sign.c (sign_file): Stripped the disabled comment packet code. - (sign_file, sign_symencrypt_file): Moved common code to .. - (write_onepass_sig_packets): .. this new function. - (sign_file, clearsign_file, sign_symencrypt_file): Moved common - code to - (write_signature_packets): this new function. - (write_signature_packets, make_keysig_packet) - (update_keysig_packet): Moved common code to - (hash_uid, hash_sigclass_to_magic): these new functions - (sign_file, sign_symencrypt_file): Moved common code to - (write_plaintext_packet): this new function. - -2001-08-21 Stefan Bellon <sbellon@sbellon.de> - - * trustdb.c (query_trust_info): Changed trustlevel to signed int. - * g10.c [__riscos__]: Fixed handling of --use-agent --lock-multiple. - -2001-08-20 Werner Koch <wk@gnupg.org> - - * encr-data.c (decrypt_data): Keep track on whether we already - printed information about the used algorithm. - * mainproc.c (proc_encrypted): Removed the non-working IDEA hack - and print a message about the assumed algorithm. - * passphrase.c (passphrase_to_dek): Use the same algorithm as above. - (proc_symkey_enc): Print the algorithm, so that the user knows it - before entering the passphrase. - (proc_pubkey_enc, proc_pubkey_enc): Zero the DEK out. - * encode.c (encode_crypt, encrypt_filter): Ditto. - - * g10.c: Allow for --sign --symmetric. - * sign.c (sign_and_symencrypt): New. - - Applied patches from Stefan Bellon <sbellon@sbellon.de> to support - RISC OS. Nearly all of these patches are identified by the - __riscos__ macro. - * compress.c: Added a couple of casts. - * g10.c [__riscos__]: Some patches and new options foo-file similar - to all foo-fd options. - * gpgv.c, openfile.c, ringedit.c, tdbio.c: Minor fixes. Mainly - replaced hardcoded path separators with EXTSEP_S like macros. - * passprase.c [__riscos__]: Disabled agent stuff - * trustdb.c (check_trust): Changed r_trustlevel to signed int to - avoid mismatch problems in pkclist.c - * pkclist.c (add_ownertrust): Ditto. - * plaintext.c (handle_plaintext) [__riscos__]: Print a note when - file can't be created. - * options.h [__riscos__]: Use an extern unless included from the - main module. - * signal.c (got_fatal_signal) [__riscos__]: Close all files. - -2001-08-14 Werner Koch <wk@gnupg.org> - - * keygen.c (ask_algo): New arg r_usage. Allow for RSA keys. - (gen_rsa): Enabled the code. - (do_create): Enabled RSA branch. - (parse_parameter_usage): New. - (proc_parameter_file): Handle usage parameter. - (read_parameter_file): Ditto. - (generate_keypair): Ditto. - (generate_subkeypair): Ditto. - (do_generate_keypair): Ditto. - (do_add_key_flags): New. - (keygen_add_std_prefs): Use the new function. - (keygen_add_key_flags_and_expire): New. - (write_selfsig, write_keybinding): Handle new usage arg. - * build-packet.c (build_sig_subpkt): Make sure that key flags go - into the hashed area. - - * keygen.c (write_uid): Initialize the reference cunter. - - * keyedit.c (keyedit_menu): No more need to update the trustdb for - preferences. Added calls to merge keblock. - - * kbnode.c (dump_kbnode): Print some more flags. - -2001-08-10 Werner Koch <wk@gnupg.org> - - Revamped the preference handling. - - * packet.h (prefitem_t, preftype_t): New. - (PKT_public_key): Added a uid field. - (PKT_user_id): Added field to store preferences and a reference - counter. - * parse-packet.c (parse_user_id,parse_photo_id): Initialize them - * free-packet.c (free_user_id): Free them. - (copy_user_id): Removed. - (scopy_user_id): New. - (cmp_user_ids): Optimized for identical pointers. - (release_public_key_parts): Release the uid. - (copy_public_key_with_new_namehash): Removed. - (copy_prefs): New. - * keyedit.c (menu_adduid): Use the new shallow copy user id. - (show_prefs): Adjusted implementation. - (keyedit_menu): No more need to update the trustdb after changing - preferences. - * getkey.c (fixup_uidnode): Store preferences. - (find_by_name): Return a user id packet and remove namehash stuff. - (lookup): Removed the unused namehash stuff. - (finish_lookup): Added foundu arg. - (pk_from_block): Removed the namehash arg and changed all callers. - (merge_selfsigs): Copy prefs to all keys. - * trustdb.c (get_pref_data): Removed. - (is_algo_in_prefs): Removed. - (make_pref_record): Deleted and removed all class. - * pkclist.c (select_algo_from_prefs): Adjusted for the new - preference implementation. - * pubkey-enc.c (is_algo_in_prefs): New. - (get_it): Use that new function. - -2001-08-09 Werner Koch <wk@gnupg.org> - - * build-packet.c (build_sig_subpkt): Fixed calculation of - newarea->size. - - * g10.c (main): New option "--preference-list" - * keyedit.c (keyedit_menu): New commands "setpref" and "updpref". - (menu_set_preferences): New. - * keygen.c (keygen_set_std_prefs): New. - (set_one_pref): New. - (check_zip_algo): New. - (keygen_get_std_prefs): New. - (keygen_upd_std_prefs): New - (keygen_add_std_prefs): Move the pref setting code into the above fnc. - * build-packet.c (build_sig_subpkt): Updated the list of allowed - to update subpackets. - -2001-08-08 Werner Koch <wk@gnupg.org> - - * packet.h (subpktarea_t): New. - (PKT_signature): Use that type for hashed_data and unhashed_data and - removed the _data prefix from those fields. Changed all users. - * parse-packet.c (parse_signature): Changed allocation for that. - (parse_sig_subpkt): Changed declaration - (enum_sig_subpkt): Ditto and changed implementation accordingly. - * free-packet.c (cp_subpktarea): Renamed from cp_data_block and - adjusted implementation. Changed caller. - * sig-check.c (mdc_kludge_check): Adjusted the hashing. - (do_check): Ditto. - * sign.c (sign_file, clearsign_file, make_keysig_packet, - update_keysig_packet): Ditto. - * build-packet.c (build_sig_subpkt): Partial rewrite. - (find_subpkt): Adjusted and made static. - (delete_sig_subpkt): Adjusted. - (do_signature): Ditto. - - * keygen.c (ask_keysize): Do not print the notes about suggested - key sizes if just a DSA key is generated. - - * trustdb.c (add_ultimate_key): s/log_error/log_info/ for - duplicated inserted trusted keys. - -2001-08-07 Werner Koch <wk@gnupg.org> - - * sign.c (sleep): Redefine for W32. - - * g10.c, options.h: Set new flag opt.no_homedir_creation when - --no-options is given. - * openfile.c (try_make_homedir): Don't create the homedir in that case. - -2001-08-03 Werner Koch <wk@gnupg.org> - - * armor.c (armor_filter): Removed the default comment string - because it could get us in trouble due to translations using non - ascii characters. - -2001-08-01 Werner Koch <wk@gnupg.org> - - * keylist.c (list_keyblock_print): Do not list revoked UIDs unless - in verbose mode and we do no signature listing. - - * getkey.c (finish_lookup): Skip subkeys which are not yet valid. - * g10.c, options.h: New option --ignore-valid-from. - - * sign.c (make_keysig_packet): Added new sigversion argument to - allow the caller to force generation of required signature - version. Changed all callers. Suggested by Thomas Roessler. - - * keyedit.c (sign_uids): Force v4 signature generation for local - sigs. Removed the check for local signature and pre-v4 keys. - -2001-07-27 Werner Koch <wk@gnupg.org> - - * keyedit.c (sign_uids): Check that we are not trying to to a - lsign with a pre-v4 key. Bug noticed by Thomas Roessler. - -2001-07-26 Werner Koch <wk@gnupg.org> - - * parse-packet.c (parse_photo_id): Reset all variables. - * getkey.c (merge_selfsigs_main): Removed checks on PHOTO_ID - because this is handled identically to a user ID. - -2001-07-06 Werner Koch <wk@gnupg.org> - - * cipher.c (write_header): Don't use MDC with --rfc1991. Suggested - by disastry@saiknes.lv. - -2001-07-05 Werner Koch <wk@gnupg.org> - - * g10.c, options.h: New option --preserve-permissions. - * ringedit.c (add_keyblock_resource): Use it here - (keyring_copy): and here. - - * trustdb.c (verify_own_keys): Be more silent on --quiet. - Suggested by Thomas Roessler. - * sig-check.c (check_key_signature2): Ditto. - * mainproc.c (proc_encrypted, proc_tree): Ditto - * getkey.c (lookup): Ditto. - -2001-07-04 Werner Koch <wk@gnupg.org> - - * ringedit.c (add_keyblock_resource): Restore filename in case of error. - -2001-06-25 Werner Koch <wk@gnupg.org> - - * kbnode.c (dump_kbnode): Print the signature timestamp. - - * keyedit.c (keyedit_menu): New menu point "primary". - (change_primary_uid_cb): New. - (menu_set_primary_uid): New. - * sign.c (update_keysig_packet): New. - * build-packet.c (build_sig_subpkt): Put the primary UID flag into - the hashed area. Allow update of some more packets. - -2001-06-15 Werner Koch <wk@gnupg.org> - - * getkey.c (merge_selfsigs): Exit gracefully when a secret key is - encountered. May happen if a secret key is in public keyring. - Reported by Francesco Potorti. - -2001-06-12 Werner Koch <wk@gnupg.org> - - * getkey.c (compare_name): Use ascii_memistr(), ascii_memcasecmp() - * keyedit.c (keyedit_menu): Use ascii_strcasecmp(). - * armor.c (radix64_read): Use ascii_toupper(). - * ringedit.c (do_bm_search): Ditto. - * keygen.c (read_parameter_file): Ditto. - * openfile.c (CMP_FILENAME): Ditto. - * g10.c (i18n_init): We can now use just LC_ALL. - -2001-05-29 Werner Koch <wk@gnupg.org> - - * keygen.c (generate_subkeypair): Print a warning if a subkey is - created on a v3 key. Suggested by Brian M. Carlson. - -2001-05-27 Werner Koch <wk@gnupg.org> - - * keyid.c (get_lsign_letter): New. - * keylist.c (list_keyblock_colon): Use it here. - * mainproc.c (list_node): and here. - - * getkey.c, packet.h, free-packet.c: Removed that useless key - created field; I dunno why I introducded this at all - the - creation time is always bound to the key packet and subject to - fingerprint calculation etc. - - * getkey.c (fixup_uidnode): Add keycreated arg and use this - instead of the signature timestamp to calculate the - help_key_expire. Bug reported by David R. Bergstein. - (merge_selfsigs_main): Correct key expiration time calculation. - (merge_selfsigs_subkey): Ditto. - -2001-05-25 Werner Koch <wk@gnupg.org> - - * revoke.c (gen_revoke): Add a cast to a tty_printf arg. - * delkey.c (do_delete_key): Ditto. - * keyedit.c (print_and_check_one_sig): Ditto. - (ask_revoke_sig): Ditto. - (menu_revsig): Ditto. - (check_all_keysigs): Removed unused arg. - -2001-05-23 Werner Koch <wk@gnupg.org> - - * g10.c (opts): Typo fix by Robert C. Ames. - -2001-05-06 Werner Koch <wk@gnupg.org> - - * revoke.c: Small typo fix - -2001-05-04 Werner Koch <wk@gnupg.org> - - * passphrase.c (passphrase_clear_cache): Shortcut if agent usage - is not enabled. - -2001-05-01 Werner Koch <wk@gnupg.org> - - * passphrase.c (writen): Replaced ssize_t by int. Thanks to - to Robert Joop for reporting that SunOS 4.1.4 does not have it. - -2001-04-28 Werner Koch <wk@gnupg.org> - - * getkey.c (merge_public_with_secret): pkttype was not set to subkey. - -2001-04-27 Werner Koch <wk@gnupg.org> - - * skclist.c (build_sk_list): Changed one log_debug to log_info. - -2001-04-25 Werner Koch <wk@gnupg.org> - - * keyedit.c (show_prefs): Add a verbose mode. - (show_key_with_all_names): Pass verbose flag for special value of - with_pref. - (keyedit_menu): New command "showpref" - (show_key_with_all_names): Mark revoked uids and the primary key. - -2001-04-24 Werner Koch <wk@gnupg.org> - - * getkey.c (get_primary_uid): Return a different string in case of - error and made it translatable. - - * build-packet.c (do_secret_key): Ugly, we wrote a zero - instead of the computed ndays. Thanks to M Taylor for complaining - about a secret key import problem. - -2001-04-23 Werner Koch <wk@gnupg.org> - - * hkp.c (hkp_ask_import): Allow to specify a port number for the - keyserver. Add a kudge to set the no_shutdown flag. - (hkp_export): Ditto. - * options.skel: Document the changes - -2001-04-20 Werner Koch <wk@gnupg.org> - - * options.skel: Add some more comments. - -2001-04-19 Werner Koch <wk@gnupg.org> - - * keyid.c (mk_datestr): New. Handles negative times. We must do - this because Windoze segvs on negative times passed to gmtime(). - Changed all datestr_from function to use this one. - - * keyid.c, keyid.h (colon_strtime): New. To implement the - fixed-list-mode. - (colon_datestr_from_pk): New. - (colon_datestr_from_sk): New. - (colon_datestr_from_sig): New. - * keylist.c (list_keyblock_colon): Use these functions here. - * mainproc.c (list_node): Ditto. - -2001-04-18 Werner Koch <wk@gnupg.org> - - * openfile.c (open_sigfile): Fixed the handling of ".sign". - * mainproc.c (proc_tree): Use iobuf_get_real_fname. - Both are by Vincent Broman. - -2001-04-14 Werner Koch <wk@gnupg.org> - - * getkey.c (fixup_uidnode): Removed check for !sig which is - pointless here. Thanks to Jan Niehusmann. - -2001-04-10 Werner Koch <wk@gnupg.org> - - * sig-check.c (check_key_signature2): Use log_info instead of - log_error so that messed up keys do not let gpg return an error. - Suggested by Christian Kurz. - - * getkey.c (merge_selfsigs_main): Do a fixup_uidnode only if we - have both, uid and sig. Thanks to M Taylor. - -2001-04-05 Werner Koch <wk@gnupg.org> - - * armor.c (unarmor_pump_new,unarmor_pump_release): New. - (unarmor_pump): New. - * pipemode.c (pipemode_filter): Use the unarmor_pump to handle - armored or non-armored detached signatures. We can't use the - regular armor_filter becuase this does only chack for armored - signatures the very first time. In pipemode we may have a mix of - armored and binary detached signatures. - * mainproc.c (proc_tree): Do not print the "old style" notice when - this is a pipemode processes detached signature. - (proc_plaintext): Special handling of pipemode detached sigs. - - * packet.h (CTRLPKT_PLAINTEXT_MARK): New. - * parse-packet.c (create_gpg_control): New. - * kbnode.c (dump_kbnode): Support it here. - * mainproc.c (check_sig_and_print): Fixed the check for bad - sequences of multiple signatures. - (proc_plaintext): Add the marker packet. - (proc_tree): We can now check multiple detached signatures. - -2001-04-02 Werner Koch <wk@gnupg.org> - - The length of encrypted packets for blocksizes != 8 was not - correct encoded. I think this is a minor problem, because we - usually use partial length packets. Kudos to Kahil D. Jallad for - pointing this out. - * packet.h: Add extralen to PKT_encrypted. - * cipher.c (write_header): Set extralen. - * build-packet.c (do_encrypted): Use extralen instead of const 10. - (do_encrypted_mdc): Ditto. - * parse-packet.c (parse_encrypted): Set extralen to 0 because we - don't know it here. - -2001-03-30 Werner Koch <wk@gnupg.org> - - * getkey.c (premerge_public_with_secret): Changed wording an add - the keyID to the info message. - -2001-03-29 Werner Koch <wk@gnupg.org> - - * getkey.c (premerge_public_with_secret): Use log_info instead of - log_error when no secret key was found for a public one. - Fix the usage if the secret parts of a key are not available. - - * openfile.c (ask_outfile_name): Trim spaces. - (open_outfile): Allow to enter an alternate filename. Thanks to - Stefan Bellon. - * plaintext.c (handle_plaintext): Ditto. - -2001-03-28 Werner Koch <wk@gnupg.org> - - * mainproc.c (do_check_sig): Allow direct key and subkey - revocation signature. - * sig-check.c (check_key_signature2): Check direct key signatures. - Print the signature class along with an error. - -2001-03-27 Werner Koch <wk@gnupg.org> - - * packet.h: Add a missing typedef to an enum. Thanks to Stefan Bellon. - - * g10.c: New option --no-sig-create-check. - * sign.c (do_sign): Implement it here. - * g10.c: New option --no-sig-cache. - * sig-check.c (check_key_signature2): Implement it here. - (cache_selfsig_result): and here. - - * keylist.c (list_keyblock): Removed debugging stuff. - - * getkey.c (cache_public_key): Made global. - * keygen.c (write_selfsig, write_keybinding): Cache the new key. - - * getkey.c (key_byname): Add new arg secmode and changed all - callers to request explicitly the mode. Deriving this information - from the other supplied parameters does not work if neither pk nor - sk are supplied. - -2001-03-25 Werner Koch <wk@gnupg.org> - - * packet.h (ctrlpkttype_t): New. - * mainproc.c (add_gpg_control,proc_plaintext,proc_tree): Use the - new enum values. - * pipemode.c (make_control): Ditto. - * armor.c (armor_filter): Ditto. - -2001-03-24 Werner Koch <wk@gnupg.org> - - * sign.c (do_sign): Verify the signature right after creation. - -2001-03-23 Werner Koch <wk@gnupg.org> - - * status.c, status.h (STATUS_UNEXPECTED): New. - * mainproc.c (do_proc_packets): And emit it here. - -2001-03-21 Werner Koch <wk@gnupg.org> - - * status.c: Add sys/types.h so that it runs on Ultrix. Reported - by Georg Schwarz.x - - * build-packet.c (build_sig_subpkt): Fixed generaton of packet - length header in case where 2 bytes headers are needed. Thanks to - Piotr Krukowiecki. - -2001-03-19 Werner Koch <wk@gnupg.org> - - * g10.c (main): the default keyring is no always used unless - --no-default-keyring is given. - - * ringedit.c (add_keyblock_resource): invalidate cache after file - creation. - -2001-03-15 Werner Koch <wk@gnupg.org> - - * keygen.c (ask_algo): Changed the warning of the ElGamal S+E Algo. - - * keylist.c (print_capabilities): New. - (list_keyblock_colon): and use it here. - -2001-03-13 Werner Koch <wk@gnupg.org> - - * main.c, options.h: New option --fixed_list_mode. - * keylist.c (list_keyblock_colon): use it here. - - * getkey.c (merge_keys_and_selfsig): Divert merging of public keys - to the function used in key selection.. - * keylist.c (is_uid_valid): Removed. - (list_keyblock): Splitted into .. - (list_keyblock_print, list_keyblock_colon): .. these. - functions. Changed them to use the flags set in the key lookup code. - (reorder_keyblock): New, so that primary user IDs are listed first. - - * ringedit.c (keyring_copy): flush the new iobuf chaces before - rename or remove operations. This is mainly needed for W32. - - * hkp.c [HAVE_DOSISH_SYSTEM]: Removed the disabled code because we - have now W32 socket support in ../util/http.c - - * skclist.c (key_present_in_sk_list): New. - (is_duplicated_entry): New. - (build_sk_list): Check for duplicates and do that before unlocking. - -2001-03-12 Werner Koch <wk@gnupg.org> - - * armor.c (parse_header_line): Removed double empty line check. - (parse_header_line): Replaced trim_trailing_ws with a counting - function so that we can adjust for the next read. - - * options.skel: Fixed 3 typos. By Thomas Klausner. Replaced the - keyserver example by a better working server. - - * parse-packet.c (parse_symkeyenc): Return Invalid_Packet on error. - (parse_pubkeyenc): Ditto. - (parse_onepass_sig): Ditto. - (parse_plaintext): Ditto. - (parse_encrypted): Ditto. - (parse_signature): Return error at other places too. - (parse_key): Ditto. - * g10.c (main): Set opt.list_packets to another value when invoked - with the --list-packets command. - * mainproc.c (do_proc_packets): Don's stop processing when running - under --list-packets command. - - * signal.c (do_sigaction): Removed. - (init_one_signal): New to replace the above. Needed to support - systems without sigactions. Suggested by Dave Dykstra. - (got_fatal_signal,init_signals): Use the above here. - (do_block): Use sigset() if sigprocmask() is not available. - - * armor.c (parse_hash_header): Test on TIGER192, which is the - correct value as per rfc2440. By Edwin Woudt. - -2001-03-08 Werner Koch <wk@gnupg.org> - - * misc.c: Include time.h. By James Troup. - - * getkey.c: Re-enabled the unknown user Id and PK caches and - increased their sizes. - - * getkey.c (merge_selfsigs_main): Set expire date and continue - processing even if we found a revoked key. - (merge_selfsigs_subkeys): Ditto. - - * packet.h: Add an is_revoked flag to the user_id packet. - * getkey.c (fixup_uidnode): Set that flag here. - (merge_selfsigs_main): Fix so that the latest signature is used to - find the self-signature for an UID. - * parse-packet.c (parse_user_id): Zero out all fields. - * mainproc.c (check_sig_and_print): Print the primary user ID - according the the node flag and then all other non-revoked user IDs. - (is_uid_revoked): Removed; it is now handled by the key selection code. - - Changed the year list of all copyright notices. - -2001-03-07 Werner Koch <wk@gnupg.org> - - * getkey.c (finish_lookup): Print an info message only in verbose mode. - -2001-03-05 Werner Koch <wk@gnupg.org> - - * packet.h: Replaced sigsubpkt_t value 101 by PRIV_VERIFY_CACHE. - We have never used the old value, so we can do this without any harm. - * parse-packet.c (dump_sig_subpkt): Ditto. - (parse_one_sig_subpkt): Parse that new sub packet. - * build-packet.c (build_sig_subpkt): Removed the old one from the - hashed area. - (delete_sig_subpkt): New. - (build_sig_subpkt): Allow an update of that new subpkt. - * sig-check.c (check_key_signature2): Add verification caching - (cache_selfsig_result): New. - * export.c (do_export_stream): Delete that sig subpkt before exporting. - * import.c (remove_bad_stuff): New. - (import): Apply that function to all imported data - -2001-03-03 Werner Koch <wk@gnupg.org> - - * getkey.c: Introduced a new lookup context flag "exact" and used - it in all place where we once used primary. - (classify_user_id2): Replaced the old function and add an extra - argument to return whether an exact keyID has been requested. - (key_byname): Removed the unused ctx.primary flag - (get_seckey_byname2): Ditto. - (finish_lookup): Changed debugging output. - -2001-03-02 Werner Koch <wk@gnupg.org> - - * keylist.c (list_one): Remove the merge key calls. - -2001-03-01 Werner Koch <wk@gnupg.org> - - * getkey.c (finish_lookup): Don't use it if we no specific usage - has been requested. - (merge_selfsigs_main): fix UID only if we have an signature. - (lookup): Return UNU_PUBKEY etc. instead of NO_PUBKEY if we found - a key but the requested usage does not allow this key. - * import.c (import_one): Take UNU_PUBKEY into account. - * mainproc.c (list_node): Ditto. - * keylist.c (list_keyblock): Ditto. - * keyedit.c (print_and_check_one_sig): Ditto. - -2001-02-09 Werner Koch <wk@gnupg.org> - - * delkey.c (delete_key): Removed that silly assert which rendered - the whole new stuff meaningless. - -2001-02-08 Werner Koch <wk@gnupg.org> - - * getkey.c (key_byname): It can happen that we have both, sk and pk - NULL, fix for that. - - * parse-packet.c (parse_one_sig_subpkt): Add support for - primary_uid and key_flags. - (can_handle_critical): Ditto - - * parse-packet.c (parse_encrypted): Fixed listing of pktlen for - MDC packets. - - * getkey.c: Backported the version of this file from gpg 1.1. this - involved some changes in other files too. - * parse-packet.c (parse_key): Clear req_usage. - * skclist.c (build_sk_list): Use req_usage to pass the usage - information to the lookup function. - * pkclist.c (build_pk_list): Ditto. - * free-packet.c (copy_public_parts_to_secret_key): New. - * keydb.h: Add IS_* macros to check the sig_class. - * misc.c (openpgp_cipher_test_algo): New. - (openpgp_pk_test_algo): New. - (openpgp_pk_algo_usage): New. - (openpgp_md_test_algo): New. - * packet.h: Add a few fields to PKT_{public,secret}_key and - PKT_user_id. - * seckey-cert.c (do_check): Use the new main_keyid field. - -2001-02-04 Werner Koch <wk@gnupg.org> - - * encr-data.c (decrypt_data): Catch error when we had problems to - parse the encrypted packet. By Timo. - -2001-01-29 Werner Koch <wk@gnupg.org> - - * g10.c (main): --batch does now set nogreeting. - - * delkey.c (do_delete_key): Fixed delete-both functionality. - -2001-01-22 Werner Koch <wk@gnupg.org> - - * g10.c: New command --delete-secret-and-public-key. - * delkey.c (delete_key): Add new arg allow_both. - (do_delete_key): Move most stuff from above to this new function. - -2001-01-12 Werner Koch <wk@gnupg.org> - - * passphrase.c (passphrase_to_dek): Use MD5 when IDEA is installed - and we have no S2K. - * mainproc.c (proc_encrypted): Likewise - -2001-01-11 Werner Koch <wk@gnupg.org> - - * sig-check.c (do_check): Print the signature key expire message - only in verbose mode and added the keyID. - -2001-01-09 Werner Koch <wk@gnupg.org> - - * status.c, status.h: New status USERID_HINT. - (write_status_text): Replace LF and CR int text by C-escape sequence. - - * passphrase.c (passphrase_to_dek): Fixed the NEED_PASSPHRASE - output. It does now always print 2 keyIDs. Emit the new - USERID_HINT. - -2001-01-08 Werner Koch <wk@gnupg.org> - - * g10.c, options.h: New option --no-expensive-trust-checks. - * keylist.c (list_keyblock): Act on this option. - -2001-01-04 Werner Koch <wk@gnupg.org> - - * g10.c (main): Set homedir only in the pre-parsing phase and - replace backslashes in the W32 version. - -2001-01-03 Werner Koch <wk@gnupg.org> - - * status.c, status.h : New status KEY_CREATED - * keygen.c (do_generate_keypair,generate_subkeypair): Emit it. - -2000-12-28 Werner Koch <wk@gnupg.org> - - * signal.c (got_fatal_signal): Remove lockfiles here because the - atexit stuff does not work due to the use of raise. Suggested by - Peter Fales. - * gpgv.c (remove_lockfiles): New stub. - -2000-12-19 Werner Koch <wk@gnupg.org> - - * status.c, status.h (cpr_get_no_help): New. - * keyedit.c (keyedit_menu): Use it here because we have our own - help list here. - -2000-12-18 Werner Koch <wk@gnupg.org> - - * mainproc.c (print_failed_pkenc): Don't print the sometimes - confusing message about unavailabe secret key. Renamed ... - (print_pkenc_list): ... to this and introduced failed arg. - (proc_encrypted): Print the failed encryption keys and then - the one to be used. - (proc_pubkey_enc): Store also the key we are going to use. - - * mainproc.c (check_sig_and_print): Don't list revoked user IDs. - (is_uid_revoked): New. - -2000-12-08 Werner Koch <wk@gnupg.org> - - * pipemode.c: Made the command work. Currently only for - non-armored detached signatures. - * mainproc.c (release_list): Reset the new pipemode vars. - (add_gpg_control): Handle the control packets for pipemode - * status.c, status.h: New stati {BEGIN,END}_STREAM. - -2000-12-07 Werner Koch <wk@gnupg.org> - - * g10.c: New option --allow-secret-key-import. - * import.c (import_keys,import_keys_stream): Honor this option. - (import): New arg allow_secret and pass that arg down to ... - (import_secret_one): to this and print a warning if secret key - importing is not allowed. - -2000-12-05 Werner Koch <wk@gnupg.org> - - * cipher.c (cipher_filter): Moved the end_encryption status ... - * encode.c (encode_simple,encode_crypt): to here - * sign.c (sign_file): and here. - - * status.c (mywrite): Removed. - (get_status_string): Removed the LFs from the strings. - (set_status_fd,is_status_enabed,write_status_text, - write_status_buffer): Replaced all mywrite by stdio calls and use - fdopen to create a strem. This is needed to make things smoother - in the W32 version. - -2000-12-04 Werner Koch <wk@gnupg.org> - - * import.c (merge_blocks): Increment n_sigs for revocations. - -2000-11-30 Werner Koch <wk@gnupg.org> - - * g10.c (main): Use iobuf_translate_file_handle for all options - with filehandles as arguments. This is function does some magic - for the W32 API. - - * verify.c (verify_signatures): Add a comment rant about the - detached signature problem. - * mainproc.c (proc_tree): Issue an error if a detached signature - is assumed but a standard one was found. - * plaintext.c (hash_datafiles): Don't fall back to read signature - from stdin. - * openfile.c (open_sigfile): Print verbose message only if the - file could be accessed. - -2000-11-24 Werner Koch <wk@gnupg.org> - - * passphrase.c [HAVE_DOSISH_SYSTEM]: Disabled all the agent stuff. - -2000-11-16 Werner Koch <wk@gnupg.org> - - * g10.c: New option --use-agent - * passphrase.c (agent_open,agent_close): New. - (agent_get_passphrase,agent_clear_passphrase): New. - (passphrase_clear_cache): New. - (passphrase_to_dek): Use the agent here. - * seckey-cert.c (do_check): Clear cached passphrases. - -2000-11-15 Werner Koch <wk@gnupg.org> - - * status.c (write_status_text): Moved the big switch to ... - (get_status_string): ... new function. - (write_status_buffer): New. - - * status.c (mywrite): New and replaced all write() by this. - - * status.c, status.h: Add 3 status lcodes for notaions and policy. - * mainproc.c (print_notation_data): Do status output of notations. - -2000-11-13 Werner Koch <wk@gnupg.org> - - * sign.c (clearsign_file): Use LF macro to print linefeed. - -2000-11-11 Paul Eggert <eggert@twinsun.com> - - Clean up the places in the code that incorrectly use "long" or - "unsigned long" for file offsets. The correct type to use is - "off_t". The difference is important on large-file hosts, - where "off_t" is longer than "long". - - * keydb.h (struct keyblock_pos_struct.offset): - Use off_t, not ulong, for file offsets. - * packet.h (dbg_search_packet, dbg_copy_some_packets, - search_packet, copy_some_packets): Likewise. - * parse-packet.c (parse, dbg_search_packet, search_packet, - dbg_copy_some_packets, copy_some_packets): Likewise. - * ringedit.c (keyring_search): Likewise. - - * parse-packet.c (parse): Do not use %lu to report file - offsets in error diagnostics; it's not portable. - * ringedit.c (keyring_search): Likewise. - -2000-11-09 Werner Koch <wk@gnupg.org> - - * g10.c (main): New option --enable-special-filenames. - -2000-11-07 Werner Koch <wk@gnupg.org> - - * g10.c (main): New command --pipemode. - * pipemode.c: New. - -2000-10-23 Werner Koch <wk@gnupg.org> - - * armor.c (armor_filter): Changed output of hdrlines, so that a CR - is emitted for DOS systems. - - * keygen.c (read_parameter_file): Add a cast for isspace(). - - * status.c (myread): Use SIGINT instead of SIGHUP for DOS. - -2000-10-19 Werner Koch <wk@gnupg.org> - - * g10.c: New option --ignore-crc-error - * armor.c (invalid_crc): New. - (radix64_read): Act on new option. - - * openfile.c (try_make_homedir): Klaus Singvogel fixed a stupid - error introduced on Sep 6th. - -2000-10-18 Werner Koch <wk@gnupg.org> - - * misc.c (print_cipher_algo_note): Don't print the note for AES. - Changed wording. - -2000-10-16 Werner Koch <wk@gnupg.org> - - * mainproc.c (do_proc_packets): Hack to fix the problem that - signatures are not detected when there is a MDC packet but no - compression packet. - - * g10.c (print_hashline): New. - (print_mds): Use above func with --with-colons. - - * mainproc.c (check_sig_and_print): Detect multiple signatures - and don't verify them. - -2000-10-14 Werner Koch <wk@gnupg.org> - - * mainproc.c (add_onepass_sig): There is an easier solution to the - error fixed yesterday; just check that we only have onepass - packets. However, the other solution provides an cleaner - interface and opens the path to get access to other information - from the armore headers. - (release_list): Reset some more variables. - -2000-10-13 Werner Koch <wk@gnupg.org> - - * mainproc.c (add_gpg_control): New. - (do_proc_packets): use it. - (proc_plaintext): Changed logic to detect clearsigns. - (proc_tree): Check the cleartext sig with some new code. - - * packet.h: New packet PKT_GPG_CONTROL. - * parse-packet.c (parse_gpg_control): New. - * misc.c (get_session_marker): New. - * armor.c (armor_filter): Replaced the faked 1-pass packet by the - new control packet. - - * keyedit.c (keyedit_menu): Allow batchmode with a command_fd. - * status.c (my_read): New. - (do_get_from_fd): use it. - -2000-10-12 Werner Koch <wk@gnupg.org> - - * keygen.c (keygen_add_std_prefs): Add Rijndael to the prefs. - -2000-10-07 Werner Koch <wk@gnupg.org> - - * gpgv.c: Add more stubs for ununsed code to make the binary smaller. - -Wed Oct 4 15:50:18 CEST 2000 Werner Koch <wk@openit.de> - - * sign.c (hash_for): New arg to take packet version in account, changed - call callers. - - * gpgv.c: New. - * Makefile.am: Rearranged source files so that gpgv can be build with - at least files as possible. - -Mon Sep 18 12:13:52 CEST 2000 Werner Koch <wk@openit.de> - - * hkp.c (not_implemented): Print a notice for W32 - -Fri Sep 15 18:40:36 CEST 2000 Werner Koch <wk@openit.de> - - * keygen.c (keygen_add_std_prefs): Changed order of preferences to - twofish, cast5, blowfish. - - * pkclist.c (algo_available): Removed hack to disable Twofish. - -Thu Sep 14 17:45:11 CEST 2000 Werner Koch <wk@openit.de> - - * parse-packet.c (dump_sig_subpkt): Dump key flags. Print special - warning in case of faked ARRs. - - * getkey.c (finsih_lookup): Hack so that for v4 RSA keys the subkey - is used for encryption. - -Thu Sep 14 14:20:38 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c (main): Default S2K algorithms are now SHA1 and CAST5 - this - should solve a lot of compatibility problems with other OpenPGP - apps because those algorithms are SHOULD and not optional. The old - way to force it was by using the --openpgp option whith the drawback - that this would disable a couple of workarounds for PGP. - - * g10.c (main): Don't set --quite along with --no-tty. By Frank Tobin. - - * misc.c (disable_core_dump): Don't display a warning here but a return - a status value and ... - * g10.c (main): ...print warnining here. Suggested by Sam Roberts. - -Wed Sep 13 18:12:34 CEST 2000 Werner Koch <wk@openit.de> - - * keyedit.c (keyedit_menu): Allow to use "debug" on the secret key. - - * ringedit.c (cmp_seckey): Fix for v4 RSA keys. - * seckey-cert.c (do_check): Workaround for PGP 7 bug. - -Wed Sep 6 17:55:47 CEST 2000 Werner Koch <wk@openit.de> - - * misc.c (print_pubkey_algo_note): Do not print the RSA notice. - * sig-check.c (do_signature_check): Do not emit the RSA status message. - * pubkey-enc.c (get_session_key): Ditto. - - * encode.c (encode_simple, encode_crypt): Fix for large files. - * sign.c (sign_file): Ditto. - -Wed Sep 6 14:59:09 CEST 2000 Werner Koch <wk@openit.de> - - * passphrase.c (hash_passphrase): Removed funny assert. Reported by - David Mathog. - - * openfile.c (try_make_homedir): Changes for non-Posix systems. - * g10.c (main): Take the default homedir from macro. - - * g10.c: The --trusted-key option is back. - * trustdb.c (verify_own_key): Handle this option. - (add_ultimate_key): Moved stuff from verify_own_key to this new func. - (register_trusted_key): New. - -Fri Aug 25 16:05:38 CEST 2000 Werner Koch <wk@openit.de> - - * parse-packet.c (dump_sig_subpkt): Print info about the ARR. - - * openfile.c (overwrite_filep): Always return okay if the file is - called /dev/null. - (make_outfile_name): Add ".sign" to the list of know extensions. - (open_sigfile): Ditto. - -Wed Aug 23 19:52:51 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c: New option --allow-freeform-uid. By Jeroen C. van Gelderen. - * keygen.c (ask_user_id): Implemented here. - -Fri Aug 4 14:23:05 CEST 2000 Werner Koch <wk@openit.de> - - * status.c (do_get_from_fd): Ooops, we used fd instead of opt.command_fd. - Thanks to Michael Tokarev. - -Tue Aug 1 20:06:23 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c: New opttion --try-all-secrets on suggestion from Matthias Urlichs. - * pubkey-enc.c (get_session_key): Quite easy to implement here. - -Thu Jul 27 17:33:04 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c: New option --merge-only. Suggested by Brendan O'Dea. - * import.c (import_one): Implemented it here - (import_secret_one): Ditto. - (print_stats): and give some stats. - -Thu Jul 27 12:01:00 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c: New options --show-session-key and --override-session-key - * pubkey-enc.c (hextobyte): New. - (get_override_session_key): New. - * mainproc.c (proc_pubkey_enc): Add session-key stuff. - * status.h, status.c (STATUS_SESSION_KEY): New. - -Thu Jul 27 10:02:38 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c (main): Use setmode(O_BINARY) for MSDOS while generating random bytes - (print_mds): Likewise for stdin. - * plaintext.c (handle_plaintext): Likewise for stdout. - -Mon Jul 24 10:30:17 CEST 2000 Werner Koch <wk@openit.de> - - * keyedit.c (menu_expire): expire date for primary key can be set again. - -Wed Jul 19 11:26:43 CEST 2000 Werner Koch <wk@openit.de> - - * keylist.c (is_uid_valid): New. - (list_keyblock): Print validity information for all user IDs. Note, this - has to be done at other places too; for now we have only minimal support. - -Wed Jul 12 13:32:06 CEST 2000 Werner Koch <wk@openit.de> - - * helptext.c, pkclist.c: s/superseeded/superseded/ - -Mon Jul 10 16:08:57 CEST 2000 Werner Koch <wk@openit.de> - - * parse-packet.c (enum_sig_subpkt): Fixed testing on crtitical bit in case - of a NULL buffer. Reported by Peter Marschall. - -Wed Jul 5 13:28:45 CEST 2000 Werner Koch <wk@openit.de> - - * keyedit.c, keyid.c: Add some _() - - * argparse.c: Changed the flag to suppress --version handling to also - suppress --help. - -Wed Jun 28 11:54:44 CEST 2000 Werner Koch <wk@openit.de> - - * armor.c (armor_filter): Set sigclass to 0 in case of non-dash-escaped - clearsig. This makes this mode work again. - - * mainproc.c (proc_tree): Fixed handling of one-pass-sig packets in textmode. - Disabled the ugly workaround for PGP 5 - let's see whether thi breaks less - cases. Found by Ted Cabeen. - - * options.h (DBG_HASHING): New. All commented md_start_debug are now - controlled by this debug option. - - * sign.c (print_status_sig_created): New and called from 2 places. - - * keygen.c (gen_rsa): New, but commented. - (ask_algo): Commented support for RSA. - - * seckey-cert.c (protect_secret_key): Started to fix the code for v4 RSA - keys - it is not solved yet. However, we have time until, Sep 20th ;) - -Wed Jun 14 12:27:09 CEST 2000 Werner Koch <wk@openit.de> - - * status.c (init_shm_coprocessing): Changed the sequence of the get,attach - to cope with the changes in newer Linux kernels. This bug has been found - by <dmitri@advantrix.com> who also proposed this solution. Hopefully - this does not break gpg on to many systems. - - * cipher.c (write_header): Protect the IV with the MDC too. - * encr-data.c (decrypt_data): Likewise. - -Fri Jun 9 10:09:52 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c: New options --no-auto-key-retrieve - * options.h (auto_key_retrieve): New. - * mainproc.c (check_sig_and_print): Implemented that. - -Wed Jun 7 19:19:09 CEST 2000 Werner Koch <wk@openit.de> - - * sig-check.c (do_check): Use EMULATE_MDENCODE also on v4 packets. - -Wed Jun 7 17:25:38 CEST 2000 Werner Koch <wk@openit.de> - - * cipher.c (write_header): Use plain CFB mode for MDC encrypted packets. - * encr-data.c (decrypt_data): Ditto. - -Mon Jun 5 23:41:54 CEST 2000 Werner Koch <wk@openit.de> - - * seskey.c (do_encode_md, encode_md_value): Add new arg v3compathack to work - around a bug in old versions. - * sig-check.c (do_check): use the aboved workaround when enabled. - * g10.c: New option --emulate-md-decode-bug - -Mon Jun 5 12:37:43 CEST 2000 Werner Koch <wk@openit.de> - - * build-packet.c (do_mdc): New. - (do_encrypted_mdc): Changed for the new proposal. - * parse-packet.c (parse_mdc): New. - (parse_encrypted): Fixed for the new proposal. - * packet.h (PKT_MDC): New. - * cipher.c (cipher_filter): Build the MDC packet here. - * g10.c (main): Enable --force-mdc. - * encr-data.c (mdc_decode_filter): Fixed for new MDC method - - * options.h(rfc2440): New. - * g10.c (main): Changed the selected values for --openpgp to not include - optional algorithms. - -Thu May 18 11:38:54 CEST 2000 Werner Koch <wk@openit.de> - - * keyedit.c (keyedit_menu): Add a keyword arg to the prompt. - - * status.c, status.h: Added 3 new status tokens. - * status.c (do_get_from_fd): New. - (cpr_enabled,cpr_get,cpr_get_hidden,cpr_kill_prompt, - cpr_get_answer_is_yes,cpr_get_answer_yes_no_quit): Modified to work - with the new function. - * g10.c: Add new option --command-fd. - - * status.c (progress_cb): New. - (set_status_fd): Register progress functions - -Fri May 12 14:01:20 CEST 2000 Werner Koch <wk@openit.de> - - * delkey.c (delete_key): Add 2 new status messages - * status.c, status.h (STATUS_DELETE_PROBLEM): New. - - Fixed years of copyright in all source files. - -Mon May 1 17:08:14 CEST 2000 Werner Koch <wk@openit.de> - - * trustdb.c (propagate_validity): Fixed the bug that only one uid - gets fully trusted even when all are signed by an ultimate key. - -Mon May 1 15:38:04 CEST 2000 Werner Koch <wk@openit.de> - - * getkey.c (key_byname): Always returned a defined context. Fixed - a segv for invalid user id specifications. Reported by Walter Koch. - - * getkey.c (get_user_id): I18ned "no user id" string. By Walter. - - * pkclist.c (do_show_revocation_reason): Typo fixes. - * helptext.c: Ditto. - - * armor.c (armor_filter): Fixed some CRLF issues. By Mike McEwan. - -Fri Apr 14 19:37:08 CEST 2000 Werner Koch <wk@openit.de> - - * pkclist.c (do_show_revocation_reason): New. - (show_revocation_reason): New and called at various places. - - * g10.c (main): Fixed small typo. - - * pkclist.c (do_we_trust): Act on always_trust but not for revoked - keys. Suggested by Chip Salzenberg. - - * g10.c: New option --lock-never. - - * ringedit.c (get_writable_keyblock_file): New. - * keygen.c (do_generate_keypair): Use this instead of the hardwired one. - - * keygen.c (ask_user_id): Check that the email address is in the - correct field. Suggested by Christian Kurz. - -Mon Apr 10 13:34:19 CEST 2000 Werner Koch <wk@openit.de> - - * keyedit.c (show_key_with_all_names): s/sbb/ssb/ - -Tue Mar 28 14:26:58 CEST 2000 Werner Koch <wk@openit.de> - - * trustdb.c (verify_own_keys): Do not print warning about unprotected - key when in quiet mode. - -Wed Mar 22 13:50:24 CET 2000 Werner Koch <wk@openit.de> - - * mainproc.c (print_userid): Do UTF8 conversion before printing. - * import.c (import_one): Ditto. - (import_secret_one): Ditto. - (delete_inv_parts): Ditto. - -Thu Mar 16 16:20:23 CET 2000 Werner Koch <wk@openit.de> - - * keylist.c (print_key_data): Handle a NULL pk gracefully. - - * getkey.c (merge_one_pk_and_selfsig): Fixed silly code for - getting the primary keys keyID but kept using the one from the - subkey. - * pubkey-enc.c (get_it): Print a note for expired subkeys. - - * getkey.c (has_expired): New. - (subkeys_expiretime): New. - (finish_lookup): Check for expired subkeys needed for encryption. - (merge_keys_and_selfsig): Fixed expiration date merging for subkeys. - - * keylist.c (list_keyblock): Print expiration time for "sub". - (list_one): Add missing merging for public keys. - * mainproc.c (list_node): Ditto. - -2000-03-14 13:49:38 Werner Koch (wk@habibti.openit.de) - - * keygen.c (keyedit_menu): Do not allow to use certain commands - while the secret key is selected. - -2000-03-09 12:53:09 Werner Koch (wk@habibti.openit.de) - - * keygen.c (ask_expire_interval): Movede parsig to ... - (parse_expire_string): ... this new function. And some new control - commands. - (proc_parameter_file): Add expire date parsing. - (do_generate_keypair): Allow the use of specified output files. - -2000-03-08 10:38:38 Werner Koch (wk@habibti.openit.de) - - * keygen.c (ask_algo): Removed is_v4 return value and the commented - code to create Elg keys in a v3 packet. Removed the rounding - of key sizes here. - (do_create): Likewise removed arg v4_packet. - (gen_elg): Likewise removed arg version. Now rounding keysizes here. - (gen_dsa): Rounding keysize now here. - (release_parameter_list): New - (get_parameter*): New. - (proc_parameter_file): New. - (read_parameter_file): New. - (generate_keypair): Splitted. Now uses read_parameter_file when in - batch mode. Additional argument to specify a parameter file. - (do_generate_keypair): Main bulk of above fucntion and uses the - parameter list. - (do_create): Don't print long notice in batch mode. - * g10.c (main): Allow batched key generation. - -Thu Mar 2 15:37:46 CET 2000 Werner Koch <wk@gnupg.de> - - * pubkey-enc.c (get_it): Print a note about unknown cipher algos. - - * g10.c (opts): Add a note to the help listing about the man page - and removed some options from the help listing. - - * keyedit.c (print_and_check_one_sig): Use a new function to truncate - the output of the user ID. Suggested by Jan-Benedict Glaw. - -Wed Feb 23 10:07:57 CET 2000 Werner Koch <wk@gnupg.de> - - * helptext.c: typo fix. - -Thu Feb 17 13:39:32 CET 2000 Werner Koch <wk@gnupg.de> - - * revoke.c: Removed a bunch of commented code. - - * packet.h (SIGSUBPKT_REVOC_REASON): New. - * build-packet.c (build_sig_subpkt): Support new sub packet. - * parse-packet.c (parse_one_sig_subpkt): Ditto. - (dump_sig_subpkt): Ditto. - * revoke.c (ask_revocation_reason): New. - (release_revocation_reason_info): New. - (revocation_reason_build_cb): New. - (gen_revoke): Ask for reason. - * main.h (struct revocation_reason_info): Add declaration. - * keyedit.c (menu_revsig): Add support for revocation reason. - (menu_revkey): Ditto. - (sign_uid_mk_attrib): Renamed to ... - (sign_mk_attrib): ... this, made static and add support for reasons. - -Tue Feb 15 08:48:13 CET 2000 Werner Koch <wk@gnupg.de> - - * build-packet.c (build_packet): Fixed fixing of old comment packets. - - * import.c (import_keys): Fixed importing from stdin when called with - nnames set to zero as it normally happens. - -Mon Feb 14 14:30:20 CET 2000 Werner Koch <wk@gnupg.de> - - * sig-check.c (check_key_signature2): Add new arg r_expired. - (do_signature_check): New arg to pass it down to ... - (do_check): New arg r-expire which is set when the signature - has expired. - * trustdb.c (check_sig_record): Set SIGF_EXPIRED flag and set - the expiretime to zero so that thi signature will not be checked - anymore. - -Fri Feb 11 17:44:40 CET 2000 Werner Koch <wk@gnupg.de> - - * g10.c (g10_exit): Update the random seed_file. - (main): Set the random seed file. New option --no-random-seed-file. - -Thu Feb 10 17:39:44 CET 2000 Werner Koch <wk@gnupg.de> - - * keyedit.c (menu_expire): Fixed segv due to unitialized sub_pk. - By Rémi. - -Thu Feb 10 11:39:41 CET 2000 Werner Koch <wk@gnupg.de> - - * keylist.c (list_keyblock): Don't print warnings in the middle of - regulat output lines. By Rémi. - - * sig-check.c: Include options.h - -Wed Feb 9 15:33:44 CET 2000 Werner Koch <wk@gnupg.de> - - * gpg.c: New option --ignore-time-conflict - * sig-check.c (do_check): Implemented this option. - * trustdb.c (check_trust): Ditto. - * sign.c (do_sign): Ditto. - * keygen.c (generate_subkeypair): Ditto. - - * encode.c (encode_simple): use iobuf_cancel after open failure. - Reported by Huy Le. - -Fri Jan 14 18:32:01 CET 2000 Werner Koch <wk@gnupg.de> - - * packet.h (STRING2KEY): Changed mode from byte to int. - * parse-packet.c (parse_key): Add the special GNU protection stuff - * build-packet.c (so_secret_key): Ditto. - * seckey-cert.c (do_check): Ditto. - * keyedit.c (change_passphrase): Ditto. - * export.c (export_secsubkeys): New. - (do_export_stream): Hack to export the primary key using mode 1001. - * g10.c: New command --export-secret-subkeys - -Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de> - - * armor.c (is_armored): Check for 1-pass-sig packets. Reported by - David Hallinan <hallinan@rtd.com>. - (armor_filter): Replaced one LF by the LF macro. Reported by - Wolfgang Redtenbacher. - -Wed Jan 5 11:51:17 CET 2000 Werner Koch <wk@gnupg.de> - - * g10.c (main): Reset new global flag opt.pgp2_workarounds - when --openpgp is used. - * mainproc.c (proc_plaintext): Do the PGP2,5 workarounds only - when the global flag is set. - (proc_tree): Ditto. - * textfilter.c (copy_clearsig_text): Ditto. - * armor.c (armor_filter): Ditto. - - * g10.c: New option --list-only - * mainproc.c (proc_tree): Don't do it if opt.list_only is active. - (proc_pubkey_enc): Implement option. - - * status.h, status.c ({BEGIN,END}_{EN,DE}CRYPTION): New. - * cipher.c (cipher_filter): New status outputs. - * mainproc.c (proc_encrypted): New status outputs. - -Fri Dec 31 14:08:15 CET 1999 Werner Koch <wk@gnupg.de> - - * armor.c (armor_filter): Made the "Comment:" header translatable. - - * hkp.c (hkp_import): Make sure that the program does not return - success when there is a connection problem. Reported by Phillip Jones. - -Sun Dec 19 15:22:26 CET 1999 Werner Koch <wk@gnupg.de> - - * armor.c (LF): Use this new macro at all places where a line LF - is needed. This way DOSish textfiles should be created when the - input data is also in dos mode. - * sign.c (LF): Ditto. - * textfilter.c (LF): Ditto. - (copy_clearsig_text): Disabled the forcing of CR,LF sequences - for DOS systems. - - * plaintext.c (handle_plaintext): Fixes for line endings on DOS. - and react on a LF in cleartext. - * armor.c (fake_packet): Restore the original line ending after - removing trailing spaces. - - * signal.c (got_fatal_signal): DOS fix. - -Thu Dec 16 10:07:58 CET 1999 Werner Koch <wk@gnupg.de> - - * mainproc.c (print_failed_pkenc): Fix for unknown algorithm. - Found by fygrave@epr0.org. - -Thu Dec 9 10:31:05 CET 1999 Werner Koch <wk@gnupg.de> - - * hkp.c: i18n the strings. - -Sat Dec 4 15:32:20 CET 1999 Werner Koch <wk@gnupg.de> - - * trustdb.c (verify_key): Shortcut for ultimately trusted keys. - -Sat Dec 4 12:30:28 CET 1999 Werner Koch <wk@gnupg.de> - - * pkclist.c (build_pk_list): Validate the trust using the namehash - if this one has been set by the key lookup. - - * g10.c: Add --delete-secret-key to the help page. - - * openfile.c (copy_options_file): Made static. - (try_make_homedir): New. - * ringedit.c (add_keyblock_resource): Use the try_make_hoemdir logic. - * tdbio.c (tdbio_set_dbname): Likewise. - - * keygen.c (generate_user_id): Use m_alloc_clear() here. We should - better use an allocation function specific to the user_id packet. - - * keygen.c (keygen_add_std_prefs): Changed symmetric preferences - to include Blowfish again. This is due to it's better speed compared - to CAST5. - - * g10.c (strusage): Print the home directory. - - * armor.c (armor_filter): Take action on the cancel control msg. - * filter.h (armor_filter_context_t): Add cancel flag. - -Mon Nov 29 21:52:11 CET 1999 Werner Koch <wk@gnupg.de> - - * g10.c: New option --fast-list-mode .. - * keylist.c (list_keyblock): .. and implemented. - * mainproc.c (list_node): Ditto. - - * import.c (mark_non_selfsigned_uids_valid): Fixed the case that there - is a uid without any packet following. - -Mon Nov 22 11:14:53 CET 1999 Werner Koch <wk@gnupg.de> - - * mainproc.c (proc_plaintext): Never enable the hash processing - when skip_verify is active. - - * armor.c (parse_header_line): Stop parsing on a WS line too. - Suggested by Aric Cyr. - - * tdbdump.c (HEXTOBIN): Changed the name of the argument, so that - traditional cpp don't mess up the macros. Suggested by Jos Backus. - - * mainproc.c (list_node): Print the PK algo in the --with-colon mode. - * keylist.c (list_keyblock): Ditto. - - * signal.c (got_fatal_signal): Found the reason why exit(8) did not - work - it is better to set the disposition back to default before - raising the signal. Print the notice on stderr always. - -Fri Nov 12 20:33:19 CET 1999 Werner Koch <wk@gnupg.de> - - * g10.c (make_username): Swapped the logic. - * keylist.c (public_key_list): Now takes a STRLIST as arg and moved - the creation ot this list to the caller, so that he can copy with - UTF-conversion of user IDs. Changed all callers. - (secret_key_list): Likewise. - - * getkey.c (get_user_id_string_native): New and ... - * encode.c (write_pubkey_enc_from_list): ... use it here. - - * pubring.asc: Updated. - - * packet.h (PKT_PHOTO_ID): New. - * parse-packet.c (parse_photo_id): New. - * build-packet.c (do_user_id: Handle photo IDs. - (build_packet): Change CTB for photo IDs - * free-packet.c (free_user_id): Release memory used for photo IDs - * sig-check.c (hash_uid_node): Handle photo IDs too. - * trustdb.c (print_uid_from_keyblock): Hash photo ID. - (make_uid_records): Ditto. - * getkey.c (find_by_name): Ditto. - * keyedit.c (show_prefs): Ditto. - * keylist.c (list_keyblock): Ditto. - -Thu Oct 28 16:08:20 CEST 1999 Werner Koch <wk@gnupg.de> - - * keygen.c (ask_expire_interval): Print a warning for systems - with a signed 32 time_t if the exiration time is beyoind 2038. - -Fri Oct 8 20:40:50 CEST 1999 Werner Koch <wk@gnupg.de> - - * ringedit.c (enum_keyblocks): The last fix way really stupid; - reverted and set rt to Unknown. - -Fri Oct 8 20:32:01 CEST 1999 Werner Koch <wk@gnupg.de> - - * ringedit.c (enum_keyblocks): Zero the entire kbpos out on open. - - * g10.c (oEntropyDLL): Removed option. - (main): Made the warning on development versions more verbose. - - * g10.c (oHonorHttpProxy): New option. - * hkp.c (hkp_ask_import,hkp_export): Implement this option. - * options.skel: Enable this option for new installations - -Mon Oct 4 21:23:04 CEST 1999 Werner Koch <wk@gnupg.de> - - * import.c (import_keys): Changed calling interface, adjusted caller. - (import): Moved printing of stats out ... - (print_stats): New. ... to here. - (import_keys_stream): Call stats print here. - (import_keys): Print stats as totals for all files. - - * tdbio.h (DIRF_NEWKEYS): New - * tdbio.c (tdbio_dump_record): Print the new flag. - * trustdb.c (check_trust_record): New arg sigs_only. Adapted all - callers. - (do_update_trust_record): Removed recheck arg and add a new sigs_only - do we can later improve on the performance. Changed all callers too. - (check_trustdb): Evalutate the new flag and add a status output. - Do a check when the dir record has not been checked. - (build_cert_tree): Evaluate the new flag. - (check_trust): Ditto. Do a trust_record check, when the dir record - is not marked as checked. - (mark_fresh_keys): New. - (clear_lid_table): New. - (sync_trustdb): New. - * import.c (import_keys): Call sync_trustdb() after processing. - (import_keys_stream): Ditto. - * tdbdump.c (import_ownertrust): Ditto. - - * import.c (import_revoke_cert): Notify the trust DB. - (do_update_trust_record): Use |= to set the REVOKED bit and not &=; - shame on me for this bad copy+paste introduced bug. - (do_we_trust): Add trustmask to allow revoked key override to work. - Chnaged are to allow return of a mofified trustlevel. Adapted the - one caller. - - * g10.c: New options --emulate-3des-s2k-bug - * passphrase.c (hash_passphrase): Implemented above. - - * mainproc.c (proc_tree): Check for standalone signatures. - (do_check_sig): Print a notice for a standalone revocation - (check_sig_and_print): Do not print an error for unchecked standalone - revocations. - -Tue Sep 28 20:54:37 CEST 1999 Werner Koch <wk@gnupg.de> - - * encode.c (encode_simple): Use new CTB when we don't have the - length of the file. This is somewhat strange as the comment above - indicates that this part is actually fixed for PGP 5 - maybe I simply - lost the source line, tsss. - - * armor.c (armor_filter): Set a flag if no OpenPGP data has been found. - * verify.c (verify_signatures): Add an error helptext. - -Thu Sep 23 19:24:30 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * openfile.c (open_outfile): Fixed the 8dot3 handling. - - * passphrase.c (passphrase_to_dek): Print uid using utf8 func. - * delkey.c (delete_key): Ditto. - * pkclist.c (show_paths,do_edit_ownertrust,do_we_trust): Ditto - (do_we_trust_pre): Ditto. - * trustdb.c (print_user_id,check_uidsigs): Ditto. - * revoke.c (gen_revoke,ask_revoke_sig): Ditto. - -Thu Sep 23 09:52:58 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * verify.c (print_file_status): New. - (verify_one_file): Moved status print to th new fnc. Add error status. - * status.c, status.h (STATUS_FILE_ERROR): New - -Wed Sep 22 10:14:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * openfile.c (make_outfile_name): Use case-insenstive compare for - DOS systems. Add ".pgp" to the list of know extensions. - (open_outfile): For DOS systems try to replace the suffiy instead of - appending it. - - * status.c, status.h: Add STATUS_FILE_{START,DONE}. - * verify.c (verify_one_file): Emit these new stati. - - * sign.c (clearsign_file): Avoid duplicated Entries in the "Hash:" - line. Those headers are now only _not_ printed when there are - only old-style keys _and_ all hashs are MD5. - -Mon Sep 20 12:24:41 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * verify.c (verify_files, ferify_one_file): New. - * g10.c: New command --verify-files - -Fri Sep 17 12:56:42 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c: Add UK spelling as alias for armor options ;-) - - * import.c (append_uid): Fixed a SEGV when there is no selfsig and - no subkey. - (merge_sigs): Ditto. Removed the assertion. - -Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c: New option --entropy-dll-name - -Mon Sep 13 10:51:29 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * signal.c (got_fatal_signal): Print message using write(2) and - only for development versions. - -Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * tdbio.c (tdbio_set_dbname): Use mkdir macro - * ringedit.c (add_keyblock_resource): Ditto. - -Fri Sep 3 10:04:45 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (build_pk_list): Skip keys set with --encrypt-to also - when asking for a key. - - * plaintext.c (handle_plaintext): Make sure that we don't read a - second EOF in the read loop for partial length packets. - - * mainproc.c (check_sig_and_print): print user ID as utf-8. - -Thu Sep 2 16:40:55 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * import.c (merge_blocks): First add new subkeys, then merge subkey - certificates. - (merge_sigs): Don't merge subkey signatures here. - -Wed Sep 1 15:30:44 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keygen.c (ask_expire_interval): Fixed bug related to cpr_xx (tnx - Francis J. Lacoste). - -Tue Aug 31 17:20:44 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * plaintext.c (do_hash): Hash CR,LF for a single CR. - (ask_for_detached_datafile): Changed arguments to be closer to - those of hash_datafiles and cleanup the code a bit. - * mainproc.c (proc_tree): Workaround for pgp5 textmode detached - signatures. Changed behavior of asking for data file to be the same - as with provided data files. - - * keylist.c (list_keyblock): Use UTF8 print functions. - -Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * import.c (chk_self_sigs): some s/log_error/log_info/ so that gpg - does not return an error if a key has some invalid packets. - - * helptext.c: Fixed some typos and changed the way the - translation works. The english text is now the keyword for gettext - and not anymore the keyword supplied to the function. Done after - some discussion with Walter who thinks this is much easier for the - translators. - - * misc.c (disable_core_dumps): Don't do it for DOSish systems. - - * signal.c (signal_name): Bounds check on signum. - -Wed Aug 4 10:34:18 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pubring.asc: Updated. - - * pkclist.c (do_we_trust_pre,check_signatures_trust): Do not print - the warning about --always_trust when --quiet is used. - - * pkclist.c (fpr_info): New and called at several places. - - * parse-packet.c (dump_sig_subpkt): List revocation key contents. - -Mon Jul 26 09:34:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (build_pk_list): Fixed typo in format string. - - * trustdb.c (create_shadow_dir): Don't translate the error string. - - * g10.c (main): Fixed spelling of user-id. - * getkey.c (find_by_name_pk,find_by_name_sk, - find_by_keyid,find_by_keyid_sk): Ditto and translate it. - * import.c (mark_non_selfsigned_uids_valid,delete_inv_parts): Ditto. - - -Mon Jul 26 01:01:39 CEST 1999 Michael Roth <mroth@nessie.de> - - * g10.c, options.h: New options --no-literal and --set-filesize - - * encode.c (encode_simple, encode_crypt): Support for the options - --no-literal and --set-filesize. - - * sign.c (sign_file): ditto. - -Fri Jul 23 13:53:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * ringedit.c (enum_keyblocks): Removed annoying error message in cases - when we have no keyring at all to enum. - - * getkey.c (classify_user_id): Rewrote to relax the recognition of - keyIDs and fingerprints (Michael). - - * mainproc.c (check_sig_and_print): Print status NO_PUBKEY. - (print_failed_pkenc): Print status NO_SECKEY. - - * import.c (mark_non_selfsigned_uids_valid): New. - * g10.c: New option --allow-non-selfsigned-uid. - - * pkclist.c (print_fpr): New. - (do_we_trust_pre): Print the fpr before asking whether to use the key - anyway. - (do_edit_ownertrust): Likewise. - -Thu Jul 22 20:03:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * ringedit.c (enum_keyblocks): Removed annoying error message in cases - when we have no keyring at all to enum. - - * getkey.c (classify_user_id): Rewrote to relax the recognition of - keyIDs and fingerprints (Michael). - - * mainproc.c (check_sig_and_print): Print status NO_PUBKEY. - (print_failed_pkenc): Print status NO_SECKEY. - - * import.c (mark_non_selfsigned_uids_valid): New. - * g10.c: New option --allow-non-selfsigned-uid. - -Thu Jul 15 10:15:35 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c: New options --disable-{cipher,pubkey}-algo. - -Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * status.h (STATUS_IMPORTED): New. - * import.c (import): Print some status information (Holger Schurig). - - * g10.c (main): Make --no-greeting work again. Add a warning when - --force-mds is used. - -Tue Jul 13 17:39:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (do_edit_ownertrust): Changed the way help works. - (build_pk_list): Implemented default recipient stuff. - * g10.c: New options --default-recipient[-self] - (main): Suppress greeting in most cases, entering a passphrase or - a missing value is not considered to be interactive use. - Merged --print-md and --print-mds; the latter is now obsolete. - Changed the way --gen-random works and documented it. - Changed the way --gen-prime works and add a man entry. - * g10.c (MAINTAINER_OPTIONS): Removed. - -Mon Jul 12 18:45:57 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keyedit.c (keyedit_menu): Add arg sign_mode and changed callers - * g10.c (main): New command --lsign-key. - -Mon Jul 12 14:55:34 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * mainproc.c (kidlist_item): New. - (release_list): Release failed pk-enc-list. - (print_failed_pkenc): New - (proc_encrypted): Print info about failed PK enc. - - * openfile.c (make_outfile_name): s/error/info/ - - * passphrase.c (passphrase_to_dek): Return an empty passphrase when - in batch mode and don't make the warning message fatal - * seckey-cert.c (check_secret_key): Try only once when in batch mode. - - * g10.c (make_username): New. - -Thu Jul 8 16:21:27 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * packet.h (PKT_ring_trust): New - * parse-packet.c (parse_trust): Store trust value - * build-packet (build_packet): Ignore ring trust packets. - * mainproc.c (add_ring_trust): New. - (list_node): Print "rtv" records. - * g10.c: New option --with-fingerprint. - - * trustdb.c (verify_own_keys): Don't insert if we are dry running - (check_trust): Ditto. - -Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * Makefile.am: Support for libtool. - - * keygen.c (ask_expire_interval): Hack to allow for an expire date. - - * trustdb.c (do_update_trust_record,update_trust_record): Splitted. - (check_trust_record): New. - (check_trust,build_cert_tree): Check the dir record as needed. - (upd_pref_record): Removed. - (make_pref_record): New. - (propagate_validity): Stop as soon as we have enough validity. - - * tbdio.c (MAX_CACHE_ENTRIES_HARD): Increased the limit. - - -Fri Jul 2 11:45:54 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c (g10_exit): Dump random stats. - - * sig-check.c (check_key_signature,check_key_signature2): Enhanced - version and wrapper for old function. - (do_signature_check,signature_check): Ditto. - -Thu Jul 1 12:47:31 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * keyedit.c (show_key_with_all_names): Print a notice for disabled keys. - (enable_disable_keys): Add functionality - * pkclist.c (edit_ownertrust): preserve disabled state. - (build_pk_list): Skip disabled keys. - * trustdb.c (upd_one_ownertrust): Ditto. - (build_cert_tree): Mask the ownertrust. - (trust_letter): Mask the value. - (do_check): Take disabled flag into account. - - * passphrase.c (passphrase_to_dek): Add a pubkey_algo arg and changed - all callers. - - * g10.c (utf8_strings): 2 new options. - - * trustdb.c (insert_trust_record_by_pk): New, replaces the next one. - (insert_trust_record): Now takes a keyblock as arg. Changed all - callers to use the appropritae function. - - * openfile.c (ask_outfile_name): New. - * plaintext.c (handle_plaintext): Ask for filename if there is - no valid syntax. Don't use fname varbatim but filter it. - -Tue Jun 29 21:44:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * trustdb.h (TRUST_FLAG_DISABLED): New. - - * status.c (USE_CAPABILITIES): Capabilities support (Remi). - - * tdbio.c : Added new fields to the DIR record. - (tdbio_write_record): Fixed the update of the hash tables. - (tdbio_delete_record): Drop the record from the hash tables. - (drop_from_hashtbl): New. - - * status.c (cpr_get): Special online help mode. - * helptext.c ("keyedit.cmd"): Removed. - * keyedit.c (keyedit_menu): Use only help system. - (enable_disable_key): New bit doies not yet work. - -Sat Jun 26 12:15:59 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * dearmor.c (enarmor_file): Fixed comment string. - * tdbdump.c (export_ownertrust): Text fix. - * tbio.c (tdbio_invalid): Ditto. - - * parse-packet.c (parse_key): Made temp buffer larger. - - * Makefile.am (install-data-local): Add missing backslashes - -Tue Jun 15 12:21:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c (main): Made iterated+salted the default S2K method. - - * Makefile.am (install-data-local): Use DESTDIR. - - * passphrase.c (passphrase_to_dek): Emit missing-passphrase while in - batchmode. - - * parse-packet.c (parse_pubkeyenc): Fixed a SEGV. - -Mon Jun 14 21:18:54 CEST 1999 Michael Roth <mroth@nessie.de> - - * g10.c: New options --openpgp, --no-tty, --emit-version, - --default-comment and --lock-multiple - -Thu Jun 10 14:18:23 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * free-packet.c (free_encrypted): Fixed EOF case (Remi). - (free_plaintext): Ditto. - - * helptext.c (keyedit.delsig.unknown): New (Remi). - * keyedit.c (print_and_check_one_sig): Add arg print_without_key and - changed all callers to make use of it (Remi): - -Tue Jun 8 13:36:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keylist.c (print_key_data): New and called elsewhere. - * g10.c: New option --with-key-data - -Wed Jun 2 14:17:19 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * mainproc.c (proc_tree): Yet another bad hack to cope with - broken pgp2 created detached messages in textmode. - -Tue Jun 1 16:01:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * openfile.c (make_outfile_name): New. - * plaintext.c (handle_plaintext): Outputfile is now the inputfile - without the suffix. - * g10.c: New option --use-embedded-filename - -Mon May 31 19:41:10 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c (main): Fix for SHM init (Michael). - - * compress.c, encr-data.c, mdfilter.c, - plaintext.c, free-packet.c: Speed patches (Rémi). - -Thu May 27 09:40:55 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * status.c (cpr_get_answer_yes_no_quit): New. - * keyedit.c (menu_delsig): New. - (check_all_keysigs): Splitted. - (print_and_check_one_sig): New. - -Wed May 26 14:36:29 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * build-packet.c (build_sig_subpkt): Support large packets. - * parse-packet.c (enum_sig_subpkt): Replaces parse_sig_subpkt. - * mainproc.c (print_notation_data): Print all notation packets. - * g10.c (add_notation_data): Add a way to specify the critical flag. - (main): Add option --set-policy-url. - (check_policy_url): Basic checks. - * sign.c (mk_notation_and_policy): Replaces mk_notation. - - * parse-packet.c (can_handle_critical): Moved decision whether we can - handle critical subpacket to an extra function. - -Tue May 25 19:50:32 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * sign.c (sign_file): Always use compression algo 1 for signed - onyl file becuase we can´ be sure the the verifier supports other - algorithms. - - * build-packet.c (build_sig_subpkt): Support for notation data. - * sign.c (sign_file,clearsign_file,make_keysig_packet): Ditto. - (mk_notation): New. - * g10.c (add_notation_data): New and add option -N - * mainproc.c (print_notation_data): New. - (check_sig_and_print): Print any notation data of the signed text. - -Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (check_signatures_trust): Print a warning and return - immediateley if opt.always_trust is true. - - * g10.c (main): Corrected handling of no-default-keyring - - * pkclist.c (algo_available): Disable Twofish until we have settled - how to do the MDC. - - * hkp.c: Disable everything for mingw32 - -Sat May 22 22:47:26 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * mainproc.c (check_sig_and_print): Add sig creation time to the - VALIDSIG status output. Add more info to the ERRSIG output. - * sig-check.c (signature_check): Add sig time after epoch to SIG_ID. - - * import.c (import_one): Merge duplicate user IDs. - (collapse_uids): New. - * kbnode.c (move_kbnode): New. - (remove_kbnode): New. - * keyedit.c (keyedit_menu): Call collapse_uids. - - * g10.c: new option --logger-fd. - - * import.c: s/log_*_f/log_*/ - -Thu May 20 14:04:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * misc.c (pull_in_libs): do the volatile only for gcc - - * sig-check (signature_check): Emit SIG_iD only for classes 0 and 1. - - * armor.c (armor_filter): Add detection of PGP2 created clearsigs. - (fake_packet): A tab is not a WS for pgp2 - handle this. - * textfilter.c (len_without_trailing_chars): New. - (copy_clearsig_text): Add pgp2mode arg. - * sign.c (clearsign_file): pass old_style to the above fnc. - - -Wed May 19 16:04:30 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c: New option --interactive. - - * mainproc.c (proc_plaintext): Add workaround for pgp2 bug - (do_check_sig): Ditto. - (proc_tree): Ditto. - * plaintext.c (do_hash): Ditto. - (hash_datafiles): Ditto, add an arg, changed all callers. - * mdfilter.c (md_filter): Add support for the alternate hash context. - -Mon May 17 21:54:43 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * parse-packet.c (parse_encrypted): Support for PKT_ENCRYPTED_MDC. - * build-packet.c (do_encrypted_mdc): Ditto. - * cipher.c (write_header): Add mdc hashing. - (cipher_filter): write out the hash. - * mainproc.c (do_proc_packets): Add PKT_ENCRYPTED_MDC. - * encr-data.c (decrypt_data): Add mdc hashing. - (mdc_decode_filter): New. - - * parse-packet.c (parse_sig_subpkt): Fixed stupid bug for subpkt - length calculation - (parse_signature): Fixed even more stupid bug. - -Sat May 8 19:28:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * build-packet.c (do_signature): Removed MDC hack. - * encode.c (encode_crypt_mdc): Removed. - * mainproc.c (do_check_sig): Removed MDC hack. - (check_sig_and_print): Ditto. - * parse-packet.c (parse_signature): Ditto. - * sig-check.c (mdc_kludge_check): Ditto. - * free-packte.c (copy_signature, free_seckey_enc): Ditto. - - * parse-packet.c (parse_signature,parse_key): Store data of - unknown algorithms with mpi_set_opaque inseatd of the old - faked data stuff. - (read_rest): Removed. - (read_rest2): Renamed to read_rest - * build-packet.c (write_fake_data): Use mpi_get_opaque. - * free-packet.c (cp_fake_data): Removed and cahnged all callers - to use mpi_copy. - (free_pubkey_enc,free_seckey_enc,release_public_key_parts, - release_secret_key_parts): Use mpi_free for opaque data. - -Thu May 6 14:18:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * trustdb.c (check_trust): Check for revoked subkeys. - * pkclist.c (do_we_trust): Handled revoked subkeys. - (do_we_trust_pre): Ditto. - (check_signatures_trust): Ditto. - - * build-packet.c (hash_public_key): Fix for ancient g10 keys. - - * mainproc.c (do_proc_packets): Return EOF if no data has been read. - * g10.c (main): Catch errors for default operation. - -Thu Apr 29 12:29:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * sign.c (sign_file): Fixed hashing in case of no subpackets. - (clearsign_file): Ditto. - (make_keysig_packet): Ditto. - -Wed Apr 28 13:03:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keyedit.c (keyedit_menu): Add new command revkey. - * (menu_revkey): New. - - -Mon Apr 26 17:48:15 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * parse-packet.c (parse_signature): Add the MDC hack. - * build-packet.c (do_signature): Ditto. - * free-packet.c (free_seckey_enc,copy_signature,cmp_signatures): Ditto. - * mainproc.c (do_check_sig): Ditto. - * sig-check.c (mdc_kludge_check): New. - * encode.c (encrypt_mdc_file): New. - - * keyedit.c (check_all_keysigs): List revocations. - * (menu_revsig): New. - * sign (make_keysig_packet): Support for class 0x30. - -Sun Apr 18 20:48:15 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (select_algo_from_prefs): Fixed the case that one key - has no preferences (Remi Guyomarch). - - keylist.c (list_keyblock): ulti_hack to propagate trust to all uids. - -Sun Apr 18 10:11:28 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * seckey-cert.c (do_check): Use real IV instead of a 0 one, so that - it works even if the length of the IV doesn't match the blocksize. - Removed the save_iv stuff. - (protect_secret_key): Likewise. Create the IV here. - * packet.h (PKT_secret_key): Increased size of IV field and add a - ivlen field. - * parse-packet.c (parse_key): Use the len protect.ivlen. - * build-packet.c (do_secret_key). Ditto. - - * getkey.c (key_byname): Close keyblocks. - - * Makefile.am (gpgm): Removed this - * g10.c: Merged gpg and gpgm - - * import.c (import): Utilize option quiet. - * tdbio.c (tdbio_set_dbname): Ditto. - * ringedit.c (add_keyblock_resource,keyring_copy): Ditto. - - * keyedit.c (sign_uids): Add some batch support. - - * g10.c (main): add call to tty_batchmode. - -Fri Apr 9 12:26:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * status.c (write_status_text): Some more status codes. - * passphrase_to_dek (passphrase_to_dek): add a status code. - * seckey_cert.c (check_secret_key): Likewise. - - * encr-data.c (decrypt_data): Reverse the last changes - * cipher.c (write_header): Ditto. - - * parse-packet.c (parse_key): Dropped kludge for ancient blowfish mode. - -Thu Apr 8 09:35:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * mainproc.c (proc_encrypted): Add a new status output - * passphrase.c (passphrase_to_dek): Ditto. - * status.h status.c: Add new status tokens. - -Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * encr-data.c (decrypt_data): Fixes for 128 bit blocksize - * cipher.c (write_header): Ditto. - * seckey-cert.c (do_check): Ditto. - (protect_secret_key). Ditto. - * misc.c (print_cipher_algo_note): Twofish is now a standard algo. - - * keygen.c (do_create): Fixed spelling (Gaël Quéri) - (ask_keysize): Only allow keysizes up to 4096 - - * ringedit.c (add_keyblock_resource): chmod newly created secrings. - - * import.c (delete_inv_parts): Fixed accidently deleted subkeys. - -Tue Apr 6 19:58:12 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c: Removed duped include (John Bley) - * mainproc.c: Ditto. - - * build-packet.c (hash_public_key): Fixed hashing of the header. - - * import.c (delete_inv_parts): Allow import of own non-exportable sigs. - -Sat Mar 20 13:59:47 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c (fake_packet): Fix for not not-dash-escaped - -Sat Mar 20 11:44:21 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c (main): Added command --recv-keys - * hkp.c (hkp_import): New. - -Wed Mar 17 13:09:03 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * trustdb.c (check_trust): add new arg add_fnc and changed all callers. - (do_check): Ditto. - (verify_key): Ditto. - (propagate_validity): Use the new add_fnc arg. - (print_user_id): Add the FILE arg. - (propagate_ownertrust): New. - * pkclist.c (add_ownertrust_cb): New and changed the add_ownertrust - logic. - - * getkey.c (get_keyblock_bylid): New. - * trustdb.c (print_uid_from_keyblock): New. - (dump_tn_tree_with_colons): New. - (list_trust_path): Add colon print mode. - - * trustdb.c (insert_trust_record): Always use the primary key. - - * encode.c (encode_simple): Added text_mode filter (Rémi Guyomarch) - (encode_crypt): Ditto. - - * mainproc.c (proc_pubkey_enc): Added status ENC_TO. - * armor.c (armor_filter): Added status NODATA. - * passphrase.c (passphrase_to_dek): Always print NEED_PASSPHRASE - * seckey_cert.c (check_secret_key): Added BAD_PASS status. - - * g10.c (main): Set g10_opt_homedir. - -Sun Mar 14 19:34:36 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keygen.c (do_create): Changed wording of the note (Hugh Daniel) - -Thu Mar 11 16:39:46 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * tdbdump.c: New - - * trustdb.c (walk_sigrecs,do_list_sigs,list_sigs, - list_records,list_trustdb,export_ownertrust,import_ownertrust): Moved - to tdbdump.c - (init_trustdb): renamed to setup_trustdb. Changed all callers. - (do_init_trustdb): renamed to init_trustdb(). - * trustdb.c (die_invalid_db): replaced by tdbio_invalid. - * tdbio.c (tdbio_invalid): New. - - * import.c (delete_inv_parts): Skip non exportable signatures. - * keyedit.c (sign_uid_mk_attrib): New. - (sign_uids): Add the local argument. - (keyedit_menu): New "lsign" command. - * trustdb.c (register_trusted_key): Removed this and all related stuff. - * g10.c (oTrustedKey): Removed option. - - * tdbio.h (dir.valcheck): New trustdb field. - * tdbio.c: Add support for this field - (tdbio_read_modify_stamp): New. - (tdbio_write_modify_stamp): New. - * trustdb.c (do_check): Check against this field. Removed cache update. - (verify_key): Add cache update. - (upd_uid_record): Some functional changes. - (upd_cert_record): Ditto - -Wed Mar 10 11:26:18 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keylist.c (list_keyblock): Fixed segv in uid. Print 'u' as - validity of sks. - -Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * getkey.c (classify_user_id): Add new mode 12 (#<lid>). - - * seckey-cert.c (check_secret_key): replaced error by info. - - * trustdb.c (query_trust_info): Add another arg, changed all callers. - (check_trust): Ditto. - (do_check): Ditto. - (verify_key): Handle namehash. - * keylist.c (list_keyblock): print trust info for user ids. - - * sig-check.c (signature_check): Add sig-created to status output. - -Tue Mar 2 16:44:57 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * textfilter.c (copy_clearsig_text): New. - (clearsign): Removed. - * sign.c (clearsign_file): does not use textfiler anymore. - - * keygen.c (ask_user_id): print a note about the used charset. - -Tue Mar 2 10:38:42 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * sig-check.c (signature_check): sig-id now works for all algos. - - * armor.c (armor_filter): Fixed armor bypassing. - -Sun Feb 28 19:11:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keygen.c (ask_user_id): Don't change the case of email addresses. - (has_invalid_email_chars): Adjusted. - - * keylist.c (list_one): Really list serect keys (Remi Guyomarch) - - * keyedit.c (menu_select_uid): Add some braces to make egcs happy. - (menu_select_key): Ditto. - - * mainproc.c (do_proc_packets): List sym-enc packets (Remi Guyomarch) - -Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (build_pk_list): Return error if there are no recipients. - - * sig-check.c (signature_check): New signature id feature. - * armor.c (make_radic64_string): New. - - * mainproc.c (proc_pubkey_enc): early check for seckey availability. - - * pkclist.c (do_we_trust_pre): print user id before asking. - - * ringedit.c (add_keyblock_resource,get_keyblock_handle): Cleaner - handling of default resource. - - -Thu Feb 25 18:47:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (algo_available): New. - (select_algo_from_prefs): Check whether algo is available. - - * ringedit.c (keyring_copy): Take care of opt.dry_run. - (do_gdbm_store): Ditto. - * openfile.c (open_outfile). Ditto. - (copy_options_file): Ditto. - * trustdb.c (update_trustdb): Ditto. - (clear_trust_checked_flag): Ditto. - (update_trust_record): Ditto. - (insert_trust_record): Ditto. - -Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keylist.c (secret_key_list): Now really list the secret key. - - * trustdb.c (do_init_trustdb): New. Init is now deferred. - -Mon Feb 22 20:04:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * getkey.c (lookup_sk): Return G10ERR_NO_SECKEY and not x_PUBKEY. - -Fri Feb 19 15:49:15 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (select_algo_from_prefs): retrieve LID if not there. - - * armor.c (fake_packet): Replaced ugly lineending handling. - - * g10.c (oNoEncryptTo): New. - * pkclist.c (build_pk_list): Implemented this option. - - * g10.c (main): Greeting is now printed to stderr and not to tty. - Use add_to_strlist() instead of direct coding. - - * import.c (import): Use iobuf_push_filter2. - - * mainproc.c (check_sig_and_print): Print all user ids - for good signatures. - * getkey.c (get_pubkeyblock): New. - - * import.c (chk_self_sigs): Fixed SEGV for unbounded class 0x18 keys. - (delete_inv_parts): Delete special marked packets. - -Tue Feb 16 14:10:02 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c (main): New option --encrypt-to - - * pkclist.c (build_pk_list): Implemented encrypt-to. - - * parse-packet.c (parse_user_id): Removed the hack to work with - utf-8 strings. - - * g10.c (main): Install lockfile cleanup handler. - * tdbio.c (cleanup): Removed: this is now handled by dotlock. - -Sat Feb 13 14:13:04 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * tdbio.c (tdbio_set_dbname): Init lockhandle for a new trustdb - -Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c (main): check for development version now in configure - - * tdbio.c (tdbio_write_record): Add uid.validity - (tdbio_read_record) : Ditto. - (tdbio_dump_record) : Ditto. - - * keygen.c (keygen_add_std_prefs): Replaced Blowfish by Twofish, - removed MD5 and Tiger. - * pubkey-enc.c (get_it): Suppress warning about missing Blowfish - in preferences in certain cases. - - * ringedit.c (lock_rentry,unlock_rentry): New. - - * getkey.c (key_byname): Pass ret_kb down to lookup_xx. - - * armor.c (armor_filter): No output of of empty comment lines. - Add option --no-version to suppress the output of the version string. - - * getkey.c: Release the getkey context for auto context variables. - -Sun Jan 24 18:16:26 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * getkey.c: Changed the internal design to allow simultaneous - lookup of multible user ids - (get_pubkey_bynames): New. - (get_seckey_bynames): New. - (get_seckey_next): New. - (get_seckey_end): New. - * keylist.c (list_one): Use the new functions. - - * keylist.c (list_keyblock): add a newline for normal listings. - - * g10.c (--recipient): New option name to replace --remote-user - - -Wed Jan 20 18:59:49 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * textfilter.c: Mostly rewritten - * plaintext.c (handle_plaintext): Use now text_filter semantics. - -Tue Jan 19 19:34:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * export.c (export_pubkeys_stream): New. - (do_export_stream): New. - * g10.c (aSendKeys): New command. - * hkp.c (hkp_export): New. - - * compress.c (do_uncompress): Hack for algo 1 and 1.1.3 - -Sun Jan 17 11:04:33 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * textfilter.c (text_filter): Now uses iobuf_read_line(). - (read_line): Removed. - - * armor.c (trim_trailing_spaces): Removed and replaced - by trim_trailing_ws from libutil - -Sat Jan 16 12:03:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * hkp.c (hkp_ask_import): Use only the short keyid - -Sat Jan 16 09:27:30 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * import.c (import_key_stream): New - (import): New, moved most of import_keys here. - * g10.c: New option --keyserver - * mainproc.c (check_sig_and_print): Hook to import a pubkey. - - * pref.c pref.h : Removed - - * hkp.c hkp.h: New - -Wed Jan 13 14:10:15 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c (radix64_read): Print an error if a bad armor was detected. - -Wed Jan 13 12:49:36 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c (radix64_read): Now handles malformed armors produced - by some buggy MUAs. - -Tue Jan 12 11:17:18 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * ringedit.c (find_keyblock_bysk): New. - - * skc_list.c (is_insecure): New. - (build_sk_list): usage check for insecure keys. - - * import.c (chk_self_sigs): Add handling for subkeys. - (delete_inv_parts): Skip unsigned subkeys - - * sig-check.c (do_check): Print info if the signature is older - than the key. - * keygen.c (generate_subkeypair): Fail on time warp. - * sign.c (do_sign): Ditto. - -Sun Jan 10 15:10:02 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c (fake_packet): Fixed not-dash-escaped bug. - -Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * sig-check.c (do_check): Output time diff on error - - * status.c (STATUS_VALIDSIG): New. - (is_status_enabled): New. - * mainproc.c (check_sig_and_print): Issue that status message. - - * plaintext.c (special_md_putc): Removed - - * armor.c (armor_filter): print error for truncated lines. - - * free-packet.c (free_encrypted): Revomed call to set_block_mode. - (free_plaintext): Ditto. - -Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (add_ownertrust): Fixed return value. - - * encr-data.c (decrypt_data): Disabled iobuf_set_limit and - iobuf_pop_filter stuff. - * compress.c (handle_compressed): Disabled iobuf_pop_filter. - - * packet.h (PKT_secret_key): Add is_primary flag. - * parse-packet.c (parse_key): Set this flag. - * passphrase.c (passphrase_to_dek): Kludge to print the primary - keyid - changed the API: keyid must now hold 2 keyids. - * getkey.c (get_primary_seckey): New. - * seckey-cert.c (do_check): pass primary keyid to passphrase query - - * tbdio.c (open_db): removed the atexit - (tdbio_set_dbname): and moved it to here. - - * armor.c: Rewrote large parts. - -Tue Dec 29 19:55:38 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * revoke.c (gen_revoke): Removed compression. - - * pkclist.c (do_we_trust_pre): special check for revoked keys - - * trustdb.c (update_trust_record): Fixed revoke flag. - -Tue Dec 29 14:41:47 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * misc.c (disable_core_dumps): Check for EINVAL (Atari) - - * getkey (merge_one_pk_and_selfsig): Fixed search of expiredate. - (merge_keys_and_selfsig): Ditto. - - * free-packet.c (cmp_public_keys): cmp expire only for v3 packets - (cmp_secret_keys): Ditto. - (cmp_public_secret_key): Ditto. - -Wed Dec 23 17:12:24 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c (find_header): Reset not_dashed at every header - -Wed Dec 23 13:18:14 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (add_ownertrust): Refresh validity values. - - * trustdb.c (enum_cert_paths_print): New arg refresh. - - * ringedit.c: Fixed problems fix keyrings - * parse-packet.c (dbg_parse_packet): New debug functions. - - * getkey.c (getkey_disable_caches): New. - * import.c (import_keys): Disable caches. - -Thu Dec 17 18:31:15 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * misc.c (trap_unaligned): Only for glibc 1 - - * sign.c (write_dash_escaped): Now escapes "From " lines - * g10.c: New option --escape-from-lines - - * trustdb.c (sort_tsl_list): New - (list_trust_path): Now prints sorted list. - (enum_cert_paths): Likewise. - (enum_cert_paths_print): New. - (print_paths): New printing format. - * pkclist.c (add_ownertrust): New arg quit. - (edit_ownertrust): New quit selection and does not query - the recipients ownertrust anymore. - (add_ownertrust): Print the ceritficate path. - - -Mon Dec 14 21:18:49 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * parse-packet.c (parse_signature): Now checks for critical bit - (parse_sig_subpkt): Splitted. - (parse_one_sig_subpkt): New. - * sig-check.c (do_check): handle critical bit. - -Sun Dec 13 14:10:56 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * pcklist.c (select_algo_from_prefs): Preferences should - now work (lost the != ? ) - -Thu Dec 10 20:15:36 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * ringedit.c (gdbm_store): Fix for inserts - - * g10.c (main): New option --export-all - * export.c (export_pubkeys): New arg. - (do_export): Now may skip old keys. - - * status.c: Minor patches for Sun's cc - - * keygen.c (ask_algo): Disabled v3 ElGamal choice, rearranged - the numbers. Add a warning question when a sign+encrypt key - is selected. - - * g10.c (do_not_use_RSA): Removed. - * misc.c (print_pubkey_algo_note): New as replacement for the - do_not_use_RSA() and chnaged all callers. - (print_cipher_algo_note): New. - (print_hash_algo_note): New. - - * cipher.c (write_header): Add a call to print_cipher_algo_note. - * seckey-cert.c (protect_secret_key): Ditto - * sign.c (do_sign): Add a call to print_digest_algo_note. - - * getkey.c (get_long_user_id_string): New. - * mainproc.c (check_sig_and_print): Changed the format of the - status output. - - * encrypt.c (write_pubkey_enc_from_list): print used symmetric cipher. - - * pkclist.c (do_we_trust): Changed a message. - -Wed Dec 9 13:41:06 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * misc.c (trap_unaligned) [ALPHA]: Only if UAC_SIGBUS is defined. - - * sign.c (write_dash_escaped): Add the forgotten patch by Brian Moore. - - * compress.c (do_uncompress): Fixed the inflating bug. - - -Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * trustdb.c (upd_uid_record): Now uses the newest self-signature - (insert_trust_record): Now calls update with recheck set to true. - (register_trusted_key): New. - (verify_own_keys): Enhanced by list of trusted keys. - - * g10.c (main): Print a warning when a devel version is used. - (main): New option --trusted-key - - * import.c (merge_blocks): Fixed merging of new user ids and - added merging of subkeys. - (append_uid): Ditto. - (merge_keysig): New. - (append_key): New. - * getkey.c (merge_one_pk_and_selfsig): Get the expiration time - from the newest self-signature. - (merge_keys_and_selfsig): Ditto. - - * free-packet.c (cmp_secret_key): New. - - -Fri Nov 27 21:37:41 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c: New option --lock-once - * tdbio.c (open_db): Add an atexit - (cleanup): New. - (tdbio_sync): Add locking. - (tdbio_end_transaction): Ditto. - (put_record_into_cache): Ditto. - * ringedit.c (keyring_copy): Ditto. - (cleanup): New. - (add_keyblock_resource): Add an atexit. - -Fri Nov 27 15:30:24 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c (find_header): Another fix for clearsigs. - -Fri Nov 27 12:39:29 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - - * status.c (display_help): Removed. - * helptext.c: New and removed the N_() from all cpr_gets. - - -Fri Nov 20 16:54:52 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): New option --not-dash-escaped - * sign.c (write_dashed_escaped): Ditto. - * armor.c (find_header): Support for NotDashEscaped header. - - * getkey.c: print "disabled cache.." only if verbose is used. - -Thu Nov 19 07:17:31 1998 Werner Koch <werner.koch@guug.de> - - * parse-packet.c (dump_sig_subpkt): Fixed expire listing - * getkey.c (merge_keys_and_selfsig): Fixed expire calculation. - (merge_one_pk_and_selfsig): Ditto. - * keyedit.c (menu_expire). Ditto. - * keygen.c (keygen_add_key_expire): Ditto. - (ask_expire_interval): New and changed all local function to use - this instead. - (keygen_add_key_expire): Opaque should now be a public key; - changed all callers. - - * parse.packet.c (parse): use skip_rest to skip packets. - - * keyedit.c (keyedit_menu): New arg for cmdline cmds. - -Wed Nov 18 20:33:50 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (check_trustdb): Now rechecks all gived userids. - (collect_paths): Some fixes. - (upd_pref_records): Skips empty items, evaluate all items. - - * parse-packet.c (dump_sig_subpkt): Better listing of prefs. - (skip_packet): Now knows about marker packet - - * g10.c: removed cmd "--edit-sig". - - * pubring.asc: Updated. - -Sat Nov 14 14:01:29 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Changed syntax of --list-trust-path - * trustdb.c (list_trust_path): Replaced max_depth by - opt.max_cert_depth - -Fri Nov 13 07:39:58 1998 Werner Koch <werner.koch@guug.de> - - * trustdb.c (collect_paths): Removed a warning message. - (enum_trust_web): Removed. - (enum_cert_paths): New. - * pkclist.c (add_ownertrust): Changed to use enum_cert_paths. - (edit_ownertrust): Now list ceritficates on request. - (show_paths): New. - -Wed Nov 11 18:05:44 1998 Werner Koch <werner.koch@guug.de> - - * g10.c (main): New option --max-cert-depth - * tdbio.h: add new fields to ver and dir record. - * tdbio.c: read/write/dump of these fields. - (tdbio_db_matches_options): New. - * trustdb.c: replaced MAC_CERT_DEPTH by opt.max_cert_depth. - (do_check): cache validity and changed other functions - to reset the cached value. - - * keylist.c (list_one): Now lists the ownertrust. - * mainproc.c (list_node): Ditto. - -Tue Nov 10 10:08:59 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (g10_exit): Now looks at the new g10_errors_seen. - * mainproc.c (check_sig_and_print): Sets g10_errors_seen. - - * *.c : i18n many more strings. - - * ringedit.c (locate_keyblock_by_keyid): Add HAVE_LIBGDBM - (locate_keyblock_by_fpr): Ditto. - - * g10.c (main): removed unsused "int errors". - (main): Add new option --charset. - - * g10.c (main): special message for the unix newbie. - -Mon Nov 9 07:17:42 1998 Werner Koch <werner.koch@guug.de> - - * getkey.c (finish_lookup): Kludge to prefere algo 16. - - * trustdb.c (new_lid_table): Clear cached item. - - * status.c (cpr_get_utf8): New. - * pkclist.c (build_pk_list): Uses this. - -Sun Nov 8 17:20:39 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mainproc.c (check_sig_and_print): Why did I use strlen()-1 - in the printf? - This truncated the TZ. - -Sat Nov 7 15:57:28 1998 me,,, (wk@tobold) - - * getkey.c (lookup): Changes to support a read_next. - (get_pubkey): Fixed a memory leak. - - * keylist.c (list_one): Now lists all matching user IDs. - -Tue Nov 3 16:19:21 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (ask_user_id): Now converted to UTF-8 - - * g10.c (main): Kludge for pgp clearsigs and textmode. - -Fri Oct 30 16:40:39 1998 me,,, (wk@tobold) - - * signal.c (block_all_signals): New. - (unblock_all_signals): New - * tdbio.c (tdbio_end_transaction): Now blocks all signals. - - * trustdb.c (new_lid_table): Changed the representation of the - former local_lid_info stuff. - - * trustdb.c (update_trust_record): Reorganized the whole thing. - * sig-check.c (check_key_signature): Now handles class 0x28 - - -Wed Oct 28 18:56:33 1998 me,,, (wk@tobold) - - * export.c (do_export): Takes care of the exportable sig flag. - -Tue Oct 27 14:53:04 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (update_trust_record): New "fast" parameter. - -Sun Oct 25 19:32:05 1998 Werner Koch (wk@isil.d.shuttle.de) - - * openfile.c (copy_options_File): New. - * ringedit.c (add_keyblock_resource): Creates options file - * tdbio.c (tdbio_set_dbname): Ditto. - -Sat Oct 24 14:10:53 1998 brian moore <bem@cmc.net> - - * mainproc.c (proc_pubkey_enc): Don't release the DEK - (do_proc_packets): Ditto. - -Fri Oct 23 06:49:38 1998 me,,, (wk@tobold) - - * keyedit.c (keyedit_menu): Comments are now allowed - - * trustdb.c: Rewrote large parts. - - -Thu Oct 22 15:56:45 1998 Michael Roth (mroth@nessie.de) - - * encode.c: (encode_simple): Only the plain filename without - a given directory is stored in generated packets. - (encode_crypt): Ditto. - - * sign.c: (sign_file) Ditto. - - -Thu Oct 22 10:53:41 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (update_trust_record): Add new optional arg. - - * import.c (import_keys): Add statistics output - * trustdb.c (update_trustdb): Ditto. - (insert_trustdb): Ditto. - - * tdbio.c (tdbio_begin_transaction): New. - (tdbio_end_transaction): New. - (tdbio_cancel_transaction): New. - - * g10.c (main): New option --quit. - - * trustdb.c (check_hint_sig): No tests for user-id w/o sig. - This caused an assert while checking the sigs. - - * trustdb.c (upd_sig_record): Splitted into several functions. - - * import.c (import_keys): New arg "fast". - * g10.c (main): New command --fast-import. - -Wed Oct 21 18:19:36 1998 Michael Roth <mroth@nessie.de> - - * ringedit.c (add_keyblock_resource): Directory is now created. - * tdbio.c (tdbio_set_dbname): New info message. - -Wed Oct 21 11:52:04 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (update_trustdb): released keyblock in loop. - - * keylist.c (list_block): New. - (list_all): Changed to use list_block. - - * trustdb.c: Completed support for GDBM - - * sign.c (only_old_style): Changed the way force_v3 is handled - (sign_file): Ditto. - (clearsign_file): Ditto. - - * keygen.c (has_invalid_email_chars): Splitted into mailbox and - host part. - - * keylist.c (list_one): Add a merge_keys_and_selfsig. - * mainproc.c (proc_tree): Ditto. - -Sun Oct 18 11:49:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * sign.c (only_old_style): Add option force_v3_sigs - (sign_file): Fixed a bug in sig->version - (clearsign_file): Ditto. - - * parse-packet.c (dump_sig_subpkt): New - - * keyedit.c (menu_expire): New. - * free-packet.c (cmp_signatures): New - - -Sat Oct 17 10:22:39 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c: changed output line length from 72 to 64. - - * keyedit.c (fix_keyblock): New. - -Fri Oct 16 10:24:47 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c: Rewrote most. - * tdbio.c: Add cache and generalized hash tables. - - * options.h (ENABLE_COMMENT_PACKETS): New but undef'ed. - * encode.c, sign.c, keygen.c: Disabled comment packets. - * export.c (do_export): Comment packets are never exported, - except for those in the secret keyring. - - * g10.c (main): Removed option do-no-export-rsa; should be - be replaced by a secpial tool. - * export.c (do_export): Removed the code for the above option. - - * armor.c (find_header): Support for new only_keyblocks. - * import.c (import_keys): Only looks for keyblock armors. - - * packet.h: replaced valid_days by expiredate and changed all users. - * build-packet.c (do_public_key): calculates valid-days - (do_secret_key): Ditto. - * parse-packet.c (parse_key): expiredate is calucated from the - valid_period in v3 packets. - * keyid.c (do_fingerprint_md): calculates valid_dates. - - * keygen.c (add_key_expire): fixed key expiration time for v4 packets. - - * armor.c (find_header): A LF in the first 28 bytes - was skipped for non-armored data. - -Thu Oct 8 11:35:51 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (is_armored): Add test on old comment packets. - - * tdbio.c (tdbio_search_dir_bypk): fixed memory leak. - - * getkey.c: Changed the caching algorithms. - -Wed Oct 7 19:33:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * kbnodes.c (unused_nodes): New. - -Wed Oct 7 11:15:36 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keyedit.c (sign_uids): Fixed a problem with SK which could caused - a save of an unprotected key. - (menu_adduid): Ditto. - - * keyedit.c (keyedit_menu): Prefs are now correctly listed for - new user ids. - - * trustdb.c (update_trust_record): New. - (insert_trust_record): Now makes use of update_trust_record. - -Tue Oct 6 16:18:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (read_record): replaces most of the tdbio_read_records. - (write_record): Ditto. - -Sat Oct 3 11:01:21 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (ask_alogo): enable ElGamal enc-only only for addmode. - -Wed Sep 30 10:15:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * import.c (import_one): Fixed update of wrong keyblock. - -Tue Sep 29 08:32:08 1998 me,,, (wk@tobold) - - * mainproc.c (proc_plaintext): Display note for special filename. - * plaintext.c (handle_plaintext): Suppress output of special file. - -Mon Sep 28 12:57:12 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (verify_own_keys): Add warning if a key is not protected. - - * passphrase (hash_passphrase): Fixed iterated+salted mode and - setup for keysizes > hashsize. - - * g10.c (main): New options: --s2k-{cipher,digest,mode}. - -Fri Sep 25 09:34:23 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c: Chnaged some help texts. - -Tue Sep 22 19:34:39 1998 Werner Koch (wk@isil.d.shuttle.de) - - * passphrase.c (read_passphrase_from_fd): fixed bug for long - passphrases. - -Mon Sep 21 11:28:05 1998 Werner Koch (wk@(none)) - - * getkey.c (lookup): Add code to use the sub key if the primary one - does not match the usage. - - * armor.c (armor_filter): New error message: no valid data found. - (radix64_read): Changes to support multiple messages. - (i18n.h): New. - * mainproc.c (add_onepass_sig): bug fix. - -Mon Sep 21 08:03:16 1998 Werner Koch (wk@isil.d.shuttle.de) - - * pkclist.c (do_we_trust): Add keyid to most messages. - - * passphrase.c (read_passphrase_from_fd): New. - (have_static_passphrase): New - (get_passphrase_fd): Removed. - (set_passphrase_fd): Removed. - * g10.c (main): passphrase is now read here. - - * keyedit.c (keyedit_menu): "help" texts should now translate fine. - -Mon Sep 21 06:40:02 1998 Werner Koch (wk@isil.d.shuttle.de) - - * encode.c (encode_simple): Now disables compression - when --rfc1991 is used. - (encode_crypt): Ditto. - -Fri Sep 18 16:50:32 1998 Werner Koch (wk@isil.d.shuttle.de) - - * getkey.c (merge_key_and_selfsig): New. - -Fri Sep 18 10:20:11 1998 Werner Koch (wk@isil.d.shuttle.de) - - * pkclist.c (select_algo_from_prefs): Removed 3DES kludge. - - * seskey.c (make_session_key): Fixed SERIOUS bug introduced - by adding the weak key detection code. - - * sign.c (sign_file): Changed aremor header in certain cases. - -Tue Sep 15 17:52:55 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mainproc.c (check_sig_and_print): Replaced ascime by asctimestamp. - -Mon Sep 14 11:40:52 1998 Werner Koch (wk@isil.d.shuttle.de) - - * seskey.c (make_session_key): Now detects weak keys. - - * trustdb (clear_trust_checked_flag): New. - - * plaintext.c (handle_plaintext): Does no anymore suppress CR from - cleartext signed messages. - -Sun Sep 13 12:54:29 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (insert_trust_record): Fixed a stupid bug in the free - liunked list loops. - -Sat Sep 12 15:49:16 1998 Werner Koch (wk@isil.d.shuttle.de) - - * status.c (remove_shmid): New. - (init_shm_comprocess): Now sets permission to the real uid. - -Wed Sep 9 11:15:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h (PKT_pubkey_enc): New flah throw_keyid, and add logic to - implement it. - * g10.c (main): New Option --throw-keyid - - * getkey.c (enum_secret_keys): Add new ar and changed all callers. - -Tue Sep 8 20:04:09 1998 Werner Koch (wk@isil.d.shuttle.de) - - * delkey.c (delete_key): Moved from keyedit.c. - -Mon Sep 7 16:37:52 1998 Werner Koch (wk@isil.d.shuttle.de) - - * build-packet.c (calc_length_header): New arg new_ctb to correctly - calculate the length of new style packets. - - * armor.c (is_armored): Checks for symkey_enc packets. - - * pkclist.c (select_algo_from_prefs): 3DEs substitute is now CAST5. - -Tue Aug 11 17:54:50 1998 Werner Koch (wk@isil.d.shuttle.de) - - * build-packet.c (do_secret_key): Fixed handling of old keys. - - * getkey.c (compare_name): Fixed exact and email matching - - * openfile.c (open_outfile): Changed arguments and all callers. - -Tue Aug 11 09:14:35 1998 Werner Koch (wk@isil.d.shuttle.de) - - * encode.c (encode_simple): Applied option set-filename and comment. - (encode_crypt): Ditto. - * sign.c (sign_file): Ditto. - * armor.c (armor_filter): Applied option comment. - - * encode.c (encode_crypt): Moved init_packet to the begin. - (encode_simple): add an init_packet(). - - * comment (write_comment): Now enforces a hash sign as the 1st byte. - - * import.c (import_one): Add explanation for "no user ids". - - * compress.c (do_uncompress): Applied Brian Warner's patch to support - zlib 1.1.3 etc. - - * trustdb.c (check_trust): Fixed a problem after inserting new keys. - - * getkey (lookup): do not return the primary key if usage is given - (lookup_sk): Ditto and take usage into account. - - * status.c (cpr_get_answer_is_yes): add display_help. - -Mon Aug 10 10:11:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * getkey.c (lookup_sk): Now always returns the primary if arg - primary is true. - (lookup): Likewise. - (get_pubkey_byname): Now returns the primary key - (get_seckey_byname): Ditto. - - -Mon Aug 10 08:34:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keyid.c (pubkey_letter): ELG_E is now a small g. - -Sat Aug 8 17:26:12 1998 Werner Koch (wk@isil.d.shuttle.de) - - * openfile (overwrite_filep): Changed semantics and all callers. - -Sat Aug 8 12:17:07 1998 Werner Koch (wk@isil.d.shuttle.de) - - * status.c (display_help): New. - -Thu Aug 6 16:30:41 1998 Werner Koch,mobil,,, (wk@tobold) - - * seskey.c (encode_session_key): Now uses get_random_bits(). - -Thu Aug 6 07:34:56 1998 Werner Koch,mobil,,, (wk@tobold) - - * ringedit.c (keyring_copy): No more backupfiles for - secret keyrings and add additional warning in case of - a failed secret keyring operation. - -Wed Aug 5 11:54:37 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (check_opts): Moved to main. Changed def_cipher_algo - semantics and chnaged all users. - - * pubkey-enc.c (get_sssion_key): New informational output - about preferences. - - * parse-packet.c (parse_symkeyenc): Fixed salted+iterated S2K - (parse_key): Ditto. - * build-packet.c (do_secret_key): Ditto. - (do_symkey_enc): Ditto. - -Tue Aug 4 08:59:10 1998 Werner Koch (wk@isil.d.shuttle.de) - - * getkey.c (enum_secret_keys): Now returns only primary keys. - - * getkey (lookup): Now sets the new namehash field. - - * parse-packet.c (parse_sig_subpkt2): New. - - * sign.c (sign_file): one-pass sigs are now emiited reverse. - Preference data is considered when selecting the compress algo. - -Wed Jul 29 12:53:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * free-packet.c (copy_signature): New. - - * keygen.c (generate_subkeypair): rewritten - * g10.c (aKeyadd): Removed option --add-key - -Mon Jul 27 10:37:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * seckey-cert.c (do_check): Additional check on cipher blocksize. - (protect_secret_key): Ditto. - * encr-data.c: Support for other blocksizes. - * cipher.c (write_header): Ditto. - -Fri Jul 24 16:47:59 1998 Werner Koch (wk@isil.d.shuttle.de) - - * kbnode.c (insert_kbnode): Changed semantics and all callers. - * keyedit.c : More or less a complete rewrite - -Wed Jul 22 17:10:04 1998 Werner Koch (wk@isil.d.shuttle.de) - - * build-packet.c (write_sign_packet_header): New. - -Tue Jul 21 14:37:09 1998 Werner Koch (wk@isil.d.shuttle.de) - - * import.c (import_one): Now creates a trustdb record. - - * g10.c (main): New command --check-trustdb - -Mon Jul 20 11:15:07 1998 Werner Koch (wk@isil.d.shuttle.de) - - * genkey.c (generate_keypair): Default key is now DSA with - encryption only ElGamal subkey. - -Thu Jul 16 10:58:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keyid.c (keyid_from_fingerprint): New. - * getkey.c (get_pubkey_byfprint): New. - -Tue Jul 14 18:09:51 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keyid.c (fingerprint_from_pk): Add argument and changed all callers. - (fingerprint_from_sk): Ditto. - -Tue Jul 14 10:10:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * plaintext.c (handle_plaintext): Now returns create error if - the file could not be created or the user responded not to overwrite - the file. - * mainproc.c (proc_plaintext): Tries again if the file could not - be created to check the signature without output. - - * misc.c (disable_core_dumps): New. - * g10.c (main): disable coredumps for gpg - - * g10.c (MAINTAINER_OPTIONS): New to disable some options - -Mon Jul 13 16:47:54 1998 Werner Koch (wk@isil.d.shuttle.de) - - * plaintext.c (hash_datafiles): New arg for better support of - detached sigs. Changed all callers. - * mainproc.c (proc_signature_packets): Ditto. - - * g10.c (main): New option "compress-sigs" - * sig.c (sign_file): detached signatures are not anymore compressed - unless the option --compress-sigs is used. - -Thu Jul 9 19:54:54 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c: Fixes to allow zero length cleartext signatures - -Thu Jul 9 14:52:47 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (build_list): Now drops setuid. - (main): Changed the way keyrings and algorithms are registered . - -Wed Jul 8 14:17:30 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h (PKT_public_key): Add field keyid. - * parse-packet.c (parse_key): Reset the above field. - * keyid.c (keyid_from_pk): Use above field as cache. - - * tdbio.c, tdbio.h: New - * trustdb.c: Moved some functions to tdbio.c. - (print_keyid): New. - - * pkclist.c (check_signatures_trust): New. - -Wed Jul 8 10:45:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * plaintext.c (special_md_putc): New. - (handle_plaintext): add clearsig argument - * mainproc.c (proc_plaintext): detection of clearsig - * sign.c (write_dased_escaped): Changed clearsig format - -Tue Jul 7 18:56:19 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (find_header): Now makes sure that there is only one - empty line for clearsigs, as this is what OP now says. - -Mon Jul 6 13:09:07 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): New option default-secret-key - * getkey.c (get_seckey_byname): support for this option. - -Mon Jul 6 09:03:49 1998 Werner Koch (wk@isil.d.shuttle.de) - - * getkey.c (add_keyring): Keyrings are now added to end of the - list of keyrings. The first added keyringwill be created. - (add_secret_keyring): Likewise. - - * ringedit.c (add_keyblock_resource): Files are created here. - - * g10.c (aNOP): Removed - - * getkey.c (lookup): Add checking of usage for name lookups - * packet.h (pubkey_usage): Add a field which may be used to store - usage capabilities. - * pkclist.c (build_pk_list): getkey now called with usage arg. - * skclist.c (build_sk_list): Ditto. - - * sign.c (clearsign_file): Fixed "Hash:" headers - -Sat Jul 4 13:33:31 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (list_ownertrust): New. - * g10.c (aListOwnerTrust): New. - - * g10.c (def_pubkey_algo): Removed. - - * trustdb.c (verify_private_data): Removed and also the call to it. - (sign_private_data): Removed. - -Fri Jul 3 13:26:10 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (aEditKey): was aEditSig. Changed usage msg. - - * keyedit.c: Done some i18n stuff. - - * g10.c (do_not_use_RSA): New. - * sign.c (do_sign): Add call to above function. - * encode.c (write_pubkey_enc_from_list): Ditto. - -Thu Jul 2 21:01:25 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c: Now is able sto store data of unknown - algorithms. - * free-packet.c: Support for this. - * build-packet.c: Can write data of packet with unknown algos. - -Thu Jul 2 11:46:36 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c (parse): fixed 4 byte length header - -Wed Jul 1 12:36:55 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h (new_ctb): New field for some packets - * build-packet.c (build_packet): Support for new_ctb - * parse-packet.c (parse): Ditto. - -Mon Jun 29 12:54:45 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h: changed all "_cert" to "_key", "subcert" to "subkey". - - * free-packet.c (free_packet): Removed memory leak for subkeys. - -Sun Jun 28 18:32:27 1998 Werner Koch (wk@isil.d.shuttle.de) - - * import.c (import_keys): Renamed from import_pubkeys. - (import_secret_one): New. - - * g10.c (aExportSecret): New. - - * export.c (export_seckeys): New. - - * parse-packet.c (parse_certificate): Cleaned up. - (parse_packet): Trust packets are now considered as unknown. - (parse_pubkey_warning): New. - -Fri Jun 26 10:37:35 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (has_invalid_email_chars): New. - -Wed Jun 24 16:40:22 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (armor_filter): Now creates valid onepass_sig packets - with all detected hash algorithms. - * mainproc.c (proc_plaintext): Now uses the hash algos as specified - in the onepass_sig packets (if there are any) - -Mon Jun 22 11:54:08 1998 Werner Koch (wk@isil.d.shuttle.de) - - * plaintext.c (handle_plaintext): add arg to disable outout - * mainproc.c (proc_plaintext): disable output when in sigs_only mode. - -Thu Jun 18 13:17:27 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c: Removed all rsa packet stuff, chnaged defaults - for key generation. - -Sun Jun 14 21:28:31 1998 Werner Koch (wk@isil.d.shuttle.de) - - * misc.c (checksum_u16): Fixed a stupid bug which caused a - wrong checksum calculation for the secret key protection and - add a backward compatibility option. - * g10.c (main): Add option --emulate-checksum-bug. - -Thu Jun 11 13:26:44 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h: Major changes to the structure of public key material - which is now stored in an array and not anaymore in a union of - algorithm specific structures. These is needed to make the system - more extendable and makes a lot of stuff much simpler. Changed - all over the system. - - * dsa.c, rsa.c, elg.c: Removed. - -Wed Jun 10 07:22:02 1998 Werner Koch,mobil,,, (wk@tobold) - - * g10.c ("load-extension"): New option. - -Mon Jun 8 22:23:37 1998 Werner Koch (wk@isil.d.shuttle.de) - - * seckey-cert.c (do_check): Removed cipher constants - (protect_secret_key): Ditto. - -Fri May 29 10:00:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (query_trust_info): New. - * keylist.c (list_one): Add output of trust info - * mainproc (list_node): ditto. - * g10.c (main): full trustdb init if -with-colons and any of the - key list modes. - -Thu May 28 10:34:42 1998 Werner Koch (wk@isil.d.shuttle.de) - - * status.c (STATUS_RSA_OR_IDEA): New. - * sig-check.c (check_signature): Output special status message. - * pubkey-enc.c (get_session_key): Ditto. - - * mainproc.c (check_sig_and_print): Changed format of output. - * passpharse.c (passphrase_to_dek): Likewise. - -Wed May 27 13:46:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (aListSecretKeys): New option --list-secret-keys - * keylist.c (std_key_list): Renamed to public_key_list. - (secret_key_list): New - (list_one, list_all): Add support for secret keys. - * getkey.c (get_secret_keyring): New. - * mainproc.c (list_node): Add option --with-colons for secret keys - - * sig-check.c (check_key_signature): detection of selfsigs - * mainproc.c (list_node): fixed listing. - - * g10.c (aListSecretKeys): New option --always-trust - * pkclist.c (do_we_trust): Override per option added - - * status.c (write_status_text): Add a prefix to every output line. - -Wed May 27 07:49:21 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10 (--compress-keys): New. - * options.h (compress_keys): New. - * export.c (export_pubkeys): Only compresses with the new option. - -Tue May 26 11:24:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * passphrase.c (get_last_passphrase): New - (set_next_passphrase): New. - (passphrase_to_dek): add support for the above functions. - * keyedit.c (make_keysig_packet): Add sigclass 0x18, - changed all callers due to a new argument. - * keygen.c (write_keybinding): New - (generate_subkeypair): Add functionality - (ask_algo, ask_keysize, ask_valid_days): Broke out of generate_keypair - (ask_user_id, ask_passphrase): Ditto. - -Thu May 21 11:26:13 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c,gpgd.c (main): Does now return an int, so that egcs does - not complain. - - * armor.c (fake_packet): Removed erro message and add a noticed - that this part should be fixed. - - * sign.c (sign_file): Compression now comes in front of encryption. - * encode.c (encode_simple): Ditto. - (encode_crypt): Ditto. - -Tue May 19 16:18:19 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (fake_packet): Changed assertion to log_error - -Sat May 16 16:02:06 1998 Werner Koch (wk@isil.d.shuttle.de) - - * build-packet.c (build_packet): Add SUBKEY packets. - -Fri May 15 17:57:23 1998 Werner Koch (wk@isil.d.shuttle.de) - - * sign.c (hash_for): New and used in all places here. - * main.h (DEFAULT_): new macros. - * g10.c (opt.def_digest_algo): Now set to 0 - - * compress.c (init_compress): Add support for algo 1 - * options.h (def_compress_algo): New - * g10.c (main): New option --compress-algo - -Fri May 15 13:23:59 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (print_mds): New feature to print only one hash, - chnaged formatting. - -Thu May 14 15:36:24 1998 Werner Koch (wk@isil.d.shuttle.de) - - * misc.c (trap_unaligned) [__alpha__]: New - * g10.c (trap_unaligned): Add call to this to track down SIGBUS - on Alphas (to avoid the slow emulation code). - -Wed May 13 11:48:27 1998 Werner Koch (wk@isil.d.shuttle.de) - - * build-packet.c (do_signature): Support for v4 pakets. - * keyedit.c (make_keysig_packet): Ditto. - * build-packet.c (build_sig_subpkt_from_sig): New. - (build_sig_subpkt): New. - - * elg.c (g10_elg_sign): removed keyid_from_skc. - * dsa.c (g10_dsa_sign): Ditto. - * rsa.c (g10_rsa_sign): Ditto. - * keyedit.c (make_keysig_packet): Add call to keyid_from_skc - - * sign.c (clearsign_file): Support for v4 signatures. - (sign_file): Ditto. - -Wed May 6 09:31:24 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c (do_parse): add support for 5 byte length leader. - (parse_subpkt): Ditto. - * build-packet.c (write_new_header): Ditto. - - * packet.h (SIGSUBPKT_): New constants. - * parse-packet.c (parse_sig_subpkt): Changed name, made global, - and arg to return packet length, chnaged all callers - - -Tue May 5 22:11:59 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (gen_dsa): New. - * build_packet.c (do_secret_cert): Support for DSA - -Mon May 4 19:01:25 1998 Werner Koch (wk@isil.d.shuttle.de) - - * compress.c: doubled buffer sizes - * parse-packet.c (do_plaintext): now uses iobuf_read/write. - -Mon May 4 09:35:53 1998 Werner Koch (wk@isil.d.shuttle.de) - - * seskey.c (encode_md_value): Add optional argument hash_algo, - changed all callers. - - * passphrase.c (make_dek_from_passphrase): Removed - * (get_passhrase_hash): Changed name to passphrase_to_dek, add arg, - changed all callers. - - * all: Introduced the new ELG identifier and added support for the - encryption only one (which is okay to use by GNUPG for signatures). - -Sun May 3 17:50:26 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h (PKT_OLD_COMMENT): New name for type 16. - * parse-packet.c (parse_comment): Now uses type 61 - -Fri May 1 12:44:39 1998 Werner Koch,mobil,,, (wk@tobold) - - * packet.h (count): Chnaged s2k count from byte to u32. - * seckey-cert.c (do_check): Changed s2k algo 3 to 4, changed - reading of count. - * build-packet.c (do_secret_cert): ditto. - * parse-packet.c (parse_certificate): ditto. - - * parse-packet.c (parse_symkeyenc): New. - * build-packet.c (do_symkey_enc): New. - -Thu Apr 30 16:33:34 1998 Werner Koch (wk@isil.d.shuttle.de) - - * sign.c (clearsign_file): Fixed "Hash: " armor line. - -Tue Apr 28 14:27:42 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c (parse_subpkt): Some new types. - -Mon Apr 27 12:53:59 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Add option --skip-verify. - * mainproc.c (check_sig_and_print): Ditto. - - * g10.c (print_mds): Add output for Tiger. - - * sign.c (sign_file): Now uses partial length headers if used - in canonical textmode (kludge to fix a bug). - - * parse-packet.c (parse_certificate): Changed BLOWFISH id. - * pubkey-enc.c (get_session_key): Ditto. - * seskey.c (make_session_key): Ditto. - * seckey-cert.c (protect_secret_key,do_check): Add BLOWFISH160. - -Fri Apr 24 17:38:48 1998 Werner Koch,mobil,,, (wk@tobold) - - * sig-check.c (check_key_signature): Add sig-class 0x14..0x17 - * keyedit.c (sign-key): Some changes to start with support of - the above new sig-classes. - -Wed Apr 22 09:01:57 1998 Werner Koch,mobil,,, (wk@tobold) - - * getkey.c (compare_name): add email matching - -Tue Apr 21 16:17:12 1998 Werner Koch,mobil,,, (wk@tobold) - - * armor.c (armor_filter): fixed missing last LF before CSUM. - -Thu Apr 9 11:35:22 1998 Werner Koch (wk@isil.d.shuttle.de) - - * seckey-cert.c (do_check): New; combines all the check functions - into one. - - * sign.c: removed all key management functions - * keyedit.c: New. - -Thu Apr 9 09:49:36 1998 Werner Koch (wk@isil.d.shuttle.de) - - * import.c (chk_self_sigs): Changed an error message. - -Wed Apr 8 16:19:39 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h: packet structs now uses structs from the pubkey, - removed all copy operations from packet to pubkey structs. - -Wed Apr 8 13:40:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (verify_own_certs): Fixed "public key not found". - - * getkey.c (key_byname): New, combines public and secret key search. - - * pkclist.c (build_pkc_list): Add new arg usage, changed all callers. - * skclist.c (build_skc_list): Likewise. - - * ringedit.c (find_keyblock, keyring_search2): Removed. - -Wed Apr 8 09:47:21 1998 Werner Koch (wk@isil.d.shuttle.de) - - * sig-check.c (do_check): Applied small fix from Ulf Möller. - -Tue Apr 7 19:28:07 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.c, encr-data.c, seckey-cert.c: Now uses cipher_xxxx - functions instead of blowfish_xxx or cast_xxx - -Tue Apr 7 11:04:02 1998 Werner Koch (wk@isil.d.shuttle.de) - - * Makefile.am (g10maint.o): Changed the way it is created. - -Mon Apr 6 11:17:08 1998 Werner Koch (wk@isil.d.shuttle.de) - - * misc.c: New. - * keygen.c (checksum,checksum_u16,checksum_mpi): Moved to misc.c - * seckey-cert.c: Kludge for wrong ELG checksum implementation. - -Sat Apr 4 20:07:01 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.c (cipher_filter): Support for CAST5 - * encr-data.c (decode_filter): Ditto. - (decrypt_data): Ditto. - * seskey.c (make_session_key): Ditto. - * seckey-cert.c (check_elg, check_dsa): Ditto, - (protect_secret_key): Ditto. - * pubkey-enc.c (get_session_key): Ditto. - * passphrase.c (hash_passphrase): Ditto. - -Thu Apr 2 20:22:35 1998 Werner Koch (wk@isil.d.shuttle.de) - - * gpgd.c: New - -Thu Apr 2 10:38:16 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (generate_keypair): Add valid_days stuff. - * trustdb.c (check_trust): Add check for valid_days. - -Wed Apr 1 16:15:58 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (generate_keypair): Addional question whether the - selected large keysize is really needed. - -Wed Apr 1 15:56:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * seckey-cert.c (protect_secret_key): merged protect_xxx to here. - -Wed Apr 1 10:34:46 1998 Werner Koch (wk@isil.d.shuttle.de) - - * Makefile.am (g10maint.c): Changed creation rule, so that it works - on FreeBSD (missing CFLAGS). - - * parse-packet.c (parse_subkey): Removed. - -Thu Mar 19 15:22:36 1998 Werner Koch (wk@isil.d.shuttle.de) - - * ringedit.c (keyring_enum): Fixed problem with reading too - many packets. Add support to read secret keyrings. - - * getkey.c (scan_keyring): Removed - (lookup): New to replace scan_keyring. - (scan_secret_keyring): Removed. - (lookup_skc): New. - -Wed Mar 18 11:47:34 1998 Werner Koch (wk@isil.d.shuttle.de) - - * ringedit.c (enum_keyblocks): New read mode 11. - - * keyid.c (elg_fingerprint_md): New and changed all other functions - to call this if the packet version is 4 or above. - -Tue Mar 17 20:46:16 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c (parse_certificate): Add listing support for subkeys. - -Tue Mar 17 20:32:22 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (is_armored): Allow marker packet. - -Thu Mar 12 13:36:49 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (check_trust): Checks timestamp of pubkey. - * sig-check. (do_check): Compares timestamps. - -Tue Mar 10 17:01:56 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Add call to init_signals. - * signal.c: New. - -Mon Mar 9 12:43:42 1998 Werner Koch (wk@isil.d.shuttle.de) - - * dsa.c: New - * packet.h, free-packet.c, parse-packet.c : Add support for DSA - * sig-check.c, getkey.c, keyid.c, ringedit.c: Ditto. - * seckey-cert.c: Ditto. - - * packet.h : Moved .digest_algo of signature packets to outer - structure. Changed all references - -Sun Mar 8 13:06:42 1998 Werner Koch (wk@isil.d.shuttle.de) - - * openfile.c : Support for stdout filename "-". - - * mainproc.c (check_sig_and_print): Enhanced status output: - * status.c (write_status_text): New. - -Fri Mar 6 16:10:54 1998 Werner Koch (wk@isil.d.shuttle.de) - - * kbnode.c (clone_kbnode): Fixed private_flag. - - * mainproc.c (list_node): Output of string "Revoked" as user-id. - -Fri Mar 6 14:26:39 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Add userids to "-kv" and cleaned up this stuff. - -Fri Mar 6 12:45:58 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Changed semantics of the list-... commands - and added a new one. Removed option "-d" - - * decrypt.c: New. - - * trustdb.c (init_trustdb): Autocreate directory only if it ends - in "/.gnupg". - -Thu Mar 5 12:12:11 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mainproc.c (do_proc_packets): New. Common part of proc_packet. - (proc_signature_packets): special version to handle signature data. - * verify.c: New. - * g10.c (aVerify): New. - * plaintext.c (hash_datafiles): New. - * compress.c (handle_compressed): Add callback arg, changed caller. - -Thu Mar 5 10:20:06 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c: Is nom the common source for gpg and gpgm - * g10maint.c: Removed - * Makefile.am: Add rule to build g10maint.c - -Thu Mar 5 08:43:59 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Changed the way clear text sigs are faked. - -Wed Mar 4 19:47:37 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10maint.c (aMuttKeyList): New - * keylist.c: New. - -Wed Mar 4 17:20:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * getkey.c (get_pubkey_byname): Kludge to allow 0x prefix. - -Tue Mar 3 13:46:55 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10maint.c (main): New option --gen-random. - -Tue Mar 3 09:50:08 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (aDeleteSecretKey): New. - (aEditSig): Add option "--edit-key" as synonym for "--edit-sig". - (aDeleteSecretKey): New. - * getkey.c (seckey_available): New. - * sign.c (delete_key): Enhanced to delete secret keys, changed all - callers. - -Mon Mar 2 21:23:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * pkc_list.c (build_pkc_list): Add interactive input of user ID. - -Mon Mar 2 20:54:05 1998 Werner Koch (wk@isil.d.shuttle.de) - - * pkclist.c (do_we_trust_pre): New. - (add_ownertrust): Add message. - * trustdb.c (enum_trust_web): Quick fix. - -Mon Mar 2 13:50:53 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): New action aDeleteKey - * sign.c (delete_key): New. - -Sun Mar 1 16:38:58 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (do_check): No returns TRUST_UNDEFINED instead of - eof error. - -Fri Feb 27 18:14:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (find_header): Removed trailing CR on headers. - -Fri Feb 27 18:02:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * ringedit.c (keyring_search) [MINGW32]: Open and close file here - because rename does not work on open files. Chnaged callers. - -Fri Feb 27 16:43:11 1998 Werner Koch (wk@isil.d.shuttle.de) - - * sig-check.c (do_check): Add an md_enable. - * mainproc.c (do_check_sig): Use md_open in case of detached sig - (proc_tree): Take detached sigs into account. - -Fri Feb 27 15:22:46 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Make use of GNUPGHOME envvar. - * g10main.c (main): Ditto. - -Wed Feb 25 11:40:04 1998 Werner Koch (wk@isil.d.shuttle.de) - - * plaintext.c (ask_for_detached_datafile): add opt.verbose to - info output. - - * openfile.c (open_sigfile): Try also name ending in ".asc" - -Wed Feb 25 08:41:00 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (generate_keypair): Fixed memory overflow. - -Tue Feb 24 15:51:55 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c (parse_certificate): Support for S2K. - * build-packet.c (do_secret_cert): Ditto. - * keygen.c (gen_elg): Ditto. - * seckey-cert.c (check_elg): Ditto - (protect_elg): Ditto. - * sign.c (chnage_passphrase): Ditto. - * passphrase.c (get_passphrase_hash): Support for a salt and - changed all callers. - (make_dek_from_passphrase): Ditto. - -Tue Feb 24 12:30:56 1998 Werner Koch (wk@isil.d.shuttle.de) - - * build-packet.c (hash_public_cert): Disabled debug output. - -Fri Feb 20 17:22:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (init_trustdb) [MINGW32]: Removed 2nd mkdir arg. - (keyring_copy) [MINGW32]: Add a remove prior to the renames. - -Wed Feb 18 18:39:02 1998 Werner Koch (wk@isil.d.shuttle.de) - - * Makefile.am (OMIT_DEPENDENCIES): New. - - * rsa.c: Replaced log_bug by BUG. - -Wed Feb 18 13:35:58 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mainproc.c (do_check_sig): Now uses hash_public_cert. - * parse-packet.c (parse_certificate): Removed hashing. - * packet.h (public_cert): Removed hash variable. - * free-packet.c (copy_public_cert, free_public_cert): Likewise. - - * sig-check.c (check_key_signatures): Changed semantics. - -Wed Feb 18 12:11:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (do_check): Add handling for revocation certificates. - (build_sigrecs): Ditto. - (check_sigs): Ditto. - -Wed Feb 18 09:31:04 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (armor_filter): Add afx->hdrlines. - * revoke.c (gen_revoke): Add comment line. - * dearmor.c (enarmor_file): Ditto. - - * sig-check.c (check_key_signature): Add handling for class 0x20. - * mainproc.c : Ditto. - -Tue Feb 17 21:24:17 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c : Add header lines "...ARMORED FILE .." - * dearmor.c (enarmor_file): New. - * g10maint.c (main): New option "--enarmor" - -Tue Feb 17 19:03:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mainproc.c : Changed a lot, because the packets are now stored - a simple linlked list and not anymore in a complicatd tree structure. - -Tue Feb 17 10:14:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * free_packet.c (cmp_public_certs): New. - (cmp_user_ids): New. - - * kbnode.c (clone_kbnode): New. - (release_kbnode): Add clone support. - - * ringedit.c (find_keyblock_bypkc): New. - - * sign.c (remove_keysigs): Self signatures are now skipped, - changed arguments and all callers. - - * import.c : Add functionality. - -Tue Feb 17 09:31:40 1998 Werner Koch (wk@isil.d.shuttle.de) - - * options.h (homedir): New option. - * g10.c, g10maint.c, getkey.c, keygen.c, trustdb.c (opt.homedir): New. - - * trustdb.c (init_trustdb): mkdir for hoem directory - (sign_private_data): Renamed "sig" to "g10.sig" - -Mon Feb 16 20:02:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * kbnode.c (commit_kbnode): New. - (delete_kbnode): removed unused first arg. Changed all Callers. - - * ringedit.c (keyblock_resource_name): New. - (get_keyblock_handle): NULL for filename returns default resource. - -Mon Feb 16 19:38:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * sig-check.s (check_key_signature): Now uses the supplied - public key to check the signature and not any more the one - from the getkey.c - (do_check): New. - (check_signature): Most work moved to do_check. - -Mon Feb 16 14:48:57 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (find_header): Fixed another bug. - -Mon Feb 16 12:18:34 1998 Werner Koch (wk@isil.d.shuttle.de) - - * getkey.c (scan_keyring): Add handling of compressed keyrings. - -Mon Feb 16 10:44:51 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c, g10maint.c (strusage): Rewrote. - (build_list): New - -Mon Feb 16 08:58:41 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (use_armor): New. - -Sat Feb 14 14:30:57 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mainproc.c (proc_tree): Sigclass fix. - -Sat Feb 14 14:16:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (armor_filter): Changed version and comment string. - * encode.c, sign.c, keygen.c: Changed all comment packet strings. - -Sat Feb 14 12:39:24 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (aGenRevoke): New command. - * revoke.c: New. - * sign.c (make_keysig_packet): Add support for sigclass 0x20. - -Fri Feb 13 20:18:14 1998 Werner Koch (wk@isil.d.shuttle.de) - - * ringedit.c (enum_keyblocks, keyring_enum): New. - -Fri Feb 13 19:33:40 1998 Werner Koch (wk@isil.d.shuttle.de) - - * export.c: Add functionality. - - * keygen.c (generate_keypair): Moved the leading comment behind the - key packet. - * kbnode.c (walk_kbnode): Fixed. - - * g10.c (main): listing armored keys now work. - -Fri Feb 13 16:17:43 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c (parse_publickey, parse_signature): Fixed calls - to mpi_read used for ELG b. - -Fri Feb 13 15:13:23 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): changed formatting of help output. - -Thu Feb 12 22:24:42 1998 Werner Koch (wk@frodo) - - * pubkey-enc.c (get_session_key): rewritten - - - Copyright 1998,1999,2000,2001,2002,2003 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. diff --git a/g10/Makefile.am b/g10/Makefile.am deleted file mode 100644 index fc33acf73..000000000 --- a/g10/Makefile.am +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright (C) 1998, 1999, 2000, 2001, 2002, -# 2003 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -EXTRA_DIST = options.skel - -AM_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/include \ - -I$(top_srcdir)/intl - -include $(top_srcdir)/am/cmacros.am - -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) - -needed_libs = ../common/libcommon.a ../jnlib/libjnlib.a - -bin_PROGRAMS = gpg2 gpgv2 - -common_source = \ - global.h gpg.h \ - build-packet.c \ - compress.c \ - filter.h \ - free-packet.c \ - getkey.c \ - keydb.c keydb.h \ - keyring.c keyring.h \ - seskey.c \ - kbnode.c \ - main.h \ - mainproc.c \ - armor.c \ - mdfilter.c \ - textfilter.c \ - progress.c \ - misc.c \ - options.h \ - openfile.c \ - keyid.c \ - packet.h \ - parse-packet.c \ - comment.c \ - status.c \ - status.h \ - plaintext.c \ - sig-check.c \ - keylist.c \ - pkglue.c pkglue.h - -gpg2_SOURCES = g10.c \ - $(common_source) \ - pkclist.c \ - skclist.c \ - pubkey-enc.c \ - passphrase.c \ - seckey-cert.c \ - encr-data.c \ - cipher.c \ - encode.c \ - sign.c \ - verify.c \ - revoke.c \ - decrypt.c \ - keyedit.c \ - dearmor.c \ - import.c \ - export.c \ - trustdb.c \ - trustdb.h \ - tdbdump.c \ - tdbio.c \ - tdbio.h \ - delkey.c \ - keygen.c \ - pipemode.c \ - helptext.c \ - keyserver.c \ - keyserver-internal.h \ - photoid.c photoid.h \ - call-agent.c call-agent.h \ - card-util.c \ - exec.c exec.h - -gpgv2_SOURCES = gpgv.c \ - $(common_source) \ - verify.c - -#gpgd_SOURCES = gpgd.c \ -# ks-proto.h \ -# ks-proto.c \ -# ks-db.c \ -# ks-db.h \ -# $(common_source) - -LDADD = $(needed_libs) @INTLLIBS@ @CAPLIBS@ @ZLIBS@ @W32LIBS@ -gpg2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error -gpgv2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error - -$(PROGRAMS): $(needed_libs) - -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) - $(INSTALL_DATA) $(srcdir)/options.skel \ - $(DESTDIR)$(pkgdatadir)/options.skel - diff --git a/g10/OPTIONS b/g10/OPTIONS deleted file mode 100644 index b1a49e254..000000000 --- a/g10/OPTIONS +++ /dev/null @@ -1,24 +0,0 @@ -# Some notes used by the maintainers - - -store -# simply packs the input data into a rfc1991 packet format - -check-trustdb - - -compress-keys -# compress exported key, compress level is still set with "-z" and -# algorithm with --compress-algo" - Default is to not compress keys, as -# this is better for interoperability. - -compress-sigs -# Normally, compressing of signatures does not make sense; so this -# is disabled for detached signatures unless this option is used. - -run-as-shm-coprocess [request-locked-shm-size] -# very special :-) -# You will have to use "--status-fd" too -# Note: This option does only work if given on the command line. - - diff --git a/g10/armor.c b/g10/armor.c deleted file mode 100644 index 121ec3a09..000000000 --- a/g10/armor.c +++ /dev/null @@ -1,1334 +0,0 @@ -/* armor.c - Armor flter - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 - * Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <ctype.h> - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "filter.h" -#include "packet.h" -#include "options.h" -#include "main.h" -#include "status.h" -#include "i18n.h" - -#ifdef HAVE_DOSISH_SYSTEM -#define LF "\r\n" -#else -#define LF "\n" -#endif - -#define MAX_LINELEN 20000 - -#define CRCINIT 0xB704CE -#define CRCPOLY 0X864CFB -#define CRCUPDATE(a,c) do { \ - a = ((a) << 8) ^ crc_table[((a)&0xff >> 16) ^ (c)]; \ - a &= 0x00ffffff; \ - } while(0) -static u32 crc_table[256]; -static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; -static byte asctobin[256]; /* runtime initialized */ -static int is_initialized; - - -typedef enum { - fhdrHASArmor = 0, - fhdrNOArmor, - fhdrINIT, - fhdrINITCont, - fhdrINITSkip, - fhdrCHECKBegin, - fhdrWAITHeader, - fhdrWAITClearsig, - fhdrSKIPHeader, - fhdrCLEARSIG, - fhdrREADClearsig, - fhdrNullClearsig, - fhdrEMPTYClearsig, - fhdrCHECKClearsig, - fhdrCHECKClearsig2, - fhdrCHECKDashEscaped, - fhdrCHECKDashEscaped2, - fhdrCHECKDashEscaped3, - fhdrREADClearsigNext, - fhdrENDClearsig, - fhdrENDClearsigHelp, - fhdrTESTSpaces, - fhdrCLEARSIGSimple, - fhdrCLEARSIGSimpleNext, - fhdrTEXT, - fhdrTEXTSimple, - fhdrERROR, - fhdrERRORShow, - fhdrEOF -} fhdr_state_t; - - -/* if we encounter this armor string with this index, go - * into a mode which fakes packets and wait for the next armor */ -#define BEGIN_SIGNATURE 2 -#define BEGIN_SIGNED_MSG_IDX 3 -static char *head_strings[] = { - "BEGIN PGP MESSAGE", - "BEGIN PGP PUBLIC KEY BLOCK", - "BEGIN PGP SIGNATURE", - "BEGIN PGP SIGNED MESSAGE", - "BEGIN PGP ARMORED FILE", /* gnupg extension */ - "BEGIN PGP PRIVATE KEY BLOCK", - "BEGIN PGP SECRET KEY BLOCK", /* only used by pgp2 */ - NULL -}; -static char *tail_strings[] = { - "END PGP MESSAGE", - "END PGP PUBLIC KEY BLOCK", - "END PGP SIGNATURE", - "END dummy", - "END PGP ARMORED FILE", - "END PGP PRIVATE KEY BLOCK", - "END PGP SECRET KEY BLOCK", - NULL -}; - - - -static void -initialize(void) -{ - int i, j; - u32 t; - byte *s; - - /* init the crc lookup table */ - crc_table[0] = 0; - for(i=j=0; j < 128; j++ ) { - t = crc_table[j]; - if( t & 0x00800000 ) { - t <<= 1; - crc_table[i++] = t ^ CRCPOLY; - crc_table[i++] = t; - } - else { - t <<= 1; - crc_table[i++] = t; - crc_table[i++] = t ^ CRCPOLY; - } - } - /* build the helptable for radix64 to bin conversion */ - for(i=0; i < 256; i++ ) - asctobin[i] = 255; /* used to detect invalid characters */ - for(s=bintoasc,i=0; *s; s++,i++ ) - asctobin[*s] = i; - - is_initialized=1; -} - -/**************** - * Check whether this is an armored file or not See also - * parse-packet.c for details on this code For unknown historic - * reasons we use a string here but only the first byte will be used. - * Returns: True if it seems to be armored - */ -static int -is_armored( const byte *buf ) -{ - int ctb, pkttype; - - ctb = *buf; - if( !(ctb & 0x80) ) - return 1; /* invalid packet: assume it is armored */ - pkttype = ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf); - switch( pkttype ) { - case PKT_MARKER: - case PKT_SYMKEY_ENC: - case PKT_ONEPASS_SIG: - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - case PKT_PUBKEY_ENC: - case PKT_SIGNATURE: - case PKT_COMMENT: - case PKT_OLD_COMMENT: - case PKT_PLAINTEXT: - case PKT_COMPRESSED: - case PKT_ENCRYPTED: - return 0; /* seems to be a regular packet: not armored */ - } - - return 1; -} - - -/**************** - * Try to check whether the iobuf is armored - * Returns true if this may be the case; the caller should use the - * filter to do further processing. - */ -int -use_armor_filter( iobuf_t a ) -{ - byte buf[1]; - int n; - - /* fixme: there might be a problem with iobuf_peek */ - n = iobuf_peek(a, buf, 1 ); - if( n == -1 ) - return 0; /* EOF, doesn't matter whether armored or not */ - if( !n ) - return 1; /* can't check it: try armored */ - return is_armored(buf); -} - - - - -static void -invalid_armor(void) -{ - write_status(STATUS_BADARMOR); - g10_exit(1); /* stop here */ -} - - -/**************** - * check whether the armor header is valid on a signed message. - * this is for security reasons: the header lines are not included in the - * hash and by using some creative formatting rules, Mallory could fake - * any text at the beginning of a document; assuming it is read with - * a simple viewer. We only allow the Hash Header. - */ -static int -parse_hash_header( const char *line ) -{ - const char *s, *s2; - unsigned found = 0; - - if( strlen(line) < 6 || strlen(line) > 60 ) - return 0; /* too short or too long */ - if( memcmp( line, "Hash:", 5 ) ) - return 0; /* invalid header */ - s = line+5; - for(s=line+5;;s=s2) { - for(; *s && (*s==' ' || *s == '\t'); s++ ) - ; - if( !*s ) - break; - for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ ) - ; - if( !strncmp( s, "RIPEMD160", s2-s ) ) - found |= 1; - else if( !strncmp( s, "SHA1", s2-s ) ) - found |= 2; - else if( !strncmp( s, "MD5", s2-s ) ) - found |= 4; - else if( !strncmp( s, "SHA256", s2-s ) ) - found |= 8; - else if( !strncmp( s, "SHA384", s2-s ) ) - found |= 16; - else if( !strncmp( s, "SHA512", s2-s ) ) - found |= 32; - else - return 0; - for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ ) - ; - if( *s2 && *s2 != ',' ) - return 0; - if( *s2 ) - s2++; - } - return found; -} - - - -/**************** - * Check whether this is a armor line. - * returns: -1 if it is not a armor header or the index number of the - * armor header. - */ -static int -is_armor_header( byte *line, unsigned len ) -{ - const char *s; - byte *save_p, *p; - int save_c; - int i; - - if( len < 15 ) - return -1; /* too short */ - if( memcmp( line, "-----", 5 ) ) - return -1; /* no */ - p = strstr( line+5, "-----"); - if( !p ) - return -1; - save_p = p; - p += 5; - - /* Some mail programs on Windows seem to add spaces to the end of - the line. This becomes strict if --openpgp is set. */ - - if(!RFC2440) - while(*p==' ') - p++; - - if( *p == '\r' ) - p++; - if( *p == '\n' ) - p++; - if( *p ) - return -1; /* garbage after dashes */ - save_c = *save_p; *save_p = 0; - p = line+5; - for(i=0; (s=head_strings[i]); i++ ) - if( !strcmp(s, p) ) - break; - *save_p = save_c; - if( !s ) - return -1; /* unknown armor line */ - - if( opt.verbose > 1 ) - log_info(_("armor: %s\n"), head_strings[i]); - return i; -} - - - -/**************** - * Parse a header lines - * Return 0: Empty line (end of header lines) - * -1: invalid header line - * >0: Good header line - */ -static int -parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len ) -{ - byte *p; - int hashes=0; - unsigned int len2; - - len2 = length_sans_trailing_ws( line, len ); - if( !len2 ) { - afx->buffer_pos = len2; /* (it is not the fine way to do it here) */ - return 0; /* WS only: same as empty line */ - } - len = len2; - line[len2] = 0; - - p = strchr( line, ':'); - if( !p || !p[1] ) { - log_error(_("invalid armor header: ")); - print_string( stderr, line, len, 0 ); - putc('\n', stderr); - return -1; - } - - if( opt.verbose ) { - log_info(_("armor header: ")); - print_string( stderr, line, len, 0 ); - putc('\n', stderr); - } - - if( afx->in_cleartext ) { - if( (hashes=parse_hash_header( line )) ) - afx->hashes |= hashes; - else if( strlen(line) > 15 && !memcmp( line, "NotDashEscaped:", 15 ) ) - afx->not_dash_escaped = 1; - else { - log_error(_("invalid clearsig header\n")); - return -1; - } - } - return 1; -} - - - -/* figure out whether the data is armored or not */ -static int -check_input( armor_filter_context_t *afx, iobuf_t a ) -{ - int rc = 0; - int i; - byte *line; - unsigned len; - unsigned maxlen; - int hdr_line = -1; - - /* read the first line to see whether this is armored data */ - maxlen = MAX_LINELEN; - len = afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - line = afx->buffer; - if( !maxlen ) { - /* line has been truncated: assume not armored */ - afx->inp_checked = 1; - afx->inp_bypass = 1; - return 0; - } - - if( !len ) { - return -1; /* eof */ - } - - /* (the line is always a C string but maybe longer) */ - if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) ) - ; - else if( !is_armored( line ) ) { - afx->inp_checked = 1; - afx->inp_bypass = 1; - return 0; - } - - /* find the armor header */ - while(len) { - i = is_armor_header( line, len ); - if( i >= 0 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) { - hdr_line = i; - if( hdr_line == BEGIN_SIGNED_MSG_IDX ) { - if( afx->in_cleartext ) { - log_error(_("nested clear text signatures\n")); - rc = GPG_ERR_INV_ARMOR; - } - afx->in_cleartext = 1; - } - break; - } - /* read the next line (skip all truncated lines) */ - do { - maxlen = MAX_LINELEN; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - line = afx->buffer; - len = afx->buffer_len; - } while( !maxlen ); - } - - /* parse the header lines */ - while(len) { - /* read the next line (skip all truncated lines) */ - do { - maxlen = MAX_LINELEN; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - line = afx->buffer; - len = afx->buffer_len; - } while( !maxlen ); - - i = parse_header_line( afx, line, len ); - if( i <= 0 ) { - if( i ) - rc = GPG_ERR_INV_ARMOR; - break; - } - } - - - if( rc ) - invalid_armor(); - else if( afx->in_cleartext ) - afx->faked = 1; - else { - afx->inp_checked = 1; - afx->crc = CRCINIT; - afx->idx = 0; - afx->radbuf[0] = 0; - } - - return rc; -} - - - -/**************** - * Fake a literal data packet and wait for the next armor line - * fixme: empty line handling and null length clear text signature are - * not implemented/checked. - */ -static int -fake_packet( armor_filter_context_t *afx, iobuf_t a, - size_t *retn, byte *buf, size_t size ) -{ - int rc = 0; - size_t len = 0; - int lastline = 0; - unsigned maxlen, n; - byte *p; - - len = 2; /* reserve 2 bytes for the length header */ - size -= 2; /* and 2 for the terminating header */ - while( !rc && len < size ) { - /* copy what we have in the line buffer */ - if( afx->faked == 1 ) - afx->faked++; /* skip the first (empty) line */ - else { - while( len < size && afx->buffer_pos < afx->buffer_len ) - buf[len++] = afx->buffer[afx->buffer_pos++]; - if( len >= size ) - continue; - } - - /* read the next line */ - maxlen = MAX_LINELEN; - afx->buffer_pos = 0; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - if( !afx->buffer_len ) { - rc = -1; /* eof (should not happen) */ - continue; - } - if( !maxlen ) - afx->truncated++; - if( !afx->not_dash_escaped ) { - int crlf; - p = afx->buffer; - n = afx->buffer_len; - crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n'; - - /* PGP2 does not treat a tab as white space character */ - afx->buffer_len = trim_trailing_chars( p, n, - afx->pgp2mode ? " \r\n" : " \t\r\n"); - /* the buffer is always allocated with enough space to append - * the removed [CR], LF and a Nul - * The reason for this complicated procedure is to keep at least - * the original type of lineending - handling of the removed - * trailing spaces seems to be impossible in our method - * of faking a packet; either we have to use a temporary file - * or calculate the hash here in this module and somehow find - * a way to send the hash down the processing line (well, a special - * faked packet could do the job). - */ - if( crlf ) - afx->buffer[afx->buffer_len++] = '\r'; - afx->buffer[afx->buffer_len++] = '\n'; - afx->buffer[afx->buffer_len] = 0; - } - p = afx->buffer; - n = afx->buffer_len; - - if( n > 2 && *p == '-' ) { - /* check for dash escaped or armor header */ - if( p[1] == ' ' && !afx->not_dash_escaped ) { - /* issue a warning if it is not regular encoded */ - if( p[2] != '-' && !( n > 6 && !memcmp(p+2, "From ", 5))) { - log_info(_("invalid dash escaped line: ")); - print_string( stderr, p, n, 0 ); - putc('\n', stderr); - } - afx->buffer_pos = 2; /* skip */ - } - else if( n >= 15 && p[1] == '-' && p[2] == '-' && p[3] == '-' ) { - int type = is_armor_header( p, n ); - if( afx->not_dash_escaped && type != BEGIN_SIGNATURE ) - ; /* this is okay */ - else { - if( type != BEGIN_SIGNATURE ) { - log_info(_("unexpected armor:")); - print_string( stderr, p, n, 0 ); - putc('\n', stderr); - } - lastline = 1; - rc = -1; - } - } - } - } - - buf[0] = (len-2) >> 8; - buf[1] = (len-2); - if( lastline ) { /* write last (ending) length header */ - if( buf[0] || buf[1] ) { /* only if we have some text */ - buf[len++] = 0; - buf[len++] = 0; - } - rc = 0; - afx->faked = 0; - afx->in_cleartext = 0; - /* and now read the header lines */ - afx->buffer_pos = 0; - for(;;) { - int i; - - /* read the next line (skip all truncated lines) */ - do { - maxlen = MAX_LINELEN; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - } while( !maxlen ); - p = afx->buffer; - n = afx->buffer_len; - if( !n ) { - rc = -1; - break; /* eof */ - } - i = parse_header_line( afx, p , n ); - if( i <= 0 ) { - if( i ) - invalid_armor(); - break; - } - } - afx->inp_checked = 1; - afx->crc = CRCINIT; - afx->idx = 0; - afx->radbuf[0] = 0; - } - - *retn = len; - return rc; -} - - -static int -invalid_crc(void) -{ - if ( opt.ignore_crc_error ) - return 0; - log_inc_errorcount(); - return GPG_ERR_INV_ARMOR; -} - - -static int -radix64_read( armor_filter_context_t *afx, iobuf_t a, size_t *retn, - byte *buf, size_t size ) -{ - byte val; - int c=0, c2; /*init c because gcc is not clever enough for the continue*/ - int checkcrc=0; - int rc = 0; - size_t n = 0; - int idx, i; - u32 crc; - - crc = afx->crc; - idx = afx->idx; - val = afx->radbuf[0]; - for( n=0; n < size; ) { - - if( afx->buffer_pos < afx->buffer_len ) - c = afx->buffer[afx->buffer_pos++]; - else { /* read the next line */ - unsigned maxlen = MAX_LINELEN; - afx->buffer_pos = 0; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - if( !maxlen ) - afx->truncated++; - if( !afx->buffer_len ) - break; /* eof */ - continue; - } - - again: - if( c == '\n' || c == ' ' || c == '\r' || c == '\t' ) - continue; - else if( c == '=' ) { /* pad character: stop */ - /* some mailers leave quoted-printable encoded characters - * so we try to workaround this */ - if( afx->buffer_pos+2 < afx->buffer_len ) { - int cc1, cc2, cc3; - cc1 = afx->buffer[afx->buffer_pos]; - cc2 = afx->buffer[afx->buffer_pos+1]; - cc3 = afx->buffer[afx->buffer_pos+2]; - if( isxdigit(cc1) && isxdigit(cc2) - && strchr( "=\n\r\t ", cc3 )) { - /* well it seems to be the case - adjust */ - c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10); - c <<= 4; - c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10); - afx->buffer_pos += 2; - afx->qp_detected = 1; - goto again; - } - } - - if( idx == 1 ) - buf[n++] = val; - checkcrc++; - break; - } - else if( (c = asctobin[(c2=c)]) == 255 ) { - log_error(_("invalid radix64 character %02x skipped\n"), c2); - continue; - } - switch(idx) { - case 0: val = c << 2; break; - case 1: val |= (c>>4)&3; buf[n++]=val;val=(c<<4)&0xf0;break; - case 2: val |= (c>>2)&15; buf[n++]=val;val=(c<<6)&0xc0;break; - case 3: val |= c&0x3f; buf[n++] = val; break; - } - idx = (idx+1) % 4; - } - - for(i=0; i < n; i++ ) - crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]]; - crc &= 0x00ffffff; - afx->crc = crc; - afx->idx = idx; - afx->radbuf[0] = val; - - if( checkcrc ) { - afx->any_data = 1; - afx->inp_checked=0; - afx->faked = 0; - for(;;) { /* skip lf and pad characters */ - if( afx->buffer_pos < afx->buffer_len ) - c = afx->buffer[afx->buffer_pos++]; - else { /* read the next line */ - unsigned maxlen = MAX_LINELEN; - afx->buffer_pos = 0; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - if( !maxlen ) - afx->truncated++; - if( !afx->buffer_len ) - break; /* eof */ - continue; - } - if( c == '\n' || c == ' ' || c == '\r' - || c == '\t' || c == '=' ) - continue; - break; - } - if( c == -1 ) - log_error(_("premature eof (no CRC)\n")); - else { - u32 mycrc = 0; - idx = 0; - do { - if( (c = asctobin[c]) == 255 ) - break; - switch(idx) { - case 0: val = c << 2; break; - case 1: val |= (c>>4)&3; mycrc |= val << 16;val=(c<<4)&0xf0;break; - case 2: val |= (c>>2)&15; mycrc |= val << 8;val=(c<<6)&0xc0;break; - case 3: val |= c&0x3f; mycrc |= val; break; - } - for(;;) { - if( afx->buffer_pos < afx->buffer_len ) - c = afx->buffer[afx->buffer_pos++]; - else { /* read the next line */ - unsigned maxlen = MAX_LINELEN; - afx->buffer_pos = 0; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, - &maxlen ); - if( !maxlen ) - afx->truncated++; - if( !afx->buffer_len ) - break; /* eof */ - continue; - } - break; - } - if( !afx->buffer_len ) - break; /* eof */ - } while( ++idx < 4 ); - if( c == -1 ) { - log_info(_("premature eof (in CRC)\n")); - rc = invalid_crc(); - } - else if( idx != 4 ) { - log_info(_("malformed CRC\n")); - rc = invalid_crc(); - } - else if( mycrc != afx->crc ) { - log_info (_("CRC error; %06lx - %06lx\n"), - (ulong)afx->crc, (ulong)mycrc); - rc = invalid_crc(); - } - else { - rc = 0; - /* FIXME: Here we should emit another control packet, - * so that we know in mainproc that we are processing - * a clearsign message */ -#if 0 - for(rc=0;!rc;) { - rc = 0 /*check_trailer( &fhdr, c )*/; - if( !rc ) { - if( (c=iobuf_get(a)) == -1 ) - rc = 2; - } - } - if( rc == -1 ) - rc = 0; - else if( rc == 2 ) { - log_error(_("premature eof (in Trailer)\n")); - rc = GPG_ERR_INV_ARMOR; - } - else { - log_error(_("error in trailer line\n")); - rc = GPG_ERR_INV_ARMOR; - } -#endif - } - } - } - - if( !n ) - rc = -1; - - *retn = n; - return rc; -} - -/**************** - * This filter is used to handle the armor stuff - */ -int -armor_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - armor_filter_context_t *afx = opaque; - int rc=0, i, c; - byte radbuf[3]; - int idx, idx2; - size_t n=0; - u32 crc; -#if 0 - static FILE *fp ; - - if( !fp ) { - fp = fopen("armor.out", "w"); - assert(fp); - } -#endif - - if( DBG_FILTER ) - log_debug("armor-filter: control: %d\n", control ); - if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) { - n = 0; - if( afx->buffer_len ) { - for(; n < size && afx->buffer_pos < afx->buffer_len; n++ ) - buf[n++] = afx->buffer[afx->buffer_pos++]; - if( afx->buffer_pos >= afx->buffer_len ) - afx->buffer_len = 0; - } - for(; n < size; n++ ) { - if( (c=iobuf_get(a)) == -1 ) - break; - buf[n] = c & 0xff; - } - if( !n ) - rc = -1; - *ret_len = n; - } - else if( control == IOBUFCTRL_UNDERFLOW ) { - /* We need some space for the faked packet. The minmum required - * size is ~18 + length of the session marker */ - if( size < 50 ) - BUG(); /* supplied buffer too short */ - - if( afx->faked ) - rc = fake_packet( afx, a, &n, buf, size ); - else if( !afx->inp_checked ) { - rc = check_input( afx, a ); - if( afx->inp_bypass ) { - for(n=0; n < size && afx->buffer_pos < afx->buffer_len; ) - buf[n++] = afx->buffer[afx->buffer_pos++]; - if( afx->buffer_pos >= afx->buffer_len ) - afx->buffer_len = 0; - if( !n ) - rc = -1; - } - else if( afx->faked ) { - unsigned int hashes = afx->hashes; - const byte *sesmark; - size_t sesmarklen; - - sesmark = get_session_marker( &sesmarklen ); - if ( sesmarklen > 20 ) - BUG(); - - /* the buffer is at least 15+n*15 bytes long, so it - * is easy to construct the packets */ - - hashes &= 1|2|4|8|16|32|64; - if( !hashes ) { - hashes |= 4; /* default to MD 5 */ - /* This is non-ideal since PGP 5-8 have the same - end-of-line bugs as PGP 2. However, we only - enable pgp2mode if there is no Hash: header. */ - if( opt.pgp2_workarounds ) - afx->pgp2mode = 1; - } - n=0; - /* first a gpg control packet */ - buf[n++] = 0xff; /* new format, type 63, 1 length byte */ - n++; /* see below */ - memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen; - buf[n++] = CTRLPKT_CLEARSIGN_START; - buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */ - if( hashes & 1 ) - buf[n++] = DIGEST_ALGO_RMD160; - if( hashes & 2 ) - buf[n++] = DIGEST_ALGO_SHA1; - if( hashes & 4 ) - buf[n++] = DIGEST_ALGO_MD5; - if( hashes & 8 ) - buf[n++] = DIGEST_ALGO_SHA256; - if( hashes & 16 ) - buf[n++] = DIGEST_ALGO_SHA384; - if( hashes & 32 ) - buf[n++] = DIGEST_ALGO_SHA512; - buf[1] = n - 2; - - /* followed by a plaintext packet */ - buf[n++] = 0xaf; /* old packet format, type 11, var length */ - buf[n++] = 0; /* set the length header */ - buf[n++] = 6; - buf[n++] = 't'; /* canonical text mode */ - buf[n++] = 0; /* namelength */ - memset(buf+n, 0, 4); /* timestamp */ - n += 4; - } - else if( !rc ) - rc = radix64_read( afx, a, &n, buf, size ); - } - else - rc = radix64_read( afx, a, &n, buf, size ); -#if 0 - if( n ) - if( fwrite(buf, n, 1, fp ) != 1 ) - BUG(); -#endif - *ret_len = n; - } - else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) { - if( !afx->status ) { /* write the header line */ - const char *s; - STRLIST comment = opt.comments; - - if( afx->what >= DIM(head_strings) ) - log_bug("afx->what=%d", afx->what); - iobuf_writestr(a, "-----"); - iobuf_writestr(a, head_strings[afx->what] ); - iobuf_writestr(a, "-----" LF ); - if( !opt.no_version ) - iobuf_writestr(a, "Version: GnuPG v" VERSION " (" - PRINTABLE_OS_NAME ")" LF ); - - /* Write the comment string. */ - for(s=comment? comment->d:NULL; comment; - comment=comment->next,s=comment->d) - { - iobuf_writestr(a, "Comment: " ); - for ( ; *s; s++ ) - { - if( *s == '\n' ) - iobuf_writestr(a, "\\n" ); - else if( *s == '\r' ) - iobuf_writestr(a, "\\r" ); - else if( *s == '\v' ) - iobuf_writestr(a, "\\v" ); - else - iobuf_put(a, *s ); - } - iobuf_writestr(a, LF ); - } - - if ( afx->hdrlines ) { - for ( s = afx->hdrlines; *s; s++ ) { -#ifdef HAVE_DOSISH_SYSTEM - if ( *s == '\n' ) - iobuf_put( a, '\r'); -#endif - iobuf_put(a, *s ); - } - } - iobuf_writestr(a, LF ); - afx->status++; - afx->idx = 0; - afx->idx2 = 0; - afx->crc = CRCINIT; - - } - crc = afx->crc; - idx = afx->idx; - idx2 = afx->idx2; - for(i=0; i < idx; i++ ) - radbuf[i] = afx->radbuf[i]; - - for(i=0; i < size; i++ ) - crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]]; - crc &= 0x00ffffff; - - for( ; size; buf++, size-- ) { - radbuf[idx++] = *buf; - if( idx > 2 ) { - idx = 0; - c = bintoasc[(*radbuf >> 2) & 077]; - iobuf_put(a, c); - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077]; - iobuf_put(a, c); - c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; - iobuf_put(a, c); - c = bintoasc[radbuf[2]&077]; - iobuf_put(a, c); - if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */ - iobuf_writestr(a, LF ); - idx2=0; - } - } - } - for(i=0; i < idx; i++ ) - afx->radbuf[i] = radbuf[i]; - afx->idx = idx; - afx->idx2 = idx2; - afx->crc = crc; - } - else if( control == IOBUFCTRL_INIT ) { - if( !is_initialized ) - initialize(); - } - else if( control == IOBUFCTRL_CANCEL ) { - afx->cancel = 1; - } - else if( control == IOBUFCTRL_FREE ) { - if( afx->cancel ) - ; - else if( afx->status ) { /* pad, write cecksum, and bottom line */ - crc = afx->crc; - idx = afx->idx; - idx2 = afx->idx2; - for(i=0; i < idx; i++ ) - radbuf[i] = afx->radbuf[i]; - if( idx ) { - c = bintoasc[(*radbuf>>2)&077]; - iobuf_put(a, c); - if( idx == 1 ) { - c = bintoasc[((*radbuf << 4) & 060) & 077]; - iobuf_put(a, c); - iobuf_put(a, '='); - iobuf_put(a, '='); - } - else { /* 2 */ - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077]; - iobuf_put(a, c); - c = bintoasc[((radbuf[1] << 2) & 074) & 077]; - iobuf_put(a, c); - iobuf_put(a, '='); - } - if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */ - iobuf_writestr(a, LF ); - idx2=0; - } - } - /* may need a linefeed */ - if( idx2 ) - iobuf_writestr(a, LF ); - /* write the CRC */ - iobuf_put(a, '='); - radbuf[0] = crc >>16; - radbuf[1] = crc >> 8; - radbuf[2] = crc; - c = bintoasc[(*radbuf >> 2) & 077]; - iobuf_put(a, c); - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077]; - iobuf_put(a, c); - c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; - iobuf_put(a, c); - c = bintoasc[radbuf[2]&077]; - iobuf_put(a, c); - iobuf_writestr(a, LF ); - /* and the the trailer */ - if( afx->what >= DIM(tail_strings) ) - log_bug("afx->what=%d", afx->what); - iobuf_writestr(a, "-----"); - iobuf_writestr(a, tail_strings[afx->what] ); - iobuf_writestr(a, "-----" LF ); - } - else if( !afx->any_data && !afx->inp_bypass ) { - log_error(_("no valid OpenPGP data found.\n")); - afx->no_openpgp_data = 1; - write_status_text( STATUS_NODATA, "1" ); - } - if( afx->truncated ) - log_info(_("invalid armor: line longer than %d characters\n"), - MAX_LINELEN ); - /* issue an error to enforce dissemination of correct software */ - if( afx->qp_detected ) - log_error(_("quoted printable character in armor - " - "probably a buggy MTA has been used\n") ); - xfree ( afx->buffer ); - afx->buffer = NULL; - } - else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "armor_filter"; - return rc; -} - - -/**************** - * create a radix64 encoded string. - */ -char * -make_radix64_string( const byte *data, size_t len ) -{ - char *buffer, *p; - - buffer = p = xmalloc ( (len+2)/3*4 + 1 ); - for( ; len >= 3 ; len -= 3, data += 3 ) { - *p++ = bintoasc[(data[0] >> 2) & 077]; - *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077]; - *p++ = bintoasc[(((data[1]<<2)&074)|((data[2]>>6)&03))&077]; - *p++ = bintoasc[data[2]&077]; - } - if( len == 2 ) { - *p++ = bintoasc[(data[0] >> 2) & 077]; - *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077]; - *p++ = bintoasc[((data[1]<<2)&074)]; - } - else if( len == 1 ) { - *p++ = bintoasc[(data[0] >> 2) & 077]; - *p++ = bintoasc[(data[0] <<4)&060]; - } - *p = 0; - return buffer; -} - - -/*********************************************** - * For the pipemode command we can't use the armor filter for various - * reasons, so we use this new unarmor_pump stuff to remove the armor - */ - -enum unarmor_state_e { - STA_init = 0, - STA_bypass, - STA_wait_newline, - STA_wait_dash, - STA_first_dash, - STA_compare_header, - STA_found_header_wait_newline, - STA_skip_header_lines, - STA_skip_header_lines_non_ws, - STA_read_data, - STA_wait_crc, - STA_read_crc, - STA_ready -}; - -struct unarmor_pump_s { - enum unarmor_state_e state; - byte val; - int checkcrc; - int pos; /* counts from 0..3 */ - u32 crc; - u32 mycrc; /* the one store in the data */ -}; - - - -UnarmorPump -unarmor_pump_new (void) -{ - UnarmorPump x; - - if( !is_initialized ) - initialize(); - x = xcalloc (1,sizeof *x); - return x; -} - -void -unarmor_pump_release (UnarmorPump x) -{ - xfree (x); -} - -/* - * Get the next character from the ascii armor taken from the IOBUF - * created earlier by unarmor_pump_new(). - * Return: c = Character - * 256 = ignore this value - * -1 = End of current armor - * -2 = Premature EOF (not used) - * -3 = Invalid armor - */ -int -unarmor_pump (UnarmorPump x, int c) -{ - int rval = 256; /* default is to ignore the return value */ - - switch (x->state) { - case STA_init: - { - byte tmp[1]; - tmp[0] = c; - if ( is_armored (tmp) ) - x->state = c == '-'? STA_first_dash : STA_wait_newline; - else { - x->state = STA_bypass; - return c; - } - } - break; - case STA_bypass: - return c; /* return here to avoid crc calculation */ - case STA_wait_newline: - if (c == '\n') - x->state = STA_wait_dash; - break; - case STA_wait_dash: - x->state = c == '-'? STA_first_dash : STA_wait_newline; - break; - case STA_first_dash: /* just need for initalization */ - x->pos = 0; - x->state = STA_compare_header; - case STA_compare_header: - if ( "-----BEGIN PGP SIGNATURE-----"[++x->pos] == c ) { - if ( x->pos == 28 ) - x->state = STA_found_header_wait_newline; - } - else - x->state = c == '\n'? STA_wait_dash : STA_wait_newline; - break; - case STA_found_header_wait_newline: - /* to make CR,LF issues easier we simply allow for white space - behind the 5 dashes */ - if ( c == '\n' ) - x->state = STA_skip_header_lines; - else if ( c != '\r' && c != ' ' && c != '\t' ) - x->state = STA_wait_dash; /* garbage after the header line */ - break; - case STA_skip_header_lines: - /* i.e. wait for one empty line */ - if ( c == '\n' ) { - x->state = STA_read_data; - x->crc = CRCINIT; - x->val = 0; - x->pos = 0; - } - else if ( c != '\r' && c != ' ' && c != '\t' ) - x->state = STA_skip_header_lines_non_ws; - break; - case STA_skip_header_lines_non_ws: - /* like above but we already encountered non white space */ - if ( c == '\n' ) - x->state = STA_skip_header_lines; - break; - case STA_read_data: - /* fixme: we don't check for the trailing dash lines but rely - * on the armor stop characters */ - if( c == '\n' || c == ' ' || c == '\r' || c == '\t' ) - break; /* skip all kind of white space */ - - if( c == '=' ) { /* pad character: stop */ - if( x->pos == 1 ) /* in this case val has some value */ - rval = x->val; - x->state = STA_wait_crc; - break; - } - - { - int c2; - if( (c = asctobin[(c2=c)]) == 255 ) { - log_error(_("invalid radix64 character %02x skipped\n"), c2); - break; - } - } - - switch(x->pos) { - case 0: - x->val = c << 2; - break; - case 1: - x->val |= (c>>4)&3; - rval = x->val; - x->val = (c<<4)&0xf0; - break; - case 2: - x->val |= (c>>2)&15; - rval = x->val; - x->val = (c<<6)&0xc0; - break; - case 3: - x->val |= c&0x3f; - rval = x->val; - break; - } - x->pos = (x->pos+1) % 4; - break; - case STA_wait_crc: - if( c == '\n' || c == ' ' || c == '\r' || c == '\t' || c == '=' ) - break; /* skip ws and pad characters */ - /* assume that we are at the next line */ - x->state = STA_read_crc; - x->pos = 0; - x->mycrc = 0; - case STA_read_crc: - if( (c = asctobin[c]) == 255 ) { - rval = -1; /* ready */ - if( x->crc != x->mycrc ) { - log_info (_("CRC error; %06lx - %06lx\n"), - (ulong)x->crc, (ulong)x->mycrc); - if ( invalid_crc() ) - rval = -3; - } - x->state = STA_ready; /* not sure whether this is correct */ - break; - } - - switch(x->pos) { - case 0: - x->val = c << 2; - break; - case 1: - x->val |= (c>>4)&3; - x->mycrc |= x->val << 16; - x->val = (c<<4)&0xf0; - break; - case 2: - x->val |= (c>>2)&15; - x->mycrc |= x->val << 8; - x->val = (c<<6)&0xc0; - break; - case 3: - x->val |= c&0x3f; - x->mycrc |= x->val; - break; - } - x->pos = (x->pos+1) % 4; - break; - case STA_ready: - rval = -1; - break; - } - - if ( !(rval & ~255) ) { /* compute the CRC */ - x->crc = (x->crc << 8) ^ crc_table[((x->crc >> 16)&0xff) ^ rval]; - x->crc &= 0x00ffffff; - } - - return rval; -} diff --git a/g10/build-packet.c b/g10/build-packet.c deleted file mode 100644 index d2c538477..000000000 --- a/g10/build-packet.c +++ /dev/null @@ -1,1203 +0,0 @@ -/* build-packet.c - assemble packets and write them - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "mpi.h" -#include "util.h" -#include "cipher.h" -#include "memory.h" -#include "options.h" - - -static int do_comment( iobuf_t out, int ctb, PKT_comment *rem ); -static int do_user_id( iobuf_t out, int ctb, PKT_user_id *uid ); -static int do_public_key( iobuf_t out, int ctb, PKT_public_key *pk ); -static int do_secret_key( iobuf_t out, int ctb, PKT_secret_key *pk ); -static int do_symkey_enc( iobuf_t out, int ctb, PKT_symkey_enc *enc ); -static int do_pubkey_enc( iobuf_t out, int ctb, PKT_pubkey_enc *enc ); -static u32 calc_plaintext( PKT_plaintext *pt ); -static int do_plaintext( iobuf_t out, int ctb, PKT_plaintext *pt ); -static int do_encrypted( iobuf_t out, int ctb, PKT_encrypted *ed ); -static int do_encrypted_mdc( iobuf_t out, int ctb, PKT_encrypted *ed ); -static int do_compressed( iobuf_t out, int ctb, PKT_compressed *cd ); -static int do_signature( iobuf_t out, int ctb, PKT_signature *sig ); -static int do_onepass_sig( iobuf_t out, int ctb, PKT_onepass_sig *ops ); - -static int calc_header_length( u32 len, int new_ctb ); -static int write_16(iobuf_t inp, u16 a); -static int write_32(iobuf_t inp, u32 a); -static int write_header( iobuf_t out, int ctb, u32 len ); -static int write_sign_packet_header( iobuf_t out, int ctb, u32 len ); -static int write_header2( iobuf_t out, int ctb, u32 len, int hdrlen, int blkmode ); -static int write_new_header( iobuf_t out, int ctb, u32 len, int hdrlen ); -static int write_version( iobuf_t out, int ctb ); - -/**************** - * Build a packet and write it to INP - * Returns: 0 := okay - * >0 := error - * Note: Caller must free the packet - */ -int -build_packet( iobuf_t out, PACKET *pkt ) -{ - int new_ctb=0, rc=0, ctb; - int pkttype; - - if( DBG_PACKET ) - log_debug("build_packet() type=%d\n", pkt->pkttype ); - assert( pkt->pkt.generic ); - - switch( (pkttype = pkt->pkttype) ) { - case PKT_OLD_COMMENT: pkttype = pkt->pkttype = PKT_COMMENT; break; - case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break; - case PKT_COMPRESSED:new_ctb = pkt->pkt.compressed->new_ctb; break; - case PKT_USER_ID: - if( pkt->pkt.user_id->attrib_data ) - pkttype = PKT_ATTRIBUTE; - break; - default: break; - } - - if( new_ctb || pkttype > 15 ) /* new format */ - ctb = 0xc0 | (pkttype & 0x3f); - else - ctb = 0x80 | ((pkttype & 15)<<2); - switch( pkttype ) { - case PKT_ATTRIBUTE: - case PKT_USER_ID: - rc = do_user_id( out, ctb, pkt->pkt.user_id ); - break; - case PKT_COMMENT: - rc = do_comment( out, ctb, pkt->pkt.comment ); - break; - case PKT_PUBLIC_SUBKEY: - case PKT_PUBLIC_KEY: - rc = do_public_key( out, ctb, pkt->pkt.public_key ); - break; - case PKT_SECRET_SUBKEY: - case PKT_SECRET_KEY: - rc = do_secret_key( out, ctb, pkt->pkt.secret_key ); - break; - case PKT_SYMKEY_ENC: - rc = do_symkey_enc( out, ctb, pkt->pkt.symkey_enc ); - break; - case PKT_PUBKEY_ENC: - rc = do_pubkey_enc( out, ctb, pkt->pkt.pubkey_enc ); - break; - case PKT_PLAINTEXT: - rc = do_plaintext( out, ctb, pkt->pkt.plaintext ); - break; - case PKT_ENCRYPTED: - rc = do_encrypted( out, ctb, pkt->pkt.encrypted ); - break; - case PKT_ENCRYPTED_MDC: - rc = do_encrypted_mdc( out, ctb, pkt->pkt.encrypted ); - break; - case PKT_COMPRESSED: - rc = do_compressed( out, ctb, pkt->pkt.compressed ); - break; - case PKT_SIGNATURE: - rc = do_signature( out, ctb, pkt->pkt.signature ); - break; - case PKT_ONEPASS_SIG: - rc = do_onepass_sig( out, ctb, pkt->pkt.onepass_sig ); - break; - case PKT_RING_TRUST: - break; /* ignore it (keyring.c does write it directly)*/ - case PKT_MDC: /* we write it directly, so we should never see it here. */ - default: - log_bug("invalid packet type in build_packet()\n"); - break; - } - - return rc; -} - -/**************** - * calculate the length of a packet described by PKT - */ -u32 -calc_packet_length( PACKET *pkt ) -{ - u32 n=0; - int new_ctb = 0; - - assert( pkt->pkt.generic ); - switch( pkt->pkttype ) { - case PKT_PLAINTEXT: - n = calc_plaintext( pkt->pkt.plaintext ); - new_ctb = pkt->pkt.plaintext->new_ctb; - break; - case PKT_ATTRIBUTE: - case PKT_USER_ID: - case PKT_COMMENT: - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - case PKT_SYMKEY_ENC: - case PKT_PUBKEY_ENC: - case PKT_ENCRYPTED: - case PKT_SIGNATURE: - case PKT_ONEPASS_SIG: - case PKT_RING_TRUST: - case PKT_COMPRESSED: - default: - log_bug("invalid packet type in calc_packet_length()"); - break; - } - - n += calc_header_length(n, new_ctb); - return n; -} - -static void -write_fake_data( iobuf_t out, gcry_mpi_t a ) -{ - if( a ) { - unsigned int n; - void *p; - - assert( gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)); - p = gcry_mpi_get_opaque (a, &n); - iobuf_write (out, p, (n+7)/8); - } -} - - -static int -do_comment (iobuf_t out, int ctb, PKT_comment *rem) -{ - int rc = 0; - - if (opt.sk_comments) - { - write_header(out, ctb, rem->len); - rc = iobuf_write( out, rem->data, rem->len ); - } - return rc; -} - -static int -do_user_id( iobuf_t out, int ctb, PKT_user_id *uid ) -{ - int rc; - - if (uid->attrib_data) - { - write_header (out, ctb, uid->attrib_len); - rc = iobuf_write (out, uid->attrib_data, uid->attrib_len ); - } - else - { - write_header (out, ctb, uid->len); - rc = iobuf_write (out, uid->name, uid->len ); - } - return rc; -} - -static int -do_public_key( iobuf_t out, int ctb, PKT_public_key *pk ) -{ - int rc = 0; - int n, i; - iobuf_t a = iobuf_temp(); - - if( !pk->version ) - iobuf_put( a, 3 ); - else - iobuf_put( a, pk->version ); - write_32(a, pk->timestamp ); - if( pk->version < 4 ) { - u16 ndays; - if( pk->expiredate ) - ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L); - else - ndays = 0; - write_16(a, ndays ); - } - iobuf_put(a, pk->pubkey_algo ); - n = pubkey_get_npkey( pk->pubkey_algo ); - if( !n ) - write_fake_data( a, pk->pkey[0] ); - for(i=0; i < n; i++ ) - mpi_write(a, pk->pkey[i] ); - - write_header2(out, ctb, iobuf_get_temp_length(a), pk->hdrbytes, 1 ); - rc = iobuf_write_temp (out, a); - - iobuf_close(a); - return rc; -} - - -/**************** - * Make a hash value from the public key certificate - */ -void -hash_public_key( MD_HANDLE md, PKT_public_key *pk ) -{ - PACKET pkt; - int rc = 0; - int ctb; - ulong pktlen; - int c; - iobuf_t a = iobuf_temp(); -#if 0 - FILE *fp = fopen("dump.pk", "a"); - int i=0; - - fprintf(fp, "\nHashing PK (v%d):\n", pk->version); -#endif - - /* build the packet */ - init_packet(&pkt); - pkt.pkttype = PKT_PUBLIC_KEY; - pkt.pkt.public_key = pk; - if( (rc = build_packet( a, &pkt )) ) - log_fatal("build public_key for hashing failed: %s\n", gpg_strerror (rc)); - - if( !(pk->version == 3 && pk->pubkey_algo == 16) ) { - /* skip the constructed header but don't do this for our very old - * v3 ElG keys */ - ctb = iobuf_get_noeof(a); - pktlen = 0; - if( (ctb & 0x40) ) { - c = iobuf_get_noeof(a); - if( c < 192 ) - pktlen = c; - else if( c < 224 ) { - pktlen = (c - 192) * 256; - c = iobuf_get_noeof(a); - pktlen += c + 192; - } - else if( c == 255 ) { - pktlen = iobuf_get_noeof(a) << 24; - pktlen |= iobuf_get_noeof(a) << 16; - pktlen |= iobuf_get_noeof(a) << 8; - pktlen |= iobuf_get_noeof(a); - } - } - else { - int lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3)); - for( ; lenbytes; lenbytes-- ) { - pktlen <<= 8; - pktlen |= iobuf_get_noeof(a); - } - } - /* hash a header */ - gcry_md_putc ( md, 0x99 ); - pktlen &= 0xffff; /* can't handle longer packets */ - gcry_md_putc ( md, pktlen >> 8 ); - gcry_md_putc ( md, pktlen & 0xff ); - } - /* hash the packet body */ - while( (c=iobuf_get(a)) != -1 ) { -#if 0 - fprintf( fp," %02x", c ); - if( (++i == 24) ) { - putc('\n', fp); - i=0; - } -#endif - gcry_md_putc ( md, c ); - } -#if 0 - putc('\n', fp); - fclose(fp); -#endif - iobuf_cancel(a); -} - - -static int -do_secret_key( iobuf_t out, int ctb, PKT_secret_key *sk ) -{ - int rc = 0; - int i, nskey, npkey; - iobuf_t a = iobuf_temp(); /* build in a self-enlarging buffer */ - - /* Write the version number - if none is specified, use 3 */ - if( !sk->version ) - iobuf_put( a, 3 ); - else - iobuf_put( a, sk->version ); - write_32(a, sk->timestamp ); - - /* v3 needs the expiration time */ - if( sk->version < 4 ) { - u16 ndays; - if( sk->expiredate ) - ndays = (u16)((sk->expiredate - sk->timestamp) / 86400L); - else - ndays = 0; - write_16(a, ndays); - } - - iobuf_put(a, sk->pubkey_algo ); - - /* get number of secret and public parameters. They are held in - one array first the public ones, then the secret ones */ - nskey = pubkey_get_nskey( sk->pubkey_algo ); - npkey = pubkey_get_npkey( sk->pubkey_algo ); - - /* If we don't have any public parameters - which is the case if - we don't know the algorithm used - the parameters are stored as - one blob in a faked (opaque) gcry_mpi_t */ - if( !npkey ) { - write_fake_data( a, sk->skey[0] ); - goto leave; - } - assert( npkey < nskey ); - - /* Writing the public parameters is easy */ - for(i=0; i < npkey; i++ ) - mpi_write(a, sk->skey[i] ); - - /* build the header for protected (encrypted) secret parameters */ - if( sk->is_protected ) { - if( is_RSA(sk->pubkey_algo) && sk->version < 4 - && !sk->protect.s2k.mode ) { - /* the simple rfc1991 (v3) way */ - iobuf_put(a, sk->protect.algo ); - iobuf_write(a, sk->protect.iv, sk->protect.ivlen ); - } - else { - /* OpenPGP protection according to rfc2440 */ - iobuf_put(a, sk->protect.sha1chk? 0xfe : 0xff ); - iobuf_put(a, sk->protect.algo ); - if( sk->protect.s2k.mode >= 1000 ) { - /* These modes are not possible in OpenPGP, we use them - to implement our extensions, 101 can be seen as a - private/experimental extension (this is not - specified in rfc2440 but the same scheme is used - for all other algorithm identifiers) */ - iobuf_put(a, 101 ); - iobuf_put(a, sk->protect.s2k.hash_algo ); - iobuf_write(a, "GNU", 3 ); - iobuf_put(a, sk->protect.s2k.mode - 1000 ); - } - else { - iobuf_put(a, sk->protect.s2k.mode ); - iobuf_put(a, sk->protect.s2k.hash_algo ); - } - if( sk->protect.s2k.mode == 1 - || sk->protect.s2k.mode == 3 ) - iobuf_write(a, sk->protect.s2k.salt, 8 ); - if( sk->protect.s2k.mode == 3 ) - iobuf_put(a, sk->protect.s2k.count ); - - /* For our special modes 1001 and 1002 we do not need an IV */ - if( sk->protect.s2k.mode != 1001 - && sk->protect.s2k.mode != 1002 ) - iobuf_write(a, sk->protect.iv, sk->protect.ivlen ); - } - } - else - iobuf_put(a, 0 ); - - if( sk->protect.s2k.mode == 1001 ) - ; /* GnuPG extension - don't write a secret key at all */ - else if( sk->protect.s2k.mode == 1002 ) - { /* GnuPG extension - divert to OpenPGP smartcard. */ - iobuf_put(a, sk->protect.ivlen ); /* length of the serial - number or 0 for no serial - number. */ - /* The serial number gets stored in the IV field. */ - iobuf_write(a, sk->protect.iv, sk->protect.ivlen); - } - else if( sk->is_protected && sk->version >= 4 ) { - /* The secret key is protected - write it out as it is */ - byte *p; - assert( gcry_mpi_get_flag( sk->skey[npkey], GCRYMPI_FLAG_OPAQUE ) ); - p = gcry_mpi_get_opaque( sk->skey[npkey], &i ); - iobuf_write(a, p, (i+7)/8 ); - } - else if( sk->is_protected ) { - /* The secret key is protected the old v4 way. */ - for( ; i < nskey; i++ ) { - byte *p; - size_t n; - - assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE)); - p = gcry_mpi_get_opaque( sk->skey[i], &n ); - iobuf_write (a, p, (n+7)/8); - } - write_16(a, sk->csum ); - } - else { - /* non-protected key */ - for( ; i < nskey; i++ ) - mpi_write(a, sk->skey[i] ); - write_16(a, sk->csum ); - } - - leave: - /* Build the header of the packet - which we must do after writing all - the other stuff, so that we know the length of the packet */ - write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes, 1 ); - /* And finally write it out the real stream */ - rc = iobuf_write_temp (out, a ); - - iobuf_close(a); /* close the remporary buffer */ - return rc; -} - -static int -do_symkey_enc( iobuf_t out, int ctb, PKT_symkey_enc *enc ) -{ - int rc = 0; - iobuf_t a = iobuf_temp(); - - assert( enc->version == 4 ); - switch( enc->s2k.mode ) { - case 0: case 1: case 3: break; - default: log_bug("do_symkey_enc: s2k=%d\n", enc->s2k.mode ); - } - iobuf_put( a, enc->version ); - iobuf_put( a, enc->cipher_algo ); - iobuf_put( a, enc->s2k.mode ); - iobuf_put( a, enc->s2k.hash_algo ); - if( enc->s2k.mode == 1 || enc->s2k.mode == 3 ) { - iobuf_write(a, enc->s2k.salt, 8 ); - if( enc->s2k.mode == 3 ) - iobuf_put(a, enc->s2k.count); - } - if( enc->seskeylen ) - iobuf_write(a, enc->seskey, enc->seskeylen ); - - write_header(out, ctb, iobuf_get_temp_length(a) ); - rc = iobuf_write_temp (out, a); - - iobuf_close(a); - return rc; -} - - - - -static int -do_pubkey_enc( iobuf_t out, int ctb, PKT_pubkey_enc *enc ) -{ - int rc = 0; - int n, i; - iobuf_t a = iobuf_temp(); - - write_version( a, ctb ); - if( enc->throw_keyid ) { - write_32(a, 0 ); /* don't tell Eve who can decrypt the message */ - write_32(a, 0 ); - } - else { - write_32(a, enc->keyid[0] ); - write_32(a, enc->keyid[1] ); - } - iobuf_put(a,enc->pubkey_algo ); - n = pubkey_get_nenc( enc->pubkey_algo ); - if( !n ) - write_fake_data( a, enc->data[0] ); - for(i=0; i < n; i++ ) - mpi_write(a, enc->data[i] ); - - write_header(out, ctb, iobuf_get_temp_length(a) ); - rc = iobuf_write_temp (out, a); - - iobuf_close(a); - return rc; -} - - - - -static u32 -calc_plaintext( PKT_plaintext *pt ) -{ - return pt->len? (1 + 1 + pt->namelen + 4 + pt->len) : 0; -} - -static int -do_plaintext( iobuf_t out, int ctb, PKT_plaintext *pt ) -{ - int i, rc = 0; - u32 n; - byte buf[1000]; /* this buffer has the plaintext! */ - int nbytes; - - /* Truncate namelen to the maximum 255 characters. This does mean - that a function that calls build_packet with an illegal literal - packet will get it back legalized. */ - if(pt->namelen>255) - pt->namelen=255; - - write_header(out, ctb, calc_plaintext( pt ) ); - iobuf_put(out, pt->mode ); - iobuf_put(out, pt->namelen ); - for(i=0; i < pt->namelen; i++ ) - iobuf_put(out, pt->name[i] ); - rc = write_32 (out, pt->timestamp); - - n = 0; - while( (nbytes=iobuf_read(pt->buf, buf, 1000)) != -1 ) { - rc = iobuf_write(out, buf, nbytes); - if (rc) - break; - n += nbytes; - } - wipememory(buf,1000); /* burn the buffer */ - if( !pt->len ) - iobuf_set_block_mode(out, 0 ); /* write end marker */ - else if( n != pt->len ) - log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n", - (ulong)n, (ulong)pt->len ); - - return rc; -} - - - -static int -do_encrypted( iobuf_t out, int ctb, PKT_encrypted *ed ) -{ - int rc = 0; - u32 n; - - n = ed->len ? (ed->len + ed->extralen) : 0; - write_header(out, ctb, n ); - - /* This is all. The caller has to write the real data */ - - return rc; -} - -static int -do_encrypted_mdc( iobuf_t out, int ctb, PKT_encrypted *ed ) -{ - int rc = 0; - u32 n; - - assert( ed->mdc_method ); - - /* Take version number and the following MDC packet in account. */ - n = ed->len ? (ed->len + ed->extralen + 1 + 22) : 0; - write_header(out, ctb, n ); - iobuf_put(out, 1 ); /* version */ - - /* This is all. The caller has to write the real data */ - - return rc; -} - - -static int -do_compressed( iobuf_t out, int ctb, PKT_compressed *cd ) -{ - int rc = 0; - - /* We must use the old convention and don't use blockmode for tyhe - sake of PGP 2 compatibility. However if the new_ctb flag was - set, CTB is already formatted as new style and write_header2 - does create a partial length encoding using new the new - style. */ - write_header2(out, ctb, 0, 0, 0 ); - iobuf_put(out, cd->algorithm ); - - /* This is all. The caller has to write the real data */ - - return rc; -} - - -/**************** - * Delete all subpackets of type REQTYPE and return a bool whether a packet - * was deleted. - */ -int -delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype ) -{ - int buflen; - sigsubpkttype_t type; - byte *buffer, *bufstart; - size_t n; - size_t unused = 0; - int okay = 0; - - if( !area ) - return 0; - buflen = area->len; - buffer = area->data; - for(;;) { - if( !buflen ) { - okay = 1; - break; - } - bufstart = buffer; - n = *buffer++; buflen--; - if( n == 255 ) { - if( buflen < 4 ) - break; - n = (buffer[0] << 24) | (buffer[1] << 16) - | (buffer[2] << 8) | buffer[3]; - buffer += 4; - buflen -= 4; - } - else if( n >= 192 ) { - if( buflen < 2 ) - break; - n = (( n - 192 ) << 8) + *buffer + 192; - buffer++; - buflen--; - } - if( buflen < n ) - break; - - type = *buffer & 0x7f; - if( type == reqtype ) { - buffer++; - buflen--; - n--; - if( n > buflen ) - break; - buffer += n; /* point to next subpkt */ - buflen -= n; - memmove (bufstart, buffer, buflen); /* shift */ - unused += buffer - bufstart; - buffer = bufstart; - } - else { - buffer += n; buflen -=n; - } - } - - if (!okay) - log_error ("delete_subpkt: buffer shorter than subpacket\n"); - assert (unused <= area->len); - area->len -= unused; - return !!unused; -} - - -/**************** - * Create or update a signature subpacket for SIG of TYPE. This - * functions knows where to put the data (hashed or unhashed). The - * function may move data from the unhashed part to the hashed one. - * Note: All pointers into sig->[un]hashed (e.g. returned by - * parse_sig_subpkt) are not valid after a call to this function. The - * data to put into the subpaket should be in a buffer with a length - * of buflen. - */ -void -build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type, - const byte *buffer, size_t buflen ) -{ - byte *p; - int critical, hashed; - subpktarea_t *oldarea, *newarea; - size_t nlen, n, n0; - - critical = (type & SIGSUBPKT_FLAG_CRITICAL); - type &= ~SIGSUBPKT_FLAG_CRITICAL; - - /* Sanity check buffer sizes */ - if(parse_one_sig_subpkt(buffer,buflen,type)<0) - BUG(); - - switch(type) - { - case SIGSUBPKT_NOTATION: - case SIGSUBPKT_POLICY: - case SIGSUBPKT_REV_KEY: - /* we do allow multiple subpackets */ - break; - - default: - /* we don't allow multiple subpackets */ - delete_sig_subpkt(sig->hashed,type); - delete_sig_subpkt(sig->unhashed,type); - break; - } - - /* Any special magic that needs to be done for this type so the - packet doesn't need to be reparsed? */ - switch(type) - { - case SIGSUBPKT_NOTATION: - sig->flags.notation=1; - break; - - case SIGSUBPKT_POLICY: - sig->flags.policy_url=1; - break; - - case SIGSUBPKT_PREF_KS: - sig->flags.pref_ks=1; - break; - - case SIGSUBPKT_EXPORTABLE: - if(buffer[0]) - sig->flags.exportable=1; - else - sig->flags.exportable=0; - break; - - case SIGSUBPKT_REVOCABLE: - if(buffer[0]) - sig->flags.revocable=1; - else - sig->flags.revocable=0; - break; - - case SIGSUBPKT_TRUST: - sig->trust_depth=buffer[0]; - sig->trust_value=buffer[1]; - break; - - case SIGSUBPKT_REGEXP: - sig->trust_regexp=buffer; - break; - - /* This should never happen since we don't currently allow - creating such a subpacket, but just in case... */ - case SIGSUBPKT_SIG_EXPIRE: - if(buffer_to_u32(buffer)+sig->timestamp<=make_timestamp()) - sig->flags.expired=1; - else - sig->flags.expired=0; - break; - - default: - break; - } - - if( (buflen+1) >= 8384 ) - nlen = 5; /* write 5 byte length header */ - else if( (buflen+1) >= 192 ) - nlen = 2; /* write 2 byte length header */ - else - nlen = 1; /* just a 1 byte length header */ - - switch( type ) { - /* The issuer being unhashed is a historical oddity. It - should work equally as well hashed. Of course, if even an - unhashed issuer is tampered with, it makes it awfully hard - to verify the sig... */ - case SIGSUBPKT_ISSUER: - hashed = 0; - break; - default: - hashed = 1; - break; - } - - if( critical ) - type |= SIGSUBPKT_FLAG_CRITICAL; - - oldarea = hashed? sig->hashed : sig->unhashed; - - /* Calculate new size of the area and allocate */ - n0 = oldarea? oldarea->len : 0; - n = n0 + nlen + 1 + buflen; /* length, type, buffer */ - if (oldarea && n <= oldarea->size) { /* fits into the unused space */ - newarea = oldarea; - /*log_debug ("updating area for type %d\n", type );*/ - } - else if (oldarea) { - newarea = xrealloc (oldarea, sizeof (*newarea) + n - 1); - newarea->size = n; - /*log_debug ("reallocating area for type %d\n", type );*/ - } - else { - newarea = xmalloc (sizeof (*newarea) + n - 1); - newarea->size = n; - /*log_debug ("allocating area for type %d\n", type );*/ - } - newarea->len = n; - - p = newarea->data + n0; - if (nlen == 5) { - *p++ = 255; - *p++ = (buflen+1) >> 24; - *p++ = (buflen+1) >> 16; - *p++ = (buflen+1) >> 8; - *p++ = (buflen+1); - *p++ = type; - memcpy (p, buffer, buflen); - } - else if (nlen == 2) { - *p++ = (buflen+1-192) / 256 + 192; - *p++ = (buflen+1-192) % 256; - *p++ = type; - memcpy (p, buffer, buflen); - } - else { - *p++ = buflen+1; - *p++ = type; - memcpy (p, buffer, buflen); - } - - if (hashed) - sig->hashed = newarea; - else - sig->unhashed = newarea; -} - -/**************** - * Put all the required stuff from SIG into subpackets of sig. - * Hmmm, should we delete those subpackets which are in a wrong area? - */ -void -build_sig_subpkt_from_sig( PKT_signature *sig ) -{ - u32 u; - byte buf[8]; - - u = sig->keyid[0]; - buf[0] = (u >> 24) & 0xff; - buf[1] = (u >> 16) & 0xff; - buf[2] = (u >> 8) & 0xff; - buf[3] = u & 0xff; - u = sig->keyid[1]; - buf[4] = (u >> 24) & 0xff; - buf[5] = (u >> 16) & 0xff; - buf[6] = (u >> 8) & 0xff; - buf[7] = u & 0xff; - build_sig_subpkt( sig, SIGSUBPKT_ISSUER, buf, 8 ); - - u = sig->timestamp; - buf[0] = (u >> 24) & 0xff; - buf[1] = (u >> 16) & 0xff; - buf[2] = (u >> 8) & 0xff; - buf[3] = u & 0xff; - build_sig_subpkt( sig, SIGSUBPKT_SIG_CREATED, buf, 4 ); - - if(sig->expiredate) - { - if(sig->expiredate>sig->timestamp) - u=sig->expiredate-sig->timestamp; - else - u=0; - - buf[0] = (u >> 24) & 0xff; - buf[1] = (u >> 16) & 0xff; - buf[2] = (u >> 8) & 0xff; - buf[3] = u & 0xff; - - /* Mark this CRITICAL, so if any implementation doesn't - understand sigs that can expire, it'll just disregard this - sig altogether. */ - - build_sig_subpkt( sig, SIGSUBPKT_SIG_EXPIRE | SIGSUBPKT_FLAG_CRITICAL, - buf, 4 ); - } -} - -void -build_attribute_subpkt(PKT_user_id *uid,byte type, - const void *buf,u32 buflen, - const void *header,u32 headerlen) -{ - byte *attrib; - int idx; - - if(1+headerlen+buflen>8383) - idx=5; - else if(1+headerlen+buflen>191) - idx=2; - else - idx=1; - - /* realloc uid->attrib_data to the right size */ - - uid->attrib_data=xrealloc(uid->attrib_data, - uid->attrib_len+idx+1+headerlen+buflen); - - attrib=&uid->attrib_data[uid->attrib_len]; - - if(idx==5) - { - attrib[0]=255; - attrib[1]=(1+headerlen+buflen) >> 24; - attrib[2]=(1+headerlen+buflen) >> 16; - attrib[3]=(1+headerlen+buflen) >> 8; - attrib[4]=1+headerlen+buflen; - } - else if(idx==2) - { - attrib[0]=(1+headerlen+buflen-192) / 256 + 192; - attrib[1]=(1+headerlen+buflen-192) % 256; - } - else - attrib[0]=1+headerlen+buflen; /* Good luck finding a JPEG this small! */ - - attrib[idx++]=type; - - /* Tack on our data at the end */ - - if(headerlen>0) - memcpy(&attrib[idx],header,headerlen); - memcpy(&attrib[idx+headerlen],buf,buflen); - uid->attrib_len+=idx+headerlen+buflen; -} - -static int -do_signature( iobuf_t out, int ctb, PKT_signature *sig ) -{ - int rc = 0; - int n, i; - iobuf_t a = iobuf_temp(); - - if( !sig->version ) - iobuf_put( a, 3 ); - else - iobuf_put( a, sig->version ); - if( sig->version < 4 ) - iobuf_put(a, 5 ); /* constant */ - iobuf_put(a, sig->sig_class ); - if( sig->version < 4 ) { - write_32(a, sig->timestamp ); - write_32(a, sig->keyid[0] ); - write_32(a, sig->keyid[1] ); - } - iobuf_put(a, sig->pubkey_algo ); - iobuf_put(a, sig->digest_algo ); - if( sig->version >= 4 ) { - size_t nn; - /* timestamp and keyid must have been packed into the - * subpackets prior to the call of this function, because - * these subpackets are hashed */ - nn = sig->hashed? sig->hashed->len : 0; - write_16(a, nn); - if( nn ) - iobuf_write( a, sig->hashed->data, nn ); - nn = sig->unhashed? sig->unhashed->len : 0; - write_16(a, nn); - if( nn ) - iobuf_write( a, sig->unhashed->data, nn ); - } - iobuf_put(a, sig->digest_start[0] ); - iobuf_put(a, sig->digest_start[1] ); - n = pubkey_get_nsig( sig->pubkey_algo ); - if( !n ) - write_fake_data( a, sig->data[0] ); - for(i=0; i < n; i++ ) - mpi_write(a, sig->data[i] ); - - if( is_RSA(sig->pubkey_algo) && sig->version < 4 ) - write_sign_packet_header(out, ctb, iobuf_get_temp_length(a) ); - else - write_header(out, ctb, iobuf_get_temp_length(a) ); - rc = iobuf_write_temp (out, a); - - iobuf_close(a); - return rc; -} - - -static int -do_onepass_sig( iobuf_t out, int ctb, PKT_onepass_sig *ops ) -{ - int rc = 0; - iobuf_t a = iobuf_temp(); - - write_version( a, ctb ); - iobuf_put(a, ops->sig_class ); - iobuf_put(a, ops->digest_algo ); - iobuf_put(a, ops->pubkey_algo ); - write_32(a, ops->keyid[0] ); - write_32(a, ops->keyid[1] ); - iobuf_put(a, ops->last ); - - write_header(out, ctb, iobuf_get_temp_length(a) ); - rc = iobuf_write_temp (out, a); - - iobuf_close(a); - return rc; -} - - -static int -write_16(iobuf_t out, u16 a) -{ - iobuf_put(out, a>>8); - return iobuf_put(out,a); -} - -static int -write_32(iobuf_t out, u32 a) -{ - iobuf_put(out, a>> 24); - iobuf_put(out, a>> 16); - iobuf_put(out, a>> 8); - return iobuf_put (out, a); -} - - -/**************** - * calculate the length of a header - */ -static int -calc_header_length( u32 len, int new_ctb ) -{ - if( !len ) - return 1; /* only the ctb */ - - if( new_ctb ) { - if( len < 192 ) - return 2; - if( len < 8384 ) - return 3; - else - return 6; - } - if( len < 256 ) - return 2; - if( len < 65536 ) - return 3; - - return 5; -} - -/**************** - * Write the CTB and the packet length - */ -static int -write_header( iobuf_t out, int ctb, u32 len ) -{ - return write_header2( out, ctb, len, 0, 1 ); -} - - -static int -write_sign_packet_header( iobuf_t out, int ctb, u32 len ) -{ - /* work around a bug in the pgp read function for signature packets, - * which are not correctly coded and silently assume at some - * point 2 byte length headers.*/ - iobuf_put(out, 0x89 ); - iobuf_put(out, len >> 8 ); - return iobuf_put(out, len ) == -1 ? -1:0; -} - -/**************** - * if HDRLEN is > 0, try to build a header of this length. - * we need this, so that we can hash packets without reading them again. - */ -static int -write_header2( iobuf_t out, int ctb, u32 len, int hdrlen, int blkmode ) -{ - if( ctb & 0x40 ) - return write_new_header( out, ctb, len, hdrlen ); - - if( hdrlen ) { - if( !len ) - ctb |= 3; - else if( hdrlen == 2 && len < 256 ) - ; - else if( hdrlen == 3 && len < 65536 ) - ctb |= 1; - else - ctb |= 2; - } - else { - if( !len ) - ctb |= 3; - else if( len < 256 ) - ; - else if( len < 65536 ) - ctb |= 1; - else - ctb |= 2; - } - if( iobuf_put(out, ctb ) ) - return -1; - if( !len ) { - if( blkmode ) - iobuf_set_block_mode(out, 8196 ); - } - else { - if( ctb & 2 ) { - iobuf_put(out, len >> 24 ); - iobuf_put(out, len >> 16 ); - } - if( ctb & 3 ) - iobuf_put(out, len >> 8 ); - if( iobuf_put(out, len ) ) - return -1; - } - return 0; -} - - -static int -write_new_header( iobuf_t out, int ctb, u32 len, int hdrlen ) -{ - if( hdrlen ) - log_bug("can't cope with hdrlen yet\n"); - - if( iobuf_put(out, ctb ) ) - return -1; - if( !len ) { - iobuf_set_partial_block_mode(out, 512 ); - } - else { - if( len < 192 ) { - if( iobuf_put(out, len ) ) - return -1; - } - else if( len < 8384 ) { - len -= 192; - if( iobuf_put( out, (len / 256) + 192) ) - return -1; - if( iobuf_put( out, (len % 256) ) ) - return -1; - } - else { - if( iobuf_put( out, 0xff ) ) - return -1; - if( iobuf_put( out, (len >> 24)&0xff ) ) - return -1; - if( iobuf_put( out, (len >> 16)&0xff ) ) - return -1; - if( iobuf_put( out, (len >> 8)&0xff ) ) - return -1; - if( iobuf_put( out, len & 0xff ) ) - return -1; - } - } - return 0; -} - -static int -write_version( iobuf_t out, int ctb ) -{ - if( iobuf_put( out, 3 ) ) - return -1; - return 0; -} diff --git a/g10/call-agent.c b/g10/call-agent.c deleted file mode 100644 index de157d491..000000000 --- a/g10/call-agent.c +++ /dev/null @@ -1,893 +0,0 @@ -/* call-agent.c - divert operations to the agent - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#if 0 /* lety Emacs display a red warning */ -#error fixme: this shares a lof of code with the file in ../sm -#endif - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif -#include <assuan.h> - -#include "gpg.h" -#include "util.h" -#include "membuf.h" -#include "options.h" -#include "i18n.h" -#include "call-agent.h" - -#ifndef DBG_ASSUAN -# define DBG_ASSUAN 1 -#endif - -static ASSUAN_CONTEXT agent_ctx = NULL; -static int force_pipe_server = 1; /* FIXME: set this back to 0. */ - -struct cipher_parm_s { - ASSUAN_CONTEXT ctx; - const char *ciphertext; - size_t ciphertextlen; -}; - -struct genkey_parm_s { - ASSUAN_CONTEXT ctx; - const char *sexp; - size_t sexplen; -}; - - - -/* Try to connect to the agent via socket or fork it off and work by - pipes. Handle the server's initial greeting */ -static int -start_agent (void) -{ - int rc = 0; - char *infostr, *p; - ASSUAN_CONTEXT ctx; - char *dft_display = NULL; - char *dft_ttyname = NULL; - char *dft_ttytype = NULL; - char *old_lc = NULL; - char *dft_lc = NULL; - - if (agent_ctx) - return 0; /* fixme: We need a context for each thread or serialize - the access to the agent. */ - - infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO"); - if (!infostr || !*infostr) - { - const char *pgmname; - const char *argv[3]; - int no_close_list[3]; - int i; - - if (opt.verbose) - log_info (_("no running gpg-agent - starting one\n")); - - if (fflush (NULL)) - { - gpg_error_t tmperr = gpg_error_from_errno (errno); - log_error ("error flushing pending output: %s\n", strerror (errno)); - return tmperr; - } - - if (!opt.agent_program || !*opt.agent_program) - opt.agent_program = GNUPG_DEFAULT_AGENT; - if ( !(pgmname = strrchr (opt.agent_program, '/'))) - pgmname = opt.agent_program; - else - pgmname++; - - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; - - i=0; - if (log_get_fd () != -1) - no_close_list[i++] = log_get_fd (); - no_close_list[i++] = fileno (stderr); - no_close_list[i] = -1; - - /* connect to the agent and perform initial handshaking */ - rc = assuan_pipe_connect (&ctx, opt.agent_program, (char**)argv, - no_close_list); - } - else - { - int prot; - int pid; - - infostr = xstrdup (infostr); - if ( !(p = strchr (infostr, ':')) || p == infostr) - { - log_error (_("malformed GPG_AGENT_INFO environment variable\n")); - xfree (infostr); - force_pipe_server = 1; - return start_agent (); - } - *p++ = 0; - pid = atoi (p); - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if (prot != 1) - { - log_error (_("gpg-agent protocol version %d is not supported\n"), - prot); - xfree (infostr); - force_pipe_server = 1; - return start_agent (); - } - - rc = assuan_socket_connect (&ctx, infostr, pid); - xfree (infostr); - if (rc == ASSUAN_Connect_Failed) - { - log_error (_("can't connect to the agent - trying fall back\n")); - force_pipe_server = 1; - return start_agent (); - } - } - - if (rc) - { - log_error ("can't connect to the agent: %s\n", assuan_strerror (rc)); - return gpg_error (GPG_ERR_NO_AGENT); - } - agent_ctx = ctx; - - if (DBG_ASSUAN) - log_debug ("connection to agent established\n"); - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - dft_display = getenv ("DISPLAY"); - if (opt.display || dft_display) - { - char *optstr; - if (asprintf (&optstr, "OPTION display=%s", - opt.display ? opt.display : dft_display) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } - if (!opt.ttyname) - { - dft_ttyname = getenv ("GPG_TTY"); - if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) - dft_ttyname = ttyname (0); - } - if (opt.ttyname || dft_ttyname) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttyname=%s", - opt.ttyname ? opt.ttyname : dft_ttyname) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } - dft_ttytype = getenv ("TERM"); - if (opt.ttytype || (dft_ttyname && dft_ttytype)) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttytype=%s", - opt.ttyname ? opt.ttytype : dft_ttytype) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - old_lc = setlocale (LC_CTYPE, NULL); - if (old_lc) - { - old_lc = strdup (old_lc); - if (!old_lc) - return gpg_error_from_errno (errno); - - } - dft_lc = setlocale (LC_CTYPE, ""); -#endif - if (opt.lc_ctype || (dft_ttyname && dft_lc)) - { - char *optstr; - if (asprintf (&optstr, "OPTION lc-ctype=%s", - opt.lc_ctype ? opt.lc_ctype : dft_lc) < 0) - rc = gpg_error_from_errno (errno); - else - { - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - rc = map_assuan_err (rc); - } - } -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - if (old_lc) - { - setlocale (LC_CTYPE, old_lc); - free (old_lc); - } -#endif - if (rc) - return rc; -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - old_lc = setlocale (LC_MESSAGES, NULL); - if (old_lc) - { - old_lc = strdup (old_lc); - if (!old_lc) - return gpg_error_from_errno (errno); - } - dft_lc = setlocale (LC_MESSAGES, ""); -#endif - if (opt.lc_messages || (dft_ttyname && dft_lc)) - { - char *optstr; - if (asprintf (&optstr, "OPTION lc-messages=%s", - opt.lc_messages ? opt.lc_messages : dft_lc) < 0) - rc = gpg_error_from_errno (errno); - else - { - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - rc = map_assuan_err (rc); - } - } -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - if (old_lc) - { - setlocale (LC_MESSAGES, old_lc); - free (old_lc); - } -#endif - - return rc; -} - - -/* Return a new malloced string by unescaping the string S. Escaping - is percent escaping and '+'/space mapping. A binary nul will - silently be replaced by a 0xFF. Function returns NULL to indicate - an out of memory status. */ -static char * -unescape_status_string (const unsigned char *s) -{ - char *buffer, *d; - - buffer = d = xtrymalloc (strlen (s)+1); - if (!buffer) - return NULL; - while (*s) - { - if (*s == '%' && s[1] && s[2]) - { - s++; - *d = xtoi_2 (s); - if (!*d) - *d = '\xff'; - d++; - s += 2; - } - else if (*s == '+') - { - *d++ = ' '; - s++; - } - else - *d++ = *s++; - } - *d = 0; - return buffer; -} - -/* Take a 20 byte hexencoded string and put it into the the provided - 20 byte buffer FPR in binary format. */ -static int -unhexify_fpr (const char *hexstr, unsigned char *fpr) -{ - const char *s; - int n; - - for (s=hexstr, n=0; hexdigitp (s); s++, n++) - ; - if (*s || (n != 40)) - return 0; /* no fingerprint (invalid or wrong length). */ - n /= 2; - for (s=hexstr, n=0; *s; s += 2, n++) - fpr[n] = xtoi_2 (s); - return 1; /* okay */ -} - -/* Take the serial number from LINE and return it verbatim in a newly - allocated string. We make sure that only hex characters are - returned. */ -static char * -store_serialno (const char *line) -{ - const char *s; - char *p; - - for (s=line; hexdigitp (s); s++) - ; - p = xtrymalloc (s + 1 - line); - if (p) - { - memcpy (p, line, s-line); - p[s-line] = 0; - } - return p; -} - - - -#if 0 -/* Handle a KEYPARMS inquiry. Note, we only send the data, - assuan_transact takes care of flushing and writing the end */ -static AssuanError -inq_genkey_parms (void *opaque, const char *keyword) -{ - struct genkey_parm_s *parm = opaque; - AssuanError rc; - - rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen); - return rc; -} - - - -/* Call the agent to generate a new key */ -int -agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey) -{ - int rc; - struct genkey_parm_s gk_parm; - membuf_t data; - size_t len; - char *buf; - - *r_pubkey = NULL; - rc = start_agent (); - if (rc) - return rc; - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, - NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - init_membuf (&data, 1024); - gk_parm.ctx = agent_ctx; - gk_parm.sexp = keyparms; - gk_parm.sexplen = gcry_sexp_canon_len (keyparms, 0, NULL, NULL); - if (!gk_parm.sexplen) - return gpg_error (GPG_ERR_INV_VALUE); - rc = assuan_transact (agent_ctx, "GENKEY", - membuf_data_cb, &data, - inq_genkey_parms, &gk_parm, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - buf = get_membuf (&data, &len); - if (!buf) - return gpg_error (GPG_ERR_ENOMEM); - if (!gcry_sexp_canon_len (buf, len, NULL, NULL)) - { - xfree (buf); - return gpg_error (GPG_ERR_INV_SEXP); - } - *r_pubkey = buf; - return 0; -} -#endif /*0*/ - - - -/* Ask the agent whether the corresponding secret key is available for - the given keygrip. */ -int -agent_havekey (const char *hexkeygrip) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (); - if (rc) - return rc; - - if (!hexkeygrip || strlen (hexkeygrip) != 40) - return gpg_error (GPG_ERR_INV_VALUE); - - snprintf (line, DIM(line)-1, "HAVEKEY %s", hexkeygrip); - line[DIM(line)-1] = 0; - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - - -/* Release the card info structure INFO. */ -void -agent_release_card_info (struct agent_card_info_s *info) -{ - if (!info) - return; - - xfree (info->serialno); info->serialno = NULL; - xfree (info->disp_name); info->disp_name = NULL; - xfree (info->disp_lang); info->disp_lang = NULL; - xfree (info->pubkey_url); info->pubkey_url = NULL; - xfree (info->login_data); info->login_data = NULL; - info->fpr1valid = info->fpr2valid = info->fpr3valid = 0; -} - -static AssuanError -learn_status_cb (void *opaque, const char *line) -{ - struct agent_card_info_s *parm = opaque; - const char *keyword = line; - int keywordlen; - int i; - - for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) - ; - while (spacep (line)) - line++; - - if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen)) - { - xfree (parm->serialno); - parm->serialno = store_serialno (line); - } - else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen)) - { - xfree (parm->disp_name); - parm->disp_name = unescape_status_string (line); - } - else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen)) - { - xfree (parm->disp_lang); - parm->disp_lang = unescape_status_string (line); - } - else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen)) - { - parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0; - } - else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen)) - { - xfree (parm->pubkey_url); - parm->pubkey_url = unescape_status_string (line); - } - else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen)) - { - xfree (parm->login_data); - parm->login_data = unescape_status_string (line); - } - else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen)) - { - parm->sig_counter = strtoul (line, NULL, 0); - } - else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen)) - { - char *p, *buf; - - buf = p = unescape_status_string (line); - if (buf) - { - while (spacep (p)) - p++; - parm->chv1_cached = atoi (p); - while (*p && !spacep (p)) - p++; - while (spacep (p)) - p++; - for (i=0; *p && i < 3; i++) - { - parm->chvmaxlen[i] = atoi (p); - while (*p && !spacep (p)) - p++; - while (spacep (p)) - p++; - } - for (i=0; *p && i < 3; i++) - { - parm->chvretry[i] = atoi (p); - while (*p && !spacep (p)) - p++; - while (spacep (p)) - p++; - } - xfree (buf); - } - } - else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen)) - { - int no = atoi (line); - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; - if (no == 1) - parm->fpr1valid = unhexify_fpr (line, parm->fpr1); - else if (no == 2) - parm->fpr2valid = unhexify_fpr (line, parm->fpr2); - else if (no == 3) - parm->fpr3valid = unhexify_fpr (line, parm->fpr3); - } - - return 0; -} - -/* Call the agent to learn about a smartcard */ -int -agent_learn (struct agent_card_info_s *info) -{ - int rc; - - rc = start_agent (); - if (rc) - return rc; - - memset (info, 0, sizeof *info); - rc = assuan_transact (agent_ctx, "LEARN --send", - NULL, NULL, NULL, NULL, - learn_status_cb, info); - - return map_assuan_err (rc); -} - -/* Call the agent to retrieve a data object. This function returns - the data in the same structure as used by the learn command. It is - allowed to update such a structure using this commmand. */ -int -agent_scd_getattr (const char *name, struct agent_card_info_s *info) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - if (!*name) - return gpg_error (GPG_ERR_INV_VALUE); - - /* We assume that NAME does not need escaping. */ - if (12 + strlen (name) > DIM(line)-1) - return gpg_error (GPG_ERR_TOO_LARGE); - stpcpy (stpcpy (line, "SCD GETATTR "), name); - - rc = start_agent (); - if (rc) - return rc; - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, - learn_status_cb, info); - - return map_assuan_err (rc); -} - - -/* Send an setattr command to the SCdaemon. */ -int -agent_scd_setattr (const char *name, - const unsigned char *value, size_t valuelen) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - char *p; - - if (!*name || !valuelen) - return gpg_error (GPG_ERR_INV_VALUE); - - /* We assume that NAME does not need escaping. */ - if (12 + strlen (name) > DIM(line)-1) - return gpg_error (GPG_ERR_TOO_LARGE); - - p = stpcpy (stpcpy (line, "SCD SETATTR "), name); - *p++ = ' '; - for (; valuelen; value++, valuelen--) - { - if (p >= line + DIM(line)-5 ) - return gpg_error (GPG_ERR_TOO_LARGE); - if (*value < ' ' || *value == '+' || *value == '%') - { - sprintf (p, "%%%02X", *value); - p += 3; - } - else if (*value == ' ') - *p++ = '+'; - else - *p++ = *value; - } - *p = 0; - - rc = start_agent (); - if (rc) - return rc; - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - - -/* Status callback for the SCD GENKEY command. */ -static AssuanError -scd_genkey_cb (void *opaque, const char *line) -{ - struct agent_card_genkey_s *parm = opaque; - const char *keyword = line; - int keywordlen; - gpg_error_t rc; - - log_debug ("got status line `%s'\n", line); - for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) - ; - while (spacep (line)) - line++; - - if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen)) - { - parm->fprvalid = unhexify_fpr (line, parm->fpr); - } - if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen)) - { - gcry_mpi_t a; - const char *name = line; - - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; - - rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL); - if (rc) - log_error ("error parsing received key data: %s\n", gpg_strerror (rc)); - else if (*name == 'n' && spacep (name+1)) - parm->n = a; - else if (*name == 'e' && spacep (name+1)) - parm->e = a; - else - { - log_info ("unknown parameter name in received key data\n"); - gcry_mpi_release (a); - } - } - else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen)) - { - parm->created_at = (u32)strtoul (line, NULL, 10); - } - - return 0; -} - -/* Send a GENKEY command to the SCdaemon. */ -int -agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (); - if (rc) - return rc; - - memset (info, 0, sizeof *info); - snprintf (line, DIM(line)-1, "SCD GENKEY %s%d", - force? "--force ":"", keyno); - line[DIM(line)-1] = 0; - - memset (info, 0, sizeof *info); - rc = assuan_transact (agent_ctx, line, - NULL, NULL, NULL, NULL, - scd_genkey_cb, info); - - return map_assuan_err (rc); -} - - -static AssuanError -membuf_data_cb (void *opaque, const void *buffer, size_t length) -{ - membuf_t *data = opaque; - - if (buffer) - put_membuf (data, buffer, length); - return 0; -} - -/* Send a sign command to the scdaemon via gpg-agent's pass thru - mechanism. */ -int -agent_scd_pksign (const char *serialno, int hashalgo, - const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen) -{ - int rc, i; - char *p, line[ASSUAN_LINELENGTH]; - membuf_t data; - size_t len; - - /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */ - - *r_buf = NULL; - *r_buflen = 0; - - rc = start_agent (); - if (rc) - return rc; - - if (indatalen*2 + 50 > DIM(line)) - return gpg_error (GPG_ERR_GENERAL); - - sprintf (line, "SCD SETDATA "); - p = line + strlen (line); - for (i=0; i < indatalen ; i++, p += 2 ) - sprintf (p, "%02X", indata[i]); - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - init_membuf (&data, 1024); -#if 0 - if (!hashalgo) /* Temporary test hack. */ - snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno); - else -#endif - snprintf (line, DIM(line)-1, "SCD PKSIGN %s", serialno); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data, - NULL, NULL, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - *r_buf = get_membuf (&data, r_buflen); - - return 0; -} - - -/* Decrypt INDATA of length INDATALEN using the card identified by - SERIALNO. Return the plaintext in a nwly allocated buffer stored - at the address of R_BUF. - - Note, we currently support only RSA or more exactly algorithms - taking one input data element. */ -int -agent_scd_pkdecrypt (const char *serialno, - const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen) -{ - int rc, i; - char *p, line[ASSUAN_LINELENGTH]; - membuf_t data; - size_t len; - - *r_buf = NULL; - rc = start_agent (); - if (rc) - return rc; - - /* FIXME: use secure memory where appropriate */ - if (indatalen*2 + 50 > DIM(line)) - return gpg_error (GPG_ERR_GENERAL); - - sprintf (line, "SCD SETDATA "); - p = line + strlen (line); - for (i=0; i < indatalen ; i++, p += 2 ) - sprintf (p, "%02X", indata[i]); - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - init_membuf (&data, 1024); - snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, - NULL, NULL, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - *r_buf = get_membuf (&data, r_buflen); - if (!*r_buf) - return gpg_error (GPG_ERR_ENOMEM); - - return 0; -} - - -/* Change the PIN of an OpenPGP card or reset the retry counter. - CHVNO 1: Change the PIN - 2: Same as 1 - 3: Change the admin PIN - 101: Set a new PIN and reset the retry counter - 102: Same as 101 - */ -int -agent_scd_change_pin (int chvno) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - const char *reset = ""; - - if (chvno >= 100) - reset = "--reset"; - chvno %= 100; - - rc = start_agent (); - if (rc) - return rc; - - snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, NULL, NULL, - NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - - -/* Perform a CHECKPIN operation. SERIALNO should be the serial - number of the card - optioanlly followed by the fingerprint; - however the fingerprint is ignored here. */ -int -agent_scd_checkpin (const char *serialno) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (); - if (rc) - return rc; - - snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno); - line[DIM(line)-1] = 0; - return assuan_transact (agent_ctx, line, - NULL, NULL, - NULL, NULL, NULL, NULL); -} - - diff --git a/g10/call-agent.h b/g10/call-agent.h deleted file mode 100644 index 875110118..000000000 --- a/g10/call-agent.h +++ /dev/null @@ -1,94 +0,0 @@ -/* call-agent.h - Divert operations to the agent - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef GNUPG_G10_CALL_AGENT_H -#define GNUPG_G10_CALL_AGENT_H - - -struct agent_card_info_s { - int error; /* private. */ - char *serialno; /* malloced hex string. */ - char *disp_name; /* malloced. */ - char *disp_lang; /* malloced. */ - int disp_sex; /* 0 = unspecified, 1 = male, 2 = female */ - char *pubkey_url; /* malloced. */ - char *login_data; /* malloced. */ - char fpr1valid; - char fpr2valid; - char fpr3valid; - char fpr1[20]; - char fpr2[20]; - char fpr3[20]; - unsigned long sig_counter; - int chv1_cached; /* True if a PIN is not required for each - signing. Note that the gpg-agent might cache - it anyway. */ - int chvmaxlen[3]; /* Maximum allowed length of a CHV. */ - int chvretry[3]; /* Allowed retries for the CHV; 0 = blocked. */ -}; - -struct agent_card_genkey_s { - char fprvalid; - char fpr[20]; - u32 created_at; - gcry_mpi_t n; - gcry_mpi_t e; -}; - - -/* Release the card info structure. */ -void agent_release_card_info (struct agent_card_info_s *info); - -/* Return card info. */ -int agent_learn (struct agent_card_info_s *info); - -/* Update INFO with the attribute NAME. */ -int agent_scd_getattr (const char *name, struct agent_card_info_s *info); - -/* Check whether the secret key for the key identified by HEXKEYGRIP - is available. Return 0 for yes or an error code. */ -int agent_havekey (const char *hexkeygrip); - -/* Send a SETATTR command to the SCdaemon. */ -int agent_scd_setattr (const char *name, - const unsigned char *value, size_t valuelen); - -/* Send a GENKEY command to the SCdaemon. */ -int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force); - -/* Send a PKSIGN command to the SCdaemon. */ -int agent_scd_pksign (const char *keyid, int hashalgo, - const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen); - -/* Send a PKDECRYPT command to the SCdaemon. */ -int agent_scd_pkdecrypt (const char *serialno, - const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen); - -/* Change the PIN of an OpenPGP card or reset the retry counter. */ -int agent_scd_change_pin (int chvno); - -/* Send the CHECKPIN command to the SCdaemon. */ -int agent_scd_checkpin (const char *serialno); - - - -#endif /*GNUPG_G10_CALL_AGENT_H*/ - diff --git a/g10/card-util.c b/g10/card-util.c deleted file mode 100644 index c93d028bd..000000000 --- a/g10/card-util.c +++ /dev/null @@ -1,884 +0,0 @@ -/* card-util.c - Utility functions for the OpenPGP card. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#if GNUPG_MAJOR_VERSION != 1 -#include "gpg.h" -#endif -#include "util.h" -#include "i18n.h" -#include "ttyio.h" -#include "status.h" -#include "options.h" -#include "main.h" -#if GNUPG_MAJOR_VERSION == 1 -#include "cardglue.h" -#else -#include "call-agent.h" -#endif - -#define CONTROL_D ('D' - 'A' + 1) - - -/* Change the PIN of a an OpenPGP card. This is an interactive - function. */ -void -change_pin (int chvno) -{ - struct agent_card_info_s info; - int rc; - - rc = agent_learn (&info); - if (rc) - { - log_error (_("OpenPGP card not available: %s\n"), - gpg_strerror (rc)); - return; - } - - log_info (_("OpenPGP card no. %s detected\n"), - info.serialno? info.serialno : "[none]"); - - agent_release_card_info (&info); - - if (opt.batch) - { - log_error (_("sorry, can't do this in batch mode\n")); - return; - } - - for (;;) - { - char *answer; - - tty_printf ("\n"); - tty_printf ("1 - change PIN\n" - "2 - unblock PIN\n" - "3 - change Admin PIN\n" - "Q - quit\n"); - tty_printf ("\n"); - - answer = cpr_get("cardutil.change_pin.menu",_("Your selection? ")); - cpr_kill_prompt(); - if (strlen (answer) != 1) - continue; - - rc = 0; - if (*answer == '1') - { - rc = agent_scd_change_pin (1); - if (rc) - tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); - else - tty_printf ("PIN changed.\n"); - } - else if (*answer == '2') - { - rc = agent_scd_change_pin (101); - if (rc) - tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc)); - else - tty_printf ("PIN unblocked and new PIN set.\n"); - } - else if (*answer == '3') - { - rc = agent_scd_change_pin (3); - if (rc) - tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); - else - tty_printf ("PIN changed.\n"); - } - else if (*answer == 'q' || *answer == 'Q') - { - break; - } - } -} - -static const char * -get_manufacturer (unsigned int no) -{ - /* Note: Make sure that there is no colon or linefeed in the string. */ - switch (no) - { - case 0: - case 0xffff: return "test card"; - case 0x0001: return "PPC Card Systems"; - default: return "unknown"; - } -} - - -static void -print_sha1_fpr (FILE *fp, const unsigned char *fpr) -{ - int i; - - if (fpr) - { - for (i=0; i < 20 ; i+=2, fpr += 2 ) - { - if (i == 10 ) - tty_fprintf (fp, " "); - tty_fprintf (fp, " %02X%02X", *fpr, fpr[1]); - } - } - else - tty_fprintf (fp, " [none]"); - tty_fprintf (fp, "\n"); -} - - -static void -print_sha1_fpr_colon (FILE *fp, const unsigned char *fpr) -{ - int i; - - if (fpr) - { - for (i=0; i < 20 ; i++, fpr++) - fprintf (fp, "%02X", *fpr); - } - putc (':', fp); -} - - -static void -print_name (FILE *fp, const char *text, const char *name) -{ - tty_fprintf (fp, "%s", text); - - /* FIXME: tty_printf_utf8_string2 eats everything after and - including an @ - e.g. when printing an url. */ - if (name && *name) - { - if (fp) - print_utf8_string2 (fp, name, strlen (name), '\n'); - else - tty_print_utf8_string2 (name, strlen (name), 0); - } - else - tty_fprintf (fp, _("[not set]")); - tty_fprintf (fp, "\n"); -} - -static void -print_isoname (FILE *fp, const char *text, const char *tag, const char *name) -{ - if (opt.with_colons) - fprintf (fp, "%s:", tag); - else - tty_fprintf (fp, "%s", text); - - if (name && *name) - { - char *p, *given, *buf = xstrdup (name); - - given = strstr (buf, "<<"); - for (p=buf; *p; p++) - if (*p == '<') - *p = ' '; - if (given && given[2]) - { - *given = 0; - given += 2; - if (opt.with_colons) - print_string (fp, given, strlen (given), ':'); - else if (fp) - print_utf8_string2 (fp, given, strlen (given), '\n'); - else - tty_print_utf8_string2 (given, strlen (given), 0); - - if (opt.with_colons) - putc (':', fp); - else if (*buf) - tty_fprintf (fp, " "); - } - - if (opt.with_colons) - print_string (fp, buf, strlen (buf), ':'); - else if (fp) - print_utf8_string2 (fp, buf, strlen (buf), '\n'); - else - tty_print_utf8_string2 (buf, strlen (buf), 0); - xfree (buf); - } - else - { - if (opt.with_colons) - putc (':', fp); - else - tty_fprintf (fp, _("[not set]")); - } - - if (opt.with_colons) - fputs (":\n", fp); - else - tty_fprintf (fp, "\n"); -} - -/* Return true if the SHA1 fingerprint FPR consists only of zeroes. */ -static int -fpr_is_zero (const char *fpr) -{ - int i; - - for (i=0; i < 20 && !fpr[i]; i++) - ; - return (i == 20); -} - - -/* Print all available information about the current card. */ -void -card_status (FILE *fp, char *serialno, size_t serialnobuflen) -{ - struct agent_card_info_s info; - PKT_public_key *pk = xcalloc (1, sizeof *pk); - int rc; - unsigned int uval; - - if (serialno && serialnobuflen) - *serialno = 0; - - rc = agent_learn (&info); - if (rc) - { - if (opt.with_colons) - fputs ("AID:::\n", fp); - log_error (_("OpenPGP card not available: %s\n"), - gpg_strerror (rc)); - xfree (pk); - return; - } - - if (opt.with_colons) - fprintf (fp, "AID:%s:", info.serialno? info.serialno : ""); - else - tty_fprintf (fp, "Application ID ...: %s\n", - info.serialno? info.serialno : "[none]"); - if (!info.serialno || strncmp (info.serialno, "D27600012401", 12) - || strlen (info.serialno) != 32 ) - { - if (opt.with_colons) - fputs ("unknown:\n", fp); - log_info ("not an OpenPGP card\n"); - agent_release_card_info (&info); - xfree (pk); - return; - } - - if (!serialno) - ; - else if (strlen (serialno)+1 > serialnobuflen) - log_error ("serial number longer than expected\n"); - else - strcpy (serialno, info.serialno); - - if (opt.with_colons) - fputs ("openpgp-card:\n", fp); - - - if (opt.with_colons) - { - fprintf (fp, "version:%.4s:\n", info.serialno+12); - uval = xtoi_2(info.serialno+16)*256 + xtoi_2 (info.serialno+18); - fprintf (fp, "vendor:%04x:%s:\n", uval, get_manufacturer (uval)); - fprintf (fp, "serial:%.8s:\n", info.serialno+20); - - print_isoname (fp, "Name of cardholder: ", "name", info.disp_name); - - fputs ("lang:", fp); - if (info.disp_lang) - print_string (fp, info.disp_lang, strlen (info.disp_lang), ':'); - fputs (":\n", fp); - - fprintf (fp, "sex:%c:\n", (info.disp_sex == 1? 'm': - info.disp_sex == 2? 'f' : 'u')); - - fputs ("url:", fp); - if (info.pubkey_url) - print_string (fp, info.pubkey_url, strlen (info.pubkey_url), ':'); - fputs (":\n", fp); - - fputs ("login:", fp); - if (info.login_data) - print_string (fp, info.login_data, strlen (info.login_data), ':'); - fputs (":\n", fp); - - fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached); - fprintf (fp, "maxpinlen:%d:%d:%d:\n", - info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]); - fprintf (fp, "pinretry:%d:%d:%d:\n", - info.chvretry[0], info.chvretry[1], info.chvretry[2]); - fprintf (fp, "sigcount:%lu:::\n", info.sig_counter); - - fputs ("fpr:", fp); - print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL); - print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL); - print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL); - putc ('\n', fp); - - } - else - { - tty_fprintf (fp, "Version ..........: %.1s%c.%.1s%c\n", - info.serialno[12] == '0'?"":info.serialno+12, - info.serialno[13], - info.serialno[14] == '0'?"":info.serialno+14, - info.serialno[15]); - tty_fprintf (fp, "Manufacturer .....: %s\n", - get_manufacturer (xtoi_2(info.serialno+16)*256 - + xtoi_2 (info.serialno+18))); - tty_fprintf (fp, "Serial number ....: %.8s\n", info.serialno+20); - - print_isoname (fp, "Name of cardholder: ", "name", info.disp_name); - print_name (fp, "Language prefs ...: ", info.disp_lang); - tty_fprintf (fp, "Sex ..............: %s\n", - info.disp_sex == 1? _("male"): - info.disp_sex == 2? _("female") : _("unspecified")); - print_name (fp, "URL of public key : ", info.pubkey_url); - print_name (fp, "Login data .......: ", info.login_data); - tty_fprintf (fp, "Signature PIN ....: %s\n", - info.chv1_cached? _("not forced"): _("forced")); - tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n", - info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]); - tty_fprintf (fp, "PIN retry counter : %d %d %d\n", - info.chvretry[0], info.chvretry[1], info.chvretry[2]); - tty_fprintf (fp, "Signature counter : %lu\n", info.sig_counter); - tty_fprintf (fp, "Signature key ....:"); - print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL); - tty_fprintf (fp, "Encryption key....:"); - print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL); - tty_fprintf (fp, "Authentication key:"); - print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL); - tty_fprintf (fp, "General key info..: "); - if (info.fpr1valid && !get_pubkey_byfprint (pk, info.fpr1, 20)) - print_pubkey_info (fp, pk); - else - tty_fprintf (fp, "[none]\n"); - } - - free_public_key (pk); - agent_release_card_info (&info); -} - - -static char * -get_one_name (const char *prompt1, const char *prompt2) -{ - char *name; - int i; - - for (;;) - { - name = cpr_get (prompt1, prompt2); - if (!name) - return NULL; - trim_spaces (name); - cpr_kill_prompt (); - for (i=0; name[i] && name[i] >= ' ' && name[i] <= 126; i++) - ; - - /* The name must be in Latin-1 and not UTF-8 - lacking the code - to ensure this we restrict it to ASCII. */ - if (name[i]) - tty_printf (_("Error: Only plain ASCII is currently allowed.\n")); - else if (strchr (name, '<')) - tty_printf (_("Error: The \"<\" character may not be used.\n")); - else if (strstr (name, " ")) - tty_printf (_("Error: Double spaces are not allowed.\n")); - else - return name; - xfree (name); - } -} - - - -static int -change_name (void) -{ - char *surname = NULL, *givenname = NULL; - char *isoname, *p; - int rc; - - surname = get_one_name ("keygen.smartcard.surname", - _("Cardholder's surname: ")); - givenname = get_one_name ("keygen.smartcard.givenname", - _("Cardholder's given name: ")); - if (!surname || !givenname || (!*surname && !*givenname)) - { - xfree (surname); - xfree (givenname); - return -1; /*canceled*/ - } - - isoname = xmalloc ( strlen (surname) + 2 + strlen (givenname) + 1); - strcpy (stpcpy (stpcpy (isoname, surname), "<<"), givenname); - xfree (surname); - xfree (givenname); - for (p=isoname; *p; p++) - if (*p == ' ') - *p = '<'; - - if (strlen (isoname) > 39 ) - { - tty_printf (_("Error: Combined name too long " - "(limit is %d characters).\n"), 39); - xfree (isoname); - return -1; - } - - log_debug ("setting Name to `%s'\n", isoname); - rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname) ); - if (rc) - log_error ("error setting Name: %s\n", gpg_strerror (rc)); - - xfree (isoname); - return rc; -} - - -static int -change_url (void) -{ - char *url; - int rc; - - url = cpr_get ("cardedit.change_url", _("URL to retrieve public key: ")); - if (!url) - return -1; - trim_spaces (url); - cpr_kill_prompt (); - - if (strlen (url) > 254 ) - { - tty_printf (_("Error: URL too long " - "(limit is %d characters).\n"), 254); - xfree (url); - return -1; - } - - rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url) ); - if (rc) - log_error ("error setting URL: %s\n", gpg_strerror (rc)); - xfree (url); - return rc; -} - -static int -change_login (void) -{ - char *data; - int rc; - - data = cpr_get ("cardedit.change_login", - _("Login data (account name): ")); - if (!data) - return -1; - trim_spaces (data); - cpr_kill_prompt (); - - if (strlen (data) > 254 ) - { - tty_printf (_("Error: Login data too long " - "(limit is %d characters).\n"), 254); - xfree (data); - return -1; - } - - rc = agent_scd_setattr ("LOGIN-DATA", data, strlen (data) ); - if (rc) - log_error ("error setting login data: %s\n", gpg_strerror (rc)); - xfree (data); - return rc; -} - -static int -change_lang (void) -{ - char *data, *p; - int rc; - - data = cpr_get ("cardedit.change_lang", - _("Language preferences: ")); - if (!data) - return -1; - trim_spaces (data); - cpr_kill_prompt (); - - if (strlen (data) > 8 || (strlen (data) & 1)) - { - tty_printf (_("Error: invalid length of preference string.\n")); - xfree (data); - return -1; - } - - for (p=data; *p && *p >= 'a' && *p <= 'z'; p++) - ; - if (*p) - { - tty_printf (_("Error: invalid characters in preference string.\n")); - xfree (data); - return -1; - } - - rc = agent_scd_setattr ("DISP-LANG", data, strlen (data) ); - if (rc) - log_error ("error setting lang: %s\n", gpg_strerror (rc)); - xfree (data); - return rc; -} - - -static int -change_sex (void) -{ - char *data; - const char *str; - int rc; - - data = cpr_get ("cardedit.change_sex", - _("Sex ((M)ale, (F)emale or space): ")); - if (!data) - return -1; - trim_spaces (data); - cpr_kill_prompt (); - - if (!*data) - str = "9"; - else if ((*data == 'M' || *data == 'm') && !data[1]) - str = "1"; - else if ((*data == 'F' || *data == 'f') && !data[1]) - str = "2"; - else - { - tty_printf (_("Error: invalid response.\n")); - xfree (data); - return -1; - } - - rc = agent_scd_setattr ("DISP-SEX", str, 1 ); - if (rc) - log_error ("error setting sex: %s\n", gpg_strerror (rc)); - xfree (data); - return rc; -} - - -static void -toggle_forcesig (void) -{ - struct agent_card_info_s info; - int rc; - int newstate; - - memset (&info, 0, sizeof info); - rc = agent_scd_getattr ("CHV-STATUS", &info); - if (rc) - { - log_error ("error getting current status: %s\n", gpg_strerror (rc)); - return; - } - newstate = !info.chv1_cached; - agent_release_card_info (&info); - - rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1); - if (rc) - log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc)); -} - - -static void -generate_card_keys (const char *serialno) -{ - struct agent_card_info_s info; - int rc; - int forced_chv1; - - memset (&info, 0, sizeof info); - rc = agent_scd_getattr ("KEY-FPR", &info); - if (!rc) - rc = agent_scd_getattr ("SERIALNO", &info); - if (!rc) - rc = agent_scd_getattr ("CHV-STATUS", &info); - if (!rc) - rc = agent_scd_getattr ("DISP-NAME", &info); - if (rc) - { - log_error ("error getting current key info: %s\n", gpg_strerror (rc)); - return; - } - if ( (info.fpr1valid && !fpr_is_zero (info.fpr1)) - || (info.fpr2valid && !fpr_is_zero (info.fpr2)) - || (info.fpr3valid && !fpr_is_zero (info.fpr3))) - { - tty_printf ("\n"); - log_info ("NOTE: keys are already stored on the card!\n"); - tty_printf ("\n"); - if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_keys", - _("Replace existing keys? "))) - { - agent_release_card_info (&info); - return; - } - } - else if (!info.disp_name || !*info.disp_name) - { - tty_printf ("\n"); - tty_printf (_("Please note that the factory settings of the PINs are\n" - " PIN = \"%s\" Admin PIN = \"%s\"\n" - "You should change them using the command --change-pin\n"), - "123456", "12345678"); - tty_printf ("\n"); - } - - forced_chv1 = !info.chv1_cached; - if (forced_chv1) - { /* Switch of the forced mode so that during key generation we - don't get bothered with PIN queries for each - self-signature. */ - rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1); - if (rc) - { - log_error ("error clearing forced signature PIN flag: %s\n", - gpg_strerror (rc)); - return; - } - } - - /* Check the PIN now, so that we won't get asked later for each - binding signature. */ - rc = agent_scd_checkpin (serialno); - if (rc) - log_error ("error checking the PIN: %s\n", gpg_strerror (rc)); - else - generate_keypair (NULL, info.serialno); - - agent_release_card_info (&info); - if (forced_chv1) - { /* Switch back to forced state. */ - rc = agent_scd_setattr ("CHV-STATUS-1", "", 1); - if (rc) - { - log_error ("error setting forced signature PIN flag: %s\n", - gpg_strerror (rc)); - return; - } - } -} - -/* Menu to edit all user changeable values on an OpenPGP card. Only - Key creation is not handled here. */ -void -card_edit (STRLIST commands) -{ - enum cmdids { - cmdNOP = 0, - cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG, - cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX, - cmdFORCESIG, cmdGENERATE, cmdPASSWD, - cmdINVCMD - }; - - static struct { - const char *name; - enum cmdids id; - const char *desc; - } cmds[] = { - { N_("quit") , cmdQUIT , N_("quit this menu") }, - { N_("q") , cmdQUIT , NULL }, - { N_("help") , cmdHELP , N_("show this help") }, - { "?" , cmdHELP , NULL }, - { N_("list") , cmdLIST , N_("list all available data") }, - { N_("l") , cmdLIST , NULL }, - { N_("debug") , cmdDEBUG , NULL }, - { N_("name") , cmdNAME , N_("change card holder's name") }, - { N_("url") , cmdURL , N_("change URL to retrieve key") }, - { N_("login") , cmdLOGIN , N_("change the login name") }, - { N_("lang") , cmdLANG , N_("change the language preferences") }, - { N_("sex") , cmdSEX , N_("change card holder's sex") }, - { N_("forcesig"), - cmdFORCESIG, N_("toggle the signature force PIN flag") }, - { N_("generate"), - cmdGENERATE, N_("generate new keys") }, - { N_("passwd"), cmdPASSWD, N_("menu to change or unblock the PIN") }, - { NULL, cmdINVCMD } - }; - - enum cmdids cmd = cmdNOP; - int have_commands = !!commands; - int redisplay = 1; - char *answer = NULL; - int did_checkpin = 0; - char serialnobuf[50]; - - - if (opt.command_fd != -1) - ; - else if (opt.batch && !have_commands) - { - log_error(_("can't do that in batchmode\n")); - goto leave; - } - - for (;;) - { - int arg_number; - const char *arg_string = ""; - char *p; - int i; - - tty_printf("\n"); - if (redisplay ) - { - if (opt.with_colons) - { - card_status (stdout, serialnobuf, DIM (serialnobuf)); - fflush (stdout); - } - else - { - card_status (NULL, serialnobuf, DIM (serialnobuf)); - tty_printf("\n"); - } - redisplay = 0; - } - - do - { - xfree (answer); - if (have_commands) - { - if (commands) - { - answer = xstrdup (commands->d); - commands = commands->next; - } - else if (opt.batch) - { - answer = xstrdup ("quit"); - } - else - have_commands = 0; - } - - if (!have_commands) - { - answer = cpr_get_no_help("cardedit.prompt", _("Command> ")); - cpr_kill_prompt(); - } - trim_spaces(answer); - } - while( *answer == '#' ); - - arg_number = 0; /* Yes, here is the init which egcc complains about */ - if (!*answer) - cmd = cmdLIST; /* Default to the list command */ - else if (*answer == CONTROL_D) - cmd = cmdQUIT; - else { - if ((p=strchr (answer,' '))) - { - *p++ = 0; - trim_spaces (answer); - trim_spaces (p); - arg_number = atoi(p); - arg_string = p; - } - - for (i=0; cmds[i].name; i++ ) - if (!ascii_strcasecmp (answer, cmds[i].name )) - break; - - cmd = cmds[i].id; - } - - - switch (cmd) - { - case cmdHELP: - for (i=0; cmds[i].name; i++ ) - if (cmds[i].desc) - tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) ); - break; - - case cmdLIST: - redisplay = 1; - break; - - case cmdNAME: - change_name (); - break; - - case cmdURL: - change_url (); - break; - - case cmdLOGIN: - change_login (); - break; - - case cmdLANG: - change_lang (); - break; - - case cmdSEX: - change_sex (); - break; - - case cmdFORCESIG: - toggle_forcesig (); - break; - - case cmdGENERATE: - generate_card_keys (serialnobuf); - break; - - case cmdPASSWD: - change_pin (0); - did_checkpin = 0; /* Need to reset it of course. */ - break; - - case cmdQUIT: - goto leave; - - case cmdNOP: - break; - - case cmdINVCMD: - default: - tty_printf ("\n"); - tty_printf (_("Invalid command (try \"help\")\n")); - break; - } /* End command switch. */ - } /* End of main menu loop. */ - - leave: - xfree (answer); -} - diff --git a/g10/cipher.c b/g10/cipher.c deleted file mode 100644 index 3d51a874a..000000000 --- a/g10/cipher.c +++ /dev/null @@ -1,165 +0,0 @@ -/* cipher.c - En-/De-ciphering filter - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "filter.h" -#include "packet.h" -#include "options.h" -#include "main.h" -#include "status.h" - - -#define MIN_PARTIAL_SIZE 512 - - -static void -write_header( cipher_filter_context_t *cfx, iobuf_t a ) -{ - PACKET pkt; - PKT_encrypted ed; - byte temp[18]; - unsigned int blocksize; - unsigned int nprefix; - gpg_error_t rc; - - blocksize = gcry_cipher_get_algo_blklen ( cfx->dek->algo ); - if( blocksize < 8 || blocksize > 16 ) - log_fatal("unsupported blocksize %u\n", blocksize ); - - memset( &ed, 0, sizeof ed ); - ed.len = cfx->datalen; - ed.extralen = blocksize+2; - ed.new_ctb = !ed.len && !RFC1991; - if( cfx->dek->use_mdc ) { - ed.mdc_method = DIGEST_ALGO_SHA1; - gcry_md_open (&cfx->mdc_hash, GCRY_MD_SHA1, 0 ); - if ( DBG_HASHING ) - gcry_md_start_debug ( cfx->mdc_hash, "creatmdc" ); - } - - { - char buf[20]; - - sprintf (buf, "%d %d", ed.mdc_method, cfx->dek->algo); - write_status_text (STATUS_BEGIN_ENCRYPTION, buf); - } - - init_packet( &pkt ); - pkt.pkttype = cfx->dek->use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED; - pkt.pkt.encrypted = &ed; - if( build_packet( a, &pkt )) - log_bug("build_packet(ENCR_DATA) failed\n"); - nprefix = blocksize; - gcry_randomize ( temp, nprefix, GCRY_STRONG_RANDOM); - temp[nprefix] = temp[nprefix-2]; - temp[nprefix+1] = temp[nprefix-1]; - print_cipher_algo_note( cfx->dek->algo ); - rc = gcry_cipher_open (&cfx->cipher_hd, cfx->dek->algo, - GCRY_CIPHER_MODE_CFB, - GCRY_CIPHER_SECURE - | ((cfx->dek->use_mdc || cfx->dek->algo >= 100) ? - 0 : GCRY_CIPHER_ENABLE_SYNC)); - if (rc) { - /* we should never get an error here cause we already checked, that - * the algorithm is available. */ - BUG(); - } -/* log_hexdump( "thekey", cfx->dek->key, cfx->dek->keylen );*/ - gcry_cipher_setkey( cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen ); - gcry_cipher_setiv( cfx->cipher_hd, NULL, 0 ); -/* log_hexdump( "prefix", temp, nprefix+2 ); */ - if( cfx->mdc_hash ) /* hash the "IV" */ - gcry_md_write( cfx->mdc_hash, temp, nprefix+2 ); - gcry_cipher_encrypt( cfx->cipher_hd, temp, nprefix+2, NULL, 0); - gcry_cipher_sync( cfx->cipher_hd ); - iobuf_write(a, temp, nprefix+2); - cfx->header=1; -} - - - -/**************** - * This filter is used to en/de-cipher data with a conventional algorithm - */ -int -cipher_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - cipher_filter_context_t *cfx = opaque; - int rc=0; - - if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */ - rc = -1; /* not yet used */ - } - else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */ - assert(a); - if( !cfx->header ) { - write_header( cfx, a ); - } - if( cfx->mdc_hash ) - gcry_md_write( cfx->mdc_hash, buf, size ); - gcry_cipher_encrypt( cfx->cipher_hd, buf, size, NULL, 0); - rc = iobuf_write( a, buf, size ); - } - else if( control == IOBUFCTRL_FREE ) { - if( cfx->mdc_hash ) { - byte *hash; - int hashlen = gcry_md_get_algo_dlen (gcry_md_get_algo ( - cfx->mdc_hash)); - byte temp[22]; - - assert( hashlen == 20 ); - /* we must hash the prefix of the MDC packet here */ - temp[0] = 0xd3; - temp[1] = 0x14; - gcry_md_putc ( cfx->mdc_hash, temp[0] ); - gcry_md_putc ( cfx->mdc_hash, temp[1] ); - - gcry_md_final ( cfx->mdc_hash ); - hash = gcry_md_read ( cfx->mdc_hash, 0 ); - memcpy(temp+2, hash, 20); - gcry_cipher_encrypt( cfx->cipher_hd, temp, 22, NULL, 0 ); - gcry_md_close ( cfx->mdc_hash ); cfx->mdc_hash = NULL; - rc = iobuf_write( a, temp, 22 ); - if (rc) - log_error("writing MDC packet failed\n" ); - } - gcry_cipher_close (cfx->cipher_hd); - } - else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "cipher_filter"; - } - return rc; -} - - - diff --git a/g10/comment.c b/g10/comment.c deleted file mode 100644 index b52104cd7..000000000 --- a/g10/comment.c +++ /dev/null @@ -1,112 +0,0 @@ -/* comment.c - write comment stuff - * Copyright (C) 1998, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "keydb.h" - - - -int -write_comment( iobuf_t out, const char *s ) -{ - PACKET pkt; - size_t n = strlen(s); - int rc=0; - - pkt.pkttype = PKT_COMMENT; - if( *s != '#' ) { - pkt.pkt.comment = xmalloc ( sizeof *pkt.pkt.comment + n ); - pkt.pkt.comment->len = n+1; - *pkt.pkt.comment->data = '#'; - strcpy(pkt.pkt.comment->data+1, s); - } - else { - pkt.pkt.comment = xmalloc ( sizeof *pkt.pkt.comment + n - 1 ); - pkt.pkt.comment->len = n; - strcpy(pkt.pkt.comment->data, s); - } - if( (rc = build_packet( out, &pkt )) ) - log_error("build_packet(comment) failed: %s\n", gpg_strerror (rc) ); - free_packet( &pkt ); - return rc; -} - - -KBNODE -make_comment_node_from_buffer (const char *s, size_t n) -{ - PACKET *pkt; - - pkt = gcry_xcalloc( 1, sizeof *pkt ); - pkt->pkttype = PKT_COMMENT; - pkt->pkt.comment = gcry_xmalloc( sizeof *pkt->pkt.comment + n - 1 ); - pkt->pkt.comment->len = n; - strcpy(pkt->pkt.comment->data, s); - return new_kbnode( pkt ); -} - -KBNODE -make_comment_node( const char *s ) -{ - return make_comment_node_from_buffer (s, strlen (s)); -} - - -KBNODE -make_mpi_comment_node( const char *s, gcry_mpi_t a ) -{ - PACKET *pkt; - byte *buf, *pp; - size_t n1, nb1; - size_t n = strlen(s); - - nb1 = mpi_get_nbits( a ); - if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &n1, a)) - BUG (); - /* fixme: allocate it on the stack */ - buf = xmalloc (n1); - if (gcry_mpi_print (GCRYMPI_FMT_PGP, buf, n1, &n1, a)) - BUG (); - - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_COMMENT; - pkt->pkt.comment = xmalloc ( sizeof *pkt->pkt.comment + n + 2 + n1 ); - pkt->pkt.comment->len = n+1+2+n1; - pp = pkt->pkt.comment->data; - memcpy(pp, s, n+1); - memcpy(pp+n+1, buf, n1 ); - xfree (buf); - return new_kbnode( pkt ); -} - - diff --git a/g10/compress.c b/g10/compress.c deleted file mode 100644 index 7dce1790a..000000000 --- a/g10/compress.c +++ /dev/null @@ -1,329 +0,0 @@ -/* compress.c - compress filter - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <assert.h> -#include <errno.h> -#include <zlib.h> -#ifdef __riscos__ -# include "zlib-riscos.h" -#endif - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "packet.h" -#include "filter.h" -#include "main.h" -#include "options.h" - -static void -init_compress( compress_filter_context_t *zfx, z_stream *zs ) -{ - int rc; - int level; - -#ifdef __riscos__ - static int zlib_initialized = 0; - - if (!zlib_initialized) - zlib_initialized = riscos_load_module("ZLib", zlib_path, 1); -#endif - - if( opt.compress >= 0 && opt.compress <= 9 ) - level = opt.compress; - else if( opt.compress == -1 ) - level = Z_DEFAULT_COMPRESSION; - else if( opt.compress == 10 ) /* remove this ! */ - level = 0; - else { - log_error("invalid compression level; using default level\n"); - level = Z_DEFAULT_COMPRESSION; - } - - - if( (rc = zfx->algo == 1? deflateInit2( zs, level, Z_DEFLATED, - -13, 8, Z_DEFAULT_STRATEGY) - : deflateInit( zs, level ) - ) != Z_OK ) { - log_fatal("zlib problem: %s\n", zs->msg? zs->msg : - rc == Z_MEM_ERROR ? "out of core" : - rc == Z_VERSION_ERROR ? "invalid lib version" : - "unknown error" ); - } - - zfx->outbufsize = 8192; - zfx->outbuf = xmalloc ( zfx->outbufsize ); -} - -static int -do_compress( compress_filter_context_t *zfx, z_stream *zs, int flush, iobuf_t a ) -{ - gpg_error_t rc; - int zrc; - unsigned n; - - do { -#ifndef __riscos__ - zs->next_out = zfx->outbuf; -#else /* __riscos__ */ - zs->next_out = (Bytef *) zfx->outbuf; -#endif /* __riscos__ */ - zs->avail_out = zfx->outbufsize; - if( DBG_FILTER ) - log_debug("enter deflate: avail_in=%u, avail_out=%u, flush=%d\n", - (unsigned)zs->avail_in, (unsigned)zs->avail_out, flush ); - zrc = deflate( zs, flush ); - if( zrc == Z_STREAM_END && flush == Z_FINISH ) - ; - else if( zrc != Z_OK ) { - if( zs->msg ) - log_fatal("zlib deflate problem: %s\n", zs->msg ); - else - log_fatal("zlib deflate problem: rc=%d\n", zrc ); - } - n = zfx->outbufsize - zs->avail_out; - if( DBG_FILTER ) - log_debug("leave deflate: " - "avail_in=%u, avail_out=%u, n=%u, zrc=%d\n", - (unsigned)zs->avail_in, (unsigned)zs->avail_out, - (unsigned)n, zrc ); - - rc = iobuf_write (a, zfx->outbuf, n); - if (rc) - { - log_debug("deflate: iobuf_write failed\n"); - return rc; - } - } while( zs->avail_in || (flush == Z_FINISH && zrc != Z_STREAM_END) ); - return 0; -} - -static void -init_uncompress( compress_filter_context_t *zfx, z_stream *zs ) -{ - int rc; - - /**************** - * PGP uses a windowsize of 13 bits. Using a negative value for - * it forces zlib not to expect a zlib header. This is a - * undocumented feature Peter Gutmann told me about. - * - * We must use 15 bits for the inflator because CryptoEx uses 15 - * bits thus the output would get scrambled w/o error indication - * if we would use 13 bits. For the uncompressing this does not - * matter at all. - */ - if( (rc = zfx->algo == 1? inflateInit2( zs, -15) - : inflateInit( zs )) != Z_OK ) { - log_fatal("zlib problem: %s\n", zs->msg? zs->msg : - rc == Z_MEM_ERROR ? "out of core" : - rc == Z_VERSION_ERROR ? "invalid lib version" : - "unknown error" ); - } - - zfx->inbufsize = 2048; - zfx->inbuf = xmalloc ( zfx->inbufsize ); - zs->avail_in = 0; -} - -static int -do_uncompress( compress_filter_context_t *zfx, z_stream *zs, - iobuf_t a, size_t *ret_len ) -{ - int zrc; - int rc=0; - size_t n; - int nread, count; - int refill = !zs->avail_in; - - if( DBG_FILTER ) - log_debug("begin inflate: avail_in=%u, avail_out=%u, inbuf=%u\n", - (unsigned)zs->avail_in, (unsigned)zs->avail_out, - (unsigned)zfx->inbufsize ); - do { - if( zs->avail_in < zfx->inbufsize && refill ) { - n = zs->avail_in; - if( !n ) -#ifndef __riscos__ - zs->next_in = zfx->inbuf; -#else /* __riscos__ */ - zs->next_in = (Bytef *) zfx->inbuf; -#endif /* __riscos__ */ - count = zfx->inbufsize - n; - nread = iobuf_read( a, zfx->inbuf + n, count ); - if( nread == -1 ) nread = 0; - n += nread; - /* If we use the undocumented feature to suppress - * the zlib header, we have to give inflate an - * extra dummy byte to read */ - if( nread < count && zfx->algo == 1 ) { - *(zfx->inbuf + n) = 0xFF; /* is it really needed ? */ - zfx->algo1hack = 1; - n++; - } - zs->avail_in = n; - } - refill = 1; - if( DBG_FILTER ) - log_debug("enter inflate: avail_in=%u, avail_out=%u\n", - (unsigned)zs->avail_in, (unsigned)zs->avail_out); -#ifdef Z_SYNC_FLUSH - zrc = inflate( zs, Z_SYNC_FLUSH ); -#else - zrc = inflate( zs, Z_PARTIAL_FLUSH ); -#endif - if( DBG_FILTER ) - log_debug("leave inflate: avail_in=%u, avail_out=%u, zrc=%d\n", - (unsigned)zs->avail_in, (unsigned)zs->avail_out, zrc); - if( zrc == Z_STREAM_END ) - rc = -1; /* eof */ - else if( zrc != Z_OK && zrc != Z_BUF_ERROR ) { - if( zs->msg ) - log_fatal("zlib inflate problem: %s\n", zs->msg ); - else - log_fatal("zlib inflate problem: rc=%d\n", zrc ); - } - } while( zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR ); - *ret_len = zfx->outbufsize - zs->avail_out; - if( DBG_FILTER ) - log_debug("do_uncompress: returning %u bytes\n", (unsigned)*ret_len ); - return rc; -} - -int -compress_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - compress_filter_context_t *zfx = opaque; - z_stream *zs = zfx->opaque; - int rc=0; - - if( control == IOBUFCTRL_UNDERFLOW ) { - if( !zfx->status ) { - zs = zfx->opaque = xcalloc (1, sizeof *zs ); - init_uncompress( zfx, zs ); - zfx->status = 1; - } - -#ifndef __riscos__ - zs->next_out = buf; -#else /* __riscos__ */ - zs->next_out = (Bytef *) buf; -#endif /* __riscos__ */ - zs->avail_out = size; - zfx->outbufsize = size; /* needed only for calculation */ - rc = do_uncompress( zfx, zs, a, ret_len ); - } - else if( control == IOBUFCTRL_FLUSH ) { - if( !zfx->status ) { - PACKET pkt; - PKT_compressed cd; - - if( !zfx->algo ) - zfx->algo = DEFAULT_COMPRESS_ALGO; - if( zfx->algo != 1 && zfx->algo != 2 ) - BUG(); - memset( &cd, 0, sizeof cd ); - cd.len = 0; - cd.algorithm = zfx->algo; - init_packet( &pkt ); - pkt.pkttype = PKT_COMPRESSED; - pkt.pkt.compressed = &cd; - if( build_packet( a, &pkt )) - log_bug("build_packet(PKT_COMPRESSED) failed\n"); - zs = zfx->opaque = xcalloc (1, sizeof *zs ); - init_compress( zfx, zs ); - zfx->status = 2; - } - -#ifndef __riscos__ - zs->next_in = buf; -#else /* __riscos__ */ - zs->next_in = (Bytef *) buf; -#endif /* __riscos__ */ - zs->avail_in = size; - rc = do_compress( zfx, zs, Z_NO_FLUSH, a ); - } - else if( control == IOBUFCTRL_FREE ) { - if( zfx->status == 1 ) { - inflateEnd(zs); - xfree (zs); - zfx->opaque = NULL; - xfree (zfx->outbuf); zfx->outbuf = NULL; - } - else if( zfx->status == 2 ) { -#ifndef __riscos__ - zs->next_in = buf; -#else /* __riscos__ */ - zs->next_in = (Bytef *) buf; -#endif /* __riscos__ */ - zs->avail_in = 0; - do_compress( zfx, zs, Z_FINISH, a ); - deflateEnd(zs); - xfree (zs); - zfx->opaque = NULL; - xfree (zfx->outbuf); zfx->outbuf = NULL; - } - if (zfx->release) - zfx->release (zfx); - } - else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "compress_filter"; - return rc; -} - - -static void -release_context (compress_filter_context_t *ctx) -{ - xfree (ctx); -} - -/**************** - * Handle a compressed packet - */ -int -handle_compressed( void *procctx, PKT_compressed *cd, - int (*callback)(iobuf_t, void *), void *passthru ) -{ - compress_filter_context_t *cfx; - int rc; - - if( cd->algorithm < 1 || cd->algorithm > 2 ) - return GPG_ERR_COMPR_ALGO; - cfx = xcalloc (1,sizeof *cfx); - cfx->algo = cd->algorithm; - cfx->release = release_context; - iobuf_push_filter( cd->buf, compress_filter, cfx ); - if( callback ) - rc = callback(cd->buf, passthru ); - else - rc = proc_packets(procctx, cd->buf); - cd->buf = NULL; - return rc; -} - diff --git a/g10/dearmor.c b/g10/dearmor.c deleted file mode 100644 index 4f9fa2db7..000000000 --- a/g10/dearmor.c +++ /dev/null @@ -1,123 +0,0 @@ -/* dearmor.c - Armor utility - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "filter.h" -#include "packet.h" -#include "options.h" -#include "main.h" - - -/**************** - * Take an armor file and write it out without armor - */ -int -dearmor_file( const char *fname ) -{ - armor_filter_context_t afx; - iobuf_t inp = NULL, out = NULL; - int rc = 0; - int c; - - memset( &afx, 0, sizeof afx); - - /* prepare iobufs */ - if( !(inp = iobuf_open(fname)) ) { - rc = gpg_error_from_errno (errno); - log_error("can't open %s: %s\n", fname? fname: "[stdin]", - strerror(errno) ); - goto leave; - } - - iobuf_push_filter( inp, armor_filter, &afx ); - - if( (rc = open_outfile( fname, 0, &out )) ) - goto leave; - - - - while( (c = iobuf_get(inp)) != -1 ) - iobuf_put( out, c ); - - - leave: - if( rc ) - iobuf_cancel(out); - else - iobuf_close(out); - iobuf_close(inp); - return rc; -} - - -/**************** - * Take file and write it out with armor - */ -int -enarmor_file( const char *fname ) -{ - armor_filter_context_t afx; - iobuf_t inp = NULL, out = NULL; - int rc = 0; - int c; - - memset( &afx, 0, sizeof afx); - - /* prepare iobufs */ - if( !(inp = iobuf_open(fname)) ) { - rc = gpg_error_from_errno (errno); - log_error("can't open %s: %s\n", fname? fname: "[stdin]", - strerror(errno) ); - goto leave; - } - - - if( (rc = open_outfile( fname, 1, &out )) ) - goto leave; - - afx.what = 4; - afx.hdrlines = "Comment: Use \"gpg --dearmor\" for unpacking\n"; - iobuf_push_filter( out, armor_filter, &afx ); - - while( (c = iobuf_get(inp)) != -1 ) - iobuf_put( out, c ); - - - leave: - if( rc ) - iobuf_cancel(out); - else - iobuf_close(out); - iobuf_close(inp); - return rc; -} - - diff --git a/g10/decrypt.c b/g10/decrypt.c deleted file mode 100644 index 98a270cfb..000000000 --- a/g10/decrypt.c +++ /dev/null @@ -1,142 +0,0 @@ -/* decrypt.c - verify signed data - * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "status.h" -#include "i18n.h" - - - -/**************** - * Assume that the input is an encrypted message and decrypt - * (and if signed, verify the signature on) it. - * This command differs from the default operation, as it never - * writes to the filename which is included in the file and it - * rejects files which don't begin with an encrypted message. - */ - -int -decrypt_message( const char *filename ) -{ - iobuf_t fp; - armor_filter_context_t afx; - progress_filter_context_t pfx; - int rc; - int no_out=0; - - /* open the message file */ - fp = iobuf_open(filename); - if( !fp ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't open `%s'\n"), print_fname_stdin(filename)); - return rc; - } - - handle_progress (&pfx, fp, filename); - - if( !opt.no_armor ) { - if( use_armor_filter( fp ) ) { - memset( &afx, 0, sizeof afx); - iobuf_push_filter( fp, armor_filter, &afx ); - } - } - - if( !opt.outfile ) { - no_out = 1; - opt.outfile = "-"; - } - rc = proc_encryption_packets( NULL, fp ); - if( no_out ) - opt.outfile = NULL; - iobuf_close(fp); - return rc; -} - -void -decrypt_messages(int nfiles, char **files) -{ - iobuf_t fp; - armor_filter_context_t afx; - progress_filter_context_t pfx; - char *p, *output = NULL; - int rc = 0; - - if (opt.outfile) - { - log_error(_("--output doesn't work for this command\n")); - return; - - } - - while (nfiles--) - { - print_file_status(STATUS_FILE_START, *files, 3); - output = make_outfile_name(*files); - if (!output) - goto next_file; - fp = iobuf_open(*files); - if (!fp) - { - log_error(_("can't open `%s'\n"), print_fname_stdin(*files)); - goto next_file; - } - - handle_progress (&pfx, fp, *files); - - if (!opt.no_armor) - { - if (use_armor_filter(fp)) - { - memset(&afx, 0, sizeof afx); - iobuf_push_filter(fp, armor_filter, &afx); - } - } - rc = proc_packets(NULL, fp); - iobuf_close(fp); - if (rc) - log_error("%s: decryption failed: %s\n", print_fname_stdin(*files), - gpg_strerror (rc)); - p = get_last_passphrase(); - set_next_passphrase(p); - xfree (p); - - next_file: - /* Note that we emit file_done even after an error. */ - write_status( STATUS_FILE_DONE ); - xfree (output); - files++; - } - set_next_passphrase(NULL); -} - diff --git a/g10/delkey.c b/g10/delkey.c deleted file mode 100644 index 6263dec47..000000000 --- a/g10/delkey.c +++ /dev/null @@ -1,209 +0,0 @@ -/* delkey.c - delete keys - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <ctype.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "trustdb.h" -#include "filter.h" -#include "ttyio.h" -#include "status.h" -#include "i18n.h" - - -/**************** - * Delete a public or secret key from a keyring. - * r_sec_avail will be set if a secret key is available and the public - * key can't be deleted for that reason. - */ -static int -do_delete_key( const char *username, int secret, int *r_sec_avail ) -{ - int rc = 0; - KBNODE keyblock = NULL; - KBNODE node; - KEYDB_HANDLE hd = keydb_new (secret); - PKT_public_key *pk = NULL; - PKT_secret_key *sk = NULL; - u32 keyid[2]; - int okay=0; - int yes; - KEYDB_SEARCH_DESC desc; - int exactmatch; - - *r_sec_avail = 0; - - /* search the userid */ - classify_user_id (username, &desc); - exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR - || desc.mode == KEYDB_SEARCH_MODE_FPR16 - || desc.mode == KEYDB_SEARCH_MODE_FPR20); - rc = desc.mode? keydb_search (hd, &desc, 1):GPG_ERR_INV_USER_ID; - if (rc) { - log_error (_("key `%s' not found: %s\n"), username, gpg_strerror (rc)); - write_status_text( STATUS_DELETE_PROBLEM, "1" ); - goto leave; - } - - /* read the keyblock */ - rc = keydb_get_keyblock (hd, &keyblock ); - if (rc) { - log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - /* get the keyid from the keyblock */ - node = find_kbnode( keyblock, secret? PKT_SECRET_KEY:PKT_PUBLIC_KEY ); - if( !node ) { - log_error("Oops; key not found anymore!\n"); - rc = GPG_ERR_GENERAL; - goto leave; - } - - if( secret ) { - sk = node->pkt->pkt.secret_key; - keyid_from_sk( sk, keyid ); - } - else { - pk = node->pkt->pkt.public_key; - keyid_from_pk( pk, keyid ); - rc = seckey_available( keyid ); - if( !rc ) { - *r_sec_avail = 1; - rc = -1; - goto leave; - } - else if( rc != GPG_ERR_NO_SECKEY ) { - log_error("%s: get secret key: %s\n", username, gpg_strerror (rc) ); - } - else - rc = 0; - } - - if( rc ) - rc = 0; - else if (opt.batch && exactmatch) - okay++; - else if( opt.batch && secret ) - { - log_error(_("can't do that in batchmode\n")); - log_info (_("(unless you specify the key by fingerprint)\n")); - } - else if( opt.batch && opt.answer_yes ) - okay++; - else if( opt.batch ) - { - log_error(_("can't do that in batchmode without \"--yes\"\n")); - log_info (_("(unless you specify the key by fingerprint)\n")); - } - else { - if( secret ) - print_seckey_info( sk ); - else - print_pubkey_info (NULL, pk ); - tty_printf( "\n" ); - - yes = cpr_get_answer_is_yes( secret? "delete_key.secret.okay" - : "delete_key.okay", - _("Delete this key from the keyring? ")); - if( !cpr_enabled() && secret && yes ) { - /* I think it is not required to check a passphrase; if - * the user is so stupid as to let others access his secret keyring - * (and has no backup) - it is up him to read some very - * basic texts about security. - */ - yes = cpr_get_answer_is_yes("delete_key.secret.okay", - _("This is a secret key! - really delete? ")); - } - if( yes ) - okay++; - } - - - if( okay ) { - rc = keydb_delete_keyblock (hd); - if (rc) { - log_error (_("deleting keyblock failed: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - /* Note that the ownertrust being cleared will trigger a - revalidation_mark(). This makes sense - only deleting keys - that have ownertrust set should trigger this. */ - - if (!secret && pk && clear_ownertrusts (pk)) { - if (opt.verbose) - log_info (_("ownertrust information cleared\n")); - } - } - - leave: - keydb_release (hd); - release_kbnode (keyblock); - return rc; -} - -/**************** - * Delete a public or secret key from a keyring. - */ -int -delete_keys( STRLIST names, int secret, int allow_both ) -{ - int rc, avail; - - for(;names;names=names->next) { - rc = do_delete_key (names->d, secret, &avail ); - if ( rc && avail ) { - if ( allow_both ) { - rc = do_delete_key (names->d, 1, &avail ); - if ( !rc ) - rc = do_delete_key (names->d, 0, &avail ); - } - else { - log_error(_( - "there is a secret key for public key \"%s\"!\n"),names->d); - log_info(_( - "use option \"--delete-secret-keys\" to delete it first.\n")); - write_status_text( STATUS_DELETE_PROBLEM, "2" ); - return rc; - } - } - - if(rc) { - log_error("%s: delete key failed: %s\n", names->d, gpg_strerror (rc) ); - return rc; - } - } - - return 0; -} diff --git a/g10/encode.c b/g10/encode.c deleted file mode 100644 index 7794bdb7c..000000000 --- a/g10/encode.c +++ /dev/null @@ -1,821 +0,0 @@ -/* encode.c - encode data - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "gpg.h" -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "filter.h" -#include "trustdb.h" -#include "i18n.h" -#include "status.h" -#include "pkglue.h" - - -static int encode_simple( const char *filename, int mode, int compat ); -static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out ); - - - -/**************** - * Encode FILENAME with only the symmetric cipher. Take input from - * stdin if FILENAME is NULL. - */ -int -encode_symmetric( const char *filename ) -{ - int compat = 1; - -#if 0 - /* We don't want to use it because older gnupg version can't - handle it and we can presume that a lot of scripts are running - with the expert mode set. Some time in the future we might - want to allow for it. */ - if ( opt.expert ) - compat = 0; /* PGP knows how to handle this mode. */ -#endif - return encode_simple( filename, 1, compat ); -} - -/**************** - * Encode FILENAME as a literal data packet only. Take input from - * stdin if FILENAME is NULL. - */ -int -encode_store( const char *filename ) -{ - return encode_simple( filename, 0, 1 ); -} - -static void -encode_sesskey (DEK * dek, DEK ** ret_dek, byte * enckey) -{ - CIPHER_HANDLE hd; - DEK * c; - byte buf[33]; - - assert (dek->keylen < 32); - - c = xcalloc (1, sizeof *c); - c->keylen = dek->keylen; - c->algo = dek->algo; - make_session_key (c); - /*log_hexdump ("thekey", c->key, c->keylen);*/ - - /* the encrypted session key is prefixed with a one-octet algorithm id */ - buf[0] = c->algo; - memcpy (buf + 1, c->key, c->keylen); - - /* due to the fact that we use only checked values, consider each - failure as fatal. */ - if (gcry_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1)) - BUG(); - if (gcry_cipher_setkey (hd, dek->key, dek->keylen)) - BUG(); - gcry_cipher_setiv (hd, NULL, 0); - gcry_cipher_encrypt (hd, buf, c->keylen + 1, NULL, 0); - gcry_cipher_close (hd); - - memcpy (enckey, buf, c->keylen + 1); - wipememory (buf, sizeof buf); /* burn key */ - *ret_dek = c; -} - -/* We try very hard to use a MDC */ -static int -use_mdc (PK_LIST pk_list,int algo) -{ - byte cipher_algid[4] = { - CIPHER_ALGO_AES, - CIPHER_ALGO_AES192, - CIPHER_ALGO_AES256, - CIPHER_ALGO_TWOFISH - }; - int i; - - /* RFC-1991 and 2440 don't have MDC */ - if(RFC1991 || RFC2440) - return 0; - - /* --force-mdc overrides --disable-mdc */ - if (opt.force_mdc) - return 1; - - if (opt.disable_mdc) - return 0; - - /* Do the keys really support MDC? */ - - if (select_mdc_from_pklist (pk_list)) - return 1; - - /* The keys don't support MDC, so now we do a bit of a hack - if any - of the AESes or TWOFISH are in the prefs, we assume that the user - can handle a MDC. This is valid for PGP 7, which can handle MDCs - though it will not generate them. 2440bis allows this, by the - way. */ - for (i=0; i < DIM (cipher_algid); i++) - { - if (select_algo_from_prefs (pk_list, PREFTYPE_SYM, cipher_algid[i], - NULL) == cipher_algid[i]) - return 1; - } - - /* Last try. Use MDC for the modern ciphers. */ - if (gcry_cipher_get_algo_blklen (algo) != 8) - return 1; - - return 0; /* No MDC */ -} - -static int -encode_simple( const char *filename, int mode, int compat ) -{ - iobuf_t inp, out; - PACKET pkt; - DEK *dek = NULL; - PKT_plaintext *pt = NULL; - STRING2KEY *s2k = NULL; - byte enckey[33]; - int rc = 0; - int seskeylen = 0; - u32 filesize; - cipher_filter_context_t cfx; - armor_filter_context_t afx; - compress_filter_context_t zfx; - text_filter_context_t tfx; - progress_filter_context_t pfx; - int do_compress = opt.compress && !RFC1991; - - memset( &cfx, 0, sizeof cfx); - memset( &afx, 0, sizeof afx); - memset( &zfx, 0, sizeof zfx); - memset( &tfx, 0, sizeof tfx); - init_packet(&pkt); - - /* prepare iobufs */ - if( !(inp = iobuf_open(filename)) ) { - rc = gpg_error_from_errno (errno); - log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]", - strerror(errno) ); - return rc; - } - - handle_progress (&pfx, inp, filename); - - if( opt.textmode ) - iobuf_push_filter( inp, text_filter, &tfx ); - - /* Due the the fact that we use don't use an IV to encrypt the - session key we can't use the new mode with RFC1991 because - it has no S2K salt. RFC1991 always uses simple S2K. */ - if ( RFC1991 && !compat ) - compat = 1; - - cfx.dek = NULL; - if( mode ) { - s2k = xcalloc (1, sizeof *s2k ); - s2k->mode = RFC1991? 0:opt.s2k_mode; - s2k->hash_algo = opt.s2k_digest_algo; - cfx.dek = passphrase_to_dek( NULL, 0, - default_cipher_algo(), s2k, 2, - NULL, NULL); - if( !cfx.dek || !cfx.dek->keylen ) { - rc = gpg_error (GPG_ERR_INV_PASSPHRASE); - xfree (cfx.dek); - xfree (s2k); - iobuf_close(inp); - log_error(_("error creating passphrase: %s\n"), gpg_strerror (rc) ); - return rc; - } - if (!compat && s2k->mode != 1 && s2k->mode != 3) { - compat = 1; - log_info (_("can't use a symmetric ESK packet " - "due to the S2K mode\n")); - } - - if ( !compat ) { - seskeylen = gcry_cipher_get_algo_keylen (default_cipher_algo()); - encode_sesskey( cfx.dek, &dek, enckey ); - xfree (cfx.dek); cfx.dek = dek; - } - - cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo); - } - - if (opt.compress == -1 && cfx.dek && cfx.dek->use_mdc && - is_file_compressed(filename, &rc)) - { - if (opt.verbose) - log_info(_("`%s' already compressed\n"), filename); - do_compress = 0; - } - - if( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) { - iobuf_cancel(inp); - xfree (cfx.dek); - xfree (s2k); - return rc; - } - - if( opt.armor ) - iobuf_push_filter( out, armor_filter, &afx ); -#ifdef ENABLE_COMMENT_PACKETS - else { - write_comment( out, "#created by GNUPG v" VERSION " (" - PRINTABLE_OS_NAME ")"); - if( opt.comment_string ) - write_comment( out, opt.comment_string ); - } -#endif - if( s2k && !RFC1991 ) { - PKT_symkey_enc *enc = xcalloc (1, sizeof *enc + seskeylen + 1 ); - enc->version = 4; - enc->cipher_algo = cfx.dek->algo; - enc->s2k = *s2k; - if ( !compat && seskeylen ) { - enc->seskeylen = seskeylen + 1; /* algo id */ - memcpy( enc->seskey, enckey, seskeylen + 1 ); - } - pkt.pkttype = PKT_SYMKEY_ENC; - pkt.pkt.symkey_enc = enc; - if( (rc = build_packet( out, &pkt )) ) - log_error("build symkey packet failed: %s\n", gpg_strerror (rc) ); - xfree (enc); - } - - if (!opt.no_literal) { - /* setup the inner packet */ - if( filename || opt.set_filename ) { - char *s = make_basename ( opt.set_filename ? opt.set_filename - : filename - /* for riscos? - .iobuf_get_real_fname( inp ) */ - ); - pt = xmalloc ( sizeof *pt + strlen(s) - 1 ); - pt->namelen = strlen(s); - memcpy(pt->name, s, pt->namelen ); - xfree (s); - } - else { /* no filename */ - pt = xmalloc ( sizeof *pt - 1 ); - pt->namelen = 0; - } - } - - /* Note that PGP 5 has problems decrypting symmetrically encrypted - data if the file length is in the inner packet. It works when - only partial length headers are use. In the past, we always - used partial body length here, but since PGP 2, PGP 6, and PGP - 7 need the file length, and nobody should be using PGP 5 - nowadays anyway, this is now set to the file length. Note also - that this only applies to the RFC-1991 style symmetric - messages, and not the RFC-2440 style. PGP 6 and 7 work with - either partial length or fixed length with the new style - messages. */ - - if (filename && *filename && !(*filename == '-' && !filename[1]) - && !opt.textmode ) { - off_t tmpsize; - - if ( !(tmpsize = iobuf_get_filelength(inp)) ) - log_info(_("%s: WARNING: 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 - packet headers, we switch to partial length encoding. */ - if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) ) - filesize = tmpsize; - else - filesize = 0; - } - else - filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ - - if (!opt.no_literal) { - pt->timestamp = make_timestamp(); - pt->mode = opt.textmode? 't' : 'b'; - pt->len = filesize; - pt->new_ctb = !pt->len && !RFC1991; - pt->buf = inp; - pkt.pkttype = PKT_PLAINTEXT; - pkt.pkt.plaintext = pt; - cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0; - } - else - { - cfx.datalen = filesize && !do_compress ? filesize : 0; - pkt.pkttype = 0; - pkt.pkt.generic = NULL; - } - - /* register the cipher filter */ - if( mode ) - iobuf_push_filter( out, cipher_filter, &cfx ); - /* register the compress filter */ - if( do_compress ) - { - if (cfx.dek && cfx.dek->use_mdc) - zfx.new_ctb = 1; - zfx.algo=default_compress_algo(); - iobuf_push_filter( out, compress_filter, &zfx ); - } - - /* do the work */ - if (!opt.no_literal) { - if( (rc = build_packet( out, &pkt )) ) - log_error("build_packet failed: %s\n", gpg_strerror (rc) ); - } - else { - /* user requested not to create a literal packet, - * so we copy the plain data */ - byte copy_buffer[4096]; - int bytes_copied; - while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1) - if ( (rc=iobuf_write(out, copy_buffer, bytes_copied))) { - log_error("copying input to output failed: %s\n", gpg_strerror (rc) ); - break; - } - wipememory(copy_buffer, 4096); /* burn buffer */ - } - - /* finish the stuff */ - iobuf_close(inp); - if (rc) - iobuf_cancel(out); - else { - iobuf_close(out); /* fixme: check returncode */ - if (mode) - write_status( STATUS_END_ENCRYPTION ); - } - if (pt) - pt->buf = NULL; - free_packet(&pkt); - xfree (cfx.dek); - xfree (s2k); - return rc; -} - -/**************** - * Encrypt the file with the given userids (or ask if none - * is supplied). - */ -int -encode_crypt( const char *filename, STRLIST remusr ) -{ - iobuf_t inp = NULL, out = NULL; - PACKET pkt; - PKT_plaintext *pt = NULL; - int rc = 0, rc2 = 0; - u32 filesize; - cipher_filter_context_t cfx; - armor_filter_context_t afx; - compress_filter_context_t zfx; - text_filter_context_t tfx; - progress_filter_context_t pfx; - PK_LIST pk_list,work_list; - int do_compress = opt.compress && !RFC1991; - - - memset( &cfx, 0, sizeof cfx); - memset( &afx, 0, sizeof afx); - memset( &zfx, 0, sizeof zfx); - memset( &tfx, 0, sizeof tfx); - init_packet(&pkt); - - if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) ) - return rc; - - if(PGP2) { - for(work_list=pk_list; work_list; work_list=work_list->next) - if(!(is_RSA(work_list->pk->pubkey_algo) && - nbits_from_pk(work_list->pk)<=2048)) - { - log_info(_("you can only encrypt to RSA keys of 2048 bits or " - "less in --pgp2 mode\n")); - compliance_failure(); - break; - } - } - - /* prepare iobufs */ - if( !(inp = iobuf_open(filename)) ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]", - strerror(errno) ); - goto leave; - } - else if( opt.verbose ) - log_info(_("reading from `%s'\n"), filename? filename: "[stdin]"); - - handle_progress (&pfx, inp, filename); - - if( opt.textmode ) - iobuf_push_filter( inp, text_filter, &tfx ); - - if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) - goto leave; - - - if( opt.armor ) - iobuf_push_filter( out, armor_filter, &afx ); -#ifdef ENABLE_COMMENT_PACKETS - else { - write_comment( out, "#created by GNUPG v" VERSION " (" - PRINTABLE_OS_NAME ")"); - if( opt.comment_string ) - write_comment( out, opt.comment_string ); - } -#endif - /* create a session key */ - cfx.dek = xcalloc_secure (1, sizeof *cfx.dek); - if( !opt.def_cipher_algo ) { /* try to get it from the prefs */ - cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL); - /* The only way select_algo_from_prefs can fail here is when - mixing v3 and v4 keys, as v4 keys have an implicit - preference entry for 3DES, and the pk_list cannot be empty. - In this case, use 3DES anyway as it's the safest choice - - perhaps the v3 key is being used in an OpenPGP - implementation and we know that the implementation behind - any v4 key can handle 3DES. */ - if( cfx.dek->algo == -1 ) { - cfx.dek->algo = CIPHER_ALGO_3DES; - - if( PGP2 ) { - log_info(_("unable to use the IDEA cipher for all of the keys " - "you are encrypting to.\n")); - compliance_failure(); - } - } - } - else { - if(!opt.expert && - select_algo_from_prefs(pk_list,PREFTYPE_SYM, - opt.def_cipher_algo,NULL)!=opt.def_cipher_algo) - log_info(_("forcing symmetric cipher %s (%d) " - "violates recipient preferences\n"), - gcry_cipher_algo_name (opt.def_cipher_algo), - opt.def_cipher_algo); - - cfx.dek->algo = opt.def_cipher_algo; - } - - cfx.dek->use_mdc=use_mdc(pk_list,cfx.dek->algo); - - /* Only do the is-file-already-compressed check if we are using a - MDC. This forces compressed files to be re-compressed if we do - not have a MDC to give some protection against chosen - ciphertext attacks. */ - - if (opt.compress == -1 && cfx.dek->use_mdc && - is_file_compressed(filename, &rc2) ) - { - if (opt.verbose) - log_info(_("`%s' already compressed\n"), filename); - do_compress = 0; - } - if (rc2) - { - rc = rc2; - goto leave; - } - - make_session_key( cfx.dek ); - if( DBG_CIPHER ) - log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen ); - - rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out ); - if( rc ) - goto leave; - - if (!opt.no_literal) { - /* setup the inner packet */ - if( filename || opt.set_filename ) { - char *s = make_basename( opt.set_filename ? opt.set_filename - : filename - /* ,iobuf_get_real_fname( inp )*/ ); - pt = xmalloc ( sizeof *pt + strlen(s) - 1 ); - pt->namelen = strlen(s); - memcpy(pt->name, s, pt->namelen ); - xfree (s); - } - else { /* no filename */ - pt = xmalloc ( sizeof *pt - 1 ); - pt->namelen = 0; - } - } - - if (filename && *filename && !(*filename == '-' && !filename[1]) - && !opt.textmode ) { - off_t tmpsize; - - if ( !(tmpsize = iobuf_get_filelength(inp)) ) - log_info(_("%s: WARNING: 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 - packet headers, we switch to partial length encoding. */ - if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) ) - filesize = tmpsize; - else - filesize = 0; - } - else - filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ - - if (!opt.no_literal) { - pt->timestamp = make_timestamp(); - pt->mode = opt.textmode ? 't' : 'b'; - pt->len = filesize; - pt->new_ctb = !pt->len && !RFC1991; - pt->buf = inp; - pkt.pkttype = PKT_PLAINTEXT; - pkt.pkt.plaintext = pt; - cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0; - } - else - cfx.datalen = filesize && !do_compress ? filesize : 0; - - /* register the cipher filter */ - iobuf_push_filter( out, cipher_filter, &cfx ); - - /* register the compress filter */ - if( do_compress ) { - int compr_algo = opt.def_compress_algo; - - if(compr_algo==-1) - { - if((compr_algo= - select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1) - compr_algo=DEFAULT_COMPRESS_ALGO; - /* Theoretically impossible to get here since uncompressed - is implicit. */ - } - else if(!opt.expert && - select_algo_from_prefs(pk_list,PREFTYPE_ZIP, - compr_algo,NULL)!=compr_algo) - log_info(_("forcing compression algorithm %s (%d) " - "violates recipient preferences\n"), - compress_algo_to_string(compr_algo),compr_algo); - - /* algo 0 means no compression */ - if( compr_algo ) - { - if (cfx.dek && cfx.dek->use_mdc) - zfx.new_ctb = 1; - zfx.algo = compr_algo; - iobuf_push_filter( out, compress_filter, &zfx ); - } - } - - /* do the work */ - if (!opt.no_literal) { - if( (rc = build_packet( out, &pkt )) ) - log_error("build_packet failed: %s\n", gpg_strerror (rc) ); - } - else { - /* user requested not to create a literal packet, so we copy - the plain data */ - byte copy_buffer[4096]; - int bytes_copied; - while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1) - if ((rc=iobuf_write(out, copy_buffer, bytes_copied))) { - log_error("copying input to output failed: %s\n", - gpg_strerror (rc) ); - break; - } - wipememory(copy_buffer, 4096); /* burn buffer */ - } - - /* finish the stuff */ - leave: - iobuf_close(inp); - if( rc ) - iobuf_cancel(out); - else { - iobuf_close(out); /* fixme: check returncode */ - write_status( STATUS_END_ENCRYPTION ); - } - if( pt ) - pt->buf = NULL; - free_packet(&pkt); - xfree (cfx.dek); - release_pk_list( pk_list ); - return rc; -} - - - - -/**************** - * Filter to do a complete public key encryption. - */ -int -encrypt_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - encrypt_filter_context_t *efx = opaque; - int rc=0; - - if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */ - BUG(); /* not used */ - } - else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */ - if( !efx->header_okay ) { - efx->cfx.dek = xcalloc_secure (1, sizeof *efx->cfx.dek ); - - if( !opt.def_cipher_algo ) { /* try to get it from the prefs */ - efx->cfx.dek->algo = - select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,-1,NULL); - if( efx->cfx.dek->algo == -1 ) { - /* because 3DES is implicitly in the prefs, this can only - * happen if we do not have any public keys in the list */ - efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO; - } - } - else { - if(!opt.expert && - select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM, - opt.def_cipher_algo, - NULL)!=opt.def_cipher_algo) - log_info(_("forcing symmetric cipher %s (%d) " - "violates recipient preferences\n"), - gcry_cipher_algo_name (opt.def_cipher_algo), - opt.def_cipher_algo); - - efx->cfx.dek->algo = opt.def_cipher_algo; - } - - efx->cfx.dek->use_mdc = use_mdc(efx->pk_list,efx->cfx.dek->algo); - - make_session_key( efx->cfx.dek ); - if( DBG_CIPHER ) - log_printhex ("DEK is: ", - efx->cfx.dek->key, efx->cfx.dek->keylen ); - - rc = write_pubkey_enc_from_list( efx->pk_list, efx->cfx.dek, a ); - if( rc ) - return rc; - - iobuf_push_filter( a, cipher_filter, &efx->cfx ); - - efx->header_okay = 1; - } - rc = iobuf_write( a, buf, size ); - - } - else if( control == IOBUFCTRL_FREE ) { - } - else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "encrypt_filter"; - } - return rc; -} - - -/**************** - * Write pubkey-enc packets from the list of PKs to OUT. - */ -static int -write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out ) -{ - PACKET pkt; - PKT_public_key *pk; - PKT_pubkey_enc *enc; - int rc; - - for( ; pk_list; pk_list = pk_list->next ) { - gcry_mpi_t frame; - - pk = pk_list->pk; - - print_pubkey_algo_note( pk->pubkey_algo ); - enc = xcalloc (1, sizeof *enc ); - enc->pubkey_algo = pk->pubkey_algo; - keyid_from_pk( pk, enc->keyid ); - enc->throw_keyid = (opt.throw_keyid || (pk_list->flags&1)); - - if(opt.throw_keyid && (PGP2 || PGP6 || PGP7 || PGP8)) - { - log_info(_("you may not use %s while in %s mode\n"), - "--throw-keyid",compliance_option_string()); - compliance_failure(); - } - - /* Okay, what's going on: We have the session key somewhere in - * the structure DEK and want to encode this session key in - * an integer value of n bits. pubkey_nbits gives us the - * number of bits we have to use. We then encode the session - * key in some way and we get it back in the big intger value - * FRAME. Then we use FRAME, the public key PK->PKEY and the - * algorithm number PK->PUBKEY_ALGO and pass it to pubkey_encrypt - * which returns the encrypted value in the array ENC->DATA. - * This array has a size which depends on the used algorithm - * (e.g. 2 for ElGamal). We don't need frame anymore because we - * have everything now in enc->data which is the passed to - * build_packet() - */ - frame = encode_session_key( dek, pubkey_nbits( pk->pubkey_algo, - pk->pkey ) ); - rc = pk_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey ); - gcry_mpi_release ( frame ); - if( rc ) - log_error("pubkey_encrypt failed: %s\n", gpg_strerror (rc) ); - else { - if( opt.verbose ) { - char *ustr = get_user_id_string_printable (enc->keyid); - log_info(_("%s/%s encrypted for: \"%s\"\n"), - gcry_pk_algo_name (enc->pubkey_algo), - gcry_cipher_algo_name (dek->algo), ustr ); - xfree (ustr); - } - /* and write it */ - init_packet(&pkt); - pkt.pkttype = PKT_PUBKEY_ENC; - pkt.pkt.pubkey_enc = enc; - rc = build_packet( out, &pkt ); - if( rc ) - log_error("build_packet(pubkey_enc) failed: %s\n", gpg_strerror (rc)); - } - free_pubkey_enc(enc); - if( rc ) - return rc; - } - return 0; -} - -void -encode_crypt_files(int nfiles, char **files, STRLIST remusr) -{ - int rc = 0; - - if (opt.outfile) - { - log_error(_("--output doesn't work for this command\n")); - return; - } - - if (!nfiles) - { - char line[2048]; - unsigned int lno = 0; - while ( fgets(line, DIM(line), stdin) ) - { - lno++; - if (!*line || line[strlen(line)-1] != '\n') - { - log_error("input line %u too long or missing LF\n", lno); - return; - } - line[strlen(line)-1] = '\0'; - print_file_status(STATUS_FILE_START, line, 2); - if ( (rc = encode_crypt(line, remusr)) ) - log_error("%s: encryption failed: %s\n", - print_fname_stdin(line), gpg_strerror (rc) ); - write_status( STATUS_FILE_DONE ); - } - } - else - { - while (nfiles--) - { - print_file_status(STATUS_FILE_START, *files, 2); - if ( (rc = encode_crypt(*files, remusr)) ) - log_error("%s: encryption failed: %s\n", - print_fname_stdin(*files), gpg_strerror (rc) ); - write_status( STATUS_FILE_DONE ); - files++; - } - } -} diff --git a/g10/encr-data.c b/g10/encr-data.c deleted file mode 100644 index 074408404..000000000 --- a/g10/encr-data.c +++ /dev/null @@ -1,269 +0,0 @@ -/* encr-data.c - process an encrypted data packet - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "packet.h" -#include "mpi.h" -#include "cipher.h" -#include "options.h" -#include "i18n.h" - - -static int mdc_decode_filter( void *opaque, int control, iobuf_t a, - byte *buf, size_t *ret_len); -static int decode_filter( void *opaque, int control, iobuf_t a, - byte *buf, size_t *ret_len); - -typedef struct { - CIPHER_HANDLE cipher_hd; - MD_HANDLE mdc_hash; - char defer[20]; - int defer_filled; - int eof_seen; -} decode_filter_ctx_t; - - -/**************** - * Decrypt the data, specified by ED with the key DEK. - */ -int -decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) -{ - decode_filter_ctx_t dfx; - byte *p; - int rc=0, c, i; - byte temp[32]; - unsigned blocksize; - unsigned nprefix; - - memset( &dfx, 0, sizeof dfx ); - if( opt.verbose && !dek->algo_info_printed ) { - const char *s = gcry_cipher_algo_name (dek->algo); - if (s && *s) - log_info(_("%s encrypted data\n"), s ); - else - log_info(_("encrypted with unknown algorithm %d\n"), dek->algo ); - dek->algo_info_printed = 1; - } - if( (rc=openpgp_cipher_test_algo(dek->algo)) ) - goto leave; - blocksize = gcry_cipher_get_algo_blklen (dek->algo); - if( !blocksize || blocksize > 16 ) - log_fatal("unsupported blocksize %u\n", blocksize ); - nprefix = blocksize; - if( ed->len && ed->len < (nprefix+2) ) - BUG(); - - if( ed->mdc_method ) { - gcry_md_open (&dfx.mdc_hash, ed->mdc_method, 0 ); - if ( DBG_HASHING ) - gcry_md_start_debug (dfx.mdc_hash, "checkmdc"); - } - rc = gcry_cipher_open (&dfx.cipher_hd, dek->algo, - GCRY_CIPHER_MODE_CFB, - GCRY_CIPHER_SECURE - | ((ed->mdc_method || dek->algo >= 100)? - 0 : GCRY_CIPHER_ENABLE_SYNC) ); - if (rc) - { - /* we should never get an error here cause we already - * checked, that the algorithm is available. What about a - * flag to let the function die in this case? */ - BUG(); - } - /* log_hexdump( "thekey", dek->key, dek->keylen );*/ - rc = gcry_cipher_setkey (dfx.cipher_hd, dek->key, dek->keylen); - if( gpg_err_code (rc) == GPG_ERR_WEAK_KEY ) - log_info(_("WARNING: message was encrypted with " - "a weak key in the symmetric cipher.\n")); - else if( rc ) { - log_error("key setup failed: %s\n", gpg_strerror (rc) ); - goto leave; - } - if (!ed->buf) { - log_error(_("problem handling encrypted packet\n")); - goto leave; - } - - gcry_cipher_setiv (dfx.cipher_hd, NULL, 0); - - if (ed->len) { - for(i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) { - if( (c=iobuf_get(ed->buf)) == -1 ) - break; - else - temp[i] = c; - } - } - else { - for(i=0; i < (nprefix+2); i++ ) - if( (c=iobuf_get(ed->buf)) == -1 ) - break; - else - temp[i] = c; - } - gcry_cipher_decrypt( dfx.cipher_hd, temp, nprefix+2, NULL, 0); - gcry_cipher_sync( dfx.cipher_hd ); - p = temp; -/* log_hexdump( "prefix", temp, nprefix+2 ); */ - if( p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1] ) { - rc = GPG_ERR_BAD_KEY; - goto leave; - } - - if( dfx.mdc_hash ) - gcry_md_write( dfx.mdc_hash, temp, nprefix+2 ); - - if( ed->mdc_method ) - iobuf_push_filter( ed->buf, mdc_decode_filter, &dfx ); - else - iobuf_push_filter( ed->buf, decode_filter, &dfx ); - - proc_packets( procctx, ed->buf ); - ed->buf = NULL; - if( ed->mdc_method && dfx.eof_seen == 2 ) - rc = gpg_error (GPG_ERR_INV_PACKET); - else if( ed->mdc_method ) { /* check the mdc */ - int datalen = gcry_md_get_algo_dlen (ed->mdc_method); - - gcry_cipher_decrypt (dfx.cipher_hd, dfx.defer, 20, NULL, 0); - gcry_md_final ( dfx.mdc_hash ); - if( datalen != 20 - || memcmp(gcry_md_read ( dfx.mdc_hash, 0 ), dfx.defer, datalen) ) - rc = gpg_error (GPG_ERR_BAD_SIGNATURE); - /*log_hexdump("MDC calculated:", gcry_md_read ( dfx.mdc_hash, 0), datalen);*/ - /*log_hexdump("MDC message :", dfx.defer, 20);*/ - } - - - leave: - gcry_cipher_close(dfx.cipher_hd); - gcry_md_close ( dfx.mdc_hash ); - return rc; -} - - - -/* I think we should merge this with cipher_filter */ -static int -mdc_decode_filter( void *opaque, int control, iobuf_t a, - byte *buf, size_t *ret_len) -{ - decode_filter_ctx_t *dfx = opaque; - size_t n, size = *ret_len; - int rc = 0; - int c; - - if( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen ) { - *ret_len = 0; - rc = -1; - } - else if( control == IOBUFCTRL_UNDERFLOW ) { - assert(a); - assert( size > 40 ); - - /* get at least 20 bytes and put it somewhere ahead in the buffer */ - for(n=20; n < 40 ; n++ ) { - if( (c = iobuf_get(a)) == -1 ) - break; - buf[n] = c; - } - if( n == 40 ) { - /* we have enough stuff - flush the deferred stuff */ - /* (we have asserted that the buffer is large enough) */ - if( !dfx->defer_filled ) { /* the first time */ - memcpy(buf, buf+20, 20 ); - n = 20; - } - else { - memcpy(buf, dfx->defer, 20 ); - } - /* now fill up */ - for(; n < size; n++ ) { - if( (c = iobuf_get(a)) == -1 ) - break; - buf[n] = c; - } - /* move the last 20 bytes back to the defer buffer */ - /* (okay, we are wasting 20 bytes of supplied buffer) */ - n -= 20; - memcpy( dfx->defer, buf+n, 20 ); - dfx->defer_filled = 1; - } - else if( !dfx->defer_filled ) { /* eof seen buf empty defer */ - /* this is bad because there is an incomplete hash */ - n -= 20; - memcpy(buf, buf+20, n ); - dfx->eof_seen = 2; /* eof with incomplete hash */ - } - else { /* eof seen */ - memcpy(buf, dfx->defer, 20 ); - n -= 20; - memcpy( dfx->defer, buf+n, 20 ); - dfx->eof_seen = 1; /* normal eof */ - } - - if( n ) { - gcry_cipher_decrypt( dfx->cipher_hd, buf, n, NULL, 0); - gcry_md_write( dfx->mdc_hash, buf, n ); - } - else { - assert( dfx->eof_seen ); - rc = -1; /* eof */ - } - *ret_len = n; - } - else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "mdc_decode_filter"; - } - return rc; -} - -static int -decode_filter( void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len) -{ - decode_filter_ctx_t *fc = opaque; - size_t n, size = *ret_len; - int rc = 0; - - if( control == IOBUFCTRL_UNDERFLOW ) { - assert(a); - n = iobuf_read( a, buf, size ); - if( n == -1 ) n = 0; - if( n ) - gcry_cipher_decrypt( fc->cipher_hd, buf, n, NULL, 0); - else - rc = -1; /* eof */ - *ret_len = n; - } - else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "decode_filter"; - } - return rc; -} - diff --git a/g10/exec.c b/g10/exec.c deleted file mode 100644 index a49fe15d2..000000000 --- a/g10/exec.c +++ /dev/null @@ -1,619 +0,0 @@ -/* exec.c - generic call-a-program code - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdarg.h> -#include <stdio.h> -#include <sys/stat.h> -#include <sys/types.h> -#ifndef EXEC_TEMPFILE_ONLY -#include <sys/wait.h> -#endif -#ifdef HAVE_DOSISH_SYSTEM -#include <windows.h> -#endif -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include "options.h" -#include "memory.h" -#include "i18n.h" -#include "iobuf.h" -#include "util.h" -#include "exec.h" - -#ifdef NO_EXEC -int exec_write(struct exec_info **info,const char *program, - const char *args_in,const char *name,int writeonly,int binary) -{ - log_error(_("no remote program execution supported\n")); - return GPG_ERR_GENERAL; -} - -int exec_read(struct exec_info *info) { return GPG_ERR_GENERAL; } -int exec_finish(struct exec_info *info) { return GPG_ERR_GENERAL; } -int set_exec_path(const char *path,int method) { return GPG_ERR_GENERAL; } - -#else /* ! NO_EXEC */ - -#ifndef HAVE_MKDTEMP -char *mkdtemp(char *template); -#endif - -#if defined (_WIN32) -/* This is a nicer system() for windows that waits for programs to - return before returning control to the caller. I hate helpful - computers. */ -static int win_system(const char *command) -{ - PROCESS_INFORMATION pi; - STARTUPINFO si; - char *string; - - /* We must use a copy of the command as CreateProcess modifies this - argument. */ - string=xstrdup (command); - - memset(&pi,0,sizeof(pi)); - memset(&si,0,sizeof(si)); - si.cb=sizeof(si); - - if(!CreateProcess(NULL,string,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) - return -1; - - /* Wait for the child to exit */ - WaitForSingleObject(pi.hProcess,INFINITE); - - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - xfree (string); - - return 0; -} -#endif - -/* method==0 to replace current $PATH, and 1 to append to current - $PATH. */ -int set_exec_path(const char *path,int method) -{ - char *p,*curpath=NULL; - size_t curlen=0; - - if(method==1 && (curpath=getenv("PATH"))) - curlen=strlen(curpath)+1; - - p=xmalloc (5+curlen+strlen(path)+1); - strcpy(p,"PATH="); - - if(curpath) - { - strcat(p,curpath); - strcat(p,":"); - } - - strcat(p,path); - - if(DBG_EXTPROG) - log_debug("set_exec_path method %d: %s\n",method,p); - - /* Notice that path is never freed. That is intentional due to the - way putenv() works. This leaks a few bytes if we call - set_exec_path multiple times. */ - - if(putenv(p)!=0) - return GPG_ERR_GENERAL; - else - return 0; -} - -/* Makes a temp directory and filenames */ -static int make_tempdir(struct exec_info *info) -{ - char *tmp=opt.temp_dir,*namein=info->name,*nameout; - - if(!namein) - namein=info->binary?"tempin" EXTSEP_S "bin":"tempin" EXTSEP_S "txt"; - - nameout=info->binary?"tempout" EXTSEP_S "bin":"tempout" EXTSEP_S "txt"; - - /* Make up the temp dir and files in case we need them */ - - if(tmp==NULL) - { -#if defined (_WIN32) - tmp=xmalloc (256); - if(GetTempPath(256,tmp)==0) - strcpy(tmp,"c:\\windows\\temp"); - else - { - int len=strlen(tmp); - - /* GetTempPath may return with \ on the end */ - while(len>0 && tmp[len-1]=='\\') - { - tmp[len-1]='\0'; - len--; - } - } -#else /* More unixish systems */ - tmp=getenv("TMPDIR"); - if(tmp==NULL) - { - tmp=getenv("TMP"); - if(tmp==NULL) - { -#ifdef __riscos__ - tmp="<Wimp$ScrapDir>.GnuPG"; - mkdir(tmp,0700); /* Error checks occur later on */ -#else - tmp="/tmp"; -#endif - } - } -#endif - } - - info->tempdir=xmalloc (strlen(tmp)+strlen(DIRSEP_S)+10+1); - - sprintf(info->tempdir,"%s" DIRSEP_S "gpg-XXXXXX",tmp); - -#if defined (_WIN32) - xfree (tmp); -#endif - - if(mkdtemp(info->tempdir)==NULL) - log_error(_("can't create directory `%s': %s\n"), - info->tempdir,strerror(errno)); - else - { - info->madedir=1; - - info->tempfile_in=xmalloc (strlen(info->tempdir)+ - strlen(DIRSEP_S)+strlen(namein)+1); - sprintf(info->tempfile_in,"%s" DIRSEP_S "%s",info->tempdir,namein); - - if(!info->writeonly) - { - info->tempfile_out=xmalloc (strlen(info->tempdir)+ - strlen(DIRSEP_S)+strlen(nameout)+1); - sprintf(info->tempfile_out,"%s" DIRSEP_S "%s",info->tempdir,nameout); - } - } - - return info->madedir?0:GPG_ERR_GENERAL; -} - -/* Expands %i and %o in the args to the full temp files within the - temp directory. */ -static int expand_args(struct exec_info *info,const char *args_in) -{ - const char *ch=args_in; - unsigned int size,len; - - info->use_temp_files=0; - info->keep_temp_files=0; - - if(DBG_EXTPROG) - log_debug("expanding string \"%s\"\n",args_in); - - size=100; - info->command=xmalloc (size); - len=0; - info->command[0]='\0'; - - while(*ch!='\0') - { - if(*ch=='%') - { - char *append=NULL; - - ch++; - - switch(*ch) - { - case 'O': - info->keep_temp_files=1; - /* fall through */ - - case 'o': /* out */ - if(!info->madedir) - { - if(make_tempdir(info)) - goto fail; - } - append=info->tempfile_out; - info->use_temp_files=1; - break; - - case 'I': - info->keep_temp_files=1; - /* fall through */ - - case 'i': /* in */ - if(!info->madedir) - { - if(make_tempdir(info)) - goto fail; - } - append=info->tempfile_in; - info->use_temp_files=1; - break; - - case '%': - append="%"; - break; - } - - if(append) - { - size_t applen=strlen(append); - - if(applen+len>size-1) - { - if(applen<100) - applen=100; - - size+=applen; - info->command=xrealloc(info->command,size); - } - - strcat(info->command,append); - len+=strlen(append); - } - } - else - { - if(len==size-1) /* leave room for the \0 */ - { - size+=100; - info->command=xrealloc(info->command,size); - } - - info->command[len++]=*ch; - info->command[len]='\0'; - } - - ch++; - } - - if(DBG_EXTPROG) - log_debug("args expanded to \"%s\", use %d, keep %d\n", - info->command,info->use_temp_files,info->keep_temp_files); - - return 0; - - fail: - - xfree (info->command); - info->command=NULL; - - return GPG_ERR_GENERAL; -} - -/* Either handles the tempfile creation, or the fork/exec. If it - returns ok, then info->tochild is a FILE * that can be written to. - The rules are: if there are no args, then it's a fork/exec/pipe. - If there are args, but no tempfiles, then it's a fork/exec/pipe via - shell -c. If there are tempfiles, then it's a system. */ - -int exec_write(struct exec_info **info,const char *program, - const char *args_in,const char *name,int writeonly,int binary) -{ - int ret=GPG_ERR_GENERAL; - - if(opt.exec_disable && !opt.no_perm_warn) - { - log_info(_("external program calls are disabled due to unsafe " - "options file permissions\n")); - - return ret; - } - -#if defined(HAVE_GETUID) && defined(HAVE_GETEUID) - /* There should be no way to get to this spot while still carrying - setuid privs. Just in case, bomb out if we are. */ - if(getuid()!=geteuid()) - BUG(); -#endif - - if(program==NULL && args_in==NULL) - BUG(); - - *info=xcalloc (1,sizeof(struct exec_info)); - - if(name) - (*info)->name=xstrdup (name); - (*info)->binary=binary; - (*info)->writeonly=writeonly; - - /* Expand the args, if any */ - if(args_in && expand_args(*info,args_in)) - goto fail; - -#ifdef EXEC_TEMPFILE_ONLY - if(!(*info)->use_temp_files) - { - log_error(_("this platform requires temp files when calling external " - "programs\n")); - goto fail; - } - -#else /* !EXEC_TEMPFILE_ONLY */ - - /* If there are no args, or there are args, but no temp files, we - can use fork/exec/pipe */ - if(args_in==NULL || (*info)->use_temp_files==0) - { - int to[2],from[2]; - - if(pipe(to)==-1) - goto fail; - - if(pipe(from)==-1) - { - close(to[0]); - close(to[1]); - goto fail; - } - - if(((*info)->child=fork())==-1) - { - close(to[0]); - close(to[1]); - close(from[0]); - close(from[1]); - goto fail; - } - - if((*info)->child==0) - { - char *shell=getenv("SHELL"); - - if(shell==NULL) - shell="/bin/sh"; - - /* I'm the child */ - - /* If the program isn't going to respond back, they get to - keep their stdout/stderr */ - if(!(*info)->writeonly) - { - /* implied close of STDERR */ - if(dup2(STDOUT_FILENO,STDERR_FILENO)==-1) - _exit(1); - - /* implied close of STDOUT */ - close(from[0]); - if(dup2(from[1],STDOUT_FILENO)==-1) - _exit(1); - } - - /* implied close of STDIN */ - close(to[1]); - if(dup2(to[0],STDIN_FILENO)==-1) - _exit(1); - - if(args_in==NULL) - { - if(DBG_EXTPROG) - log_debug("execlp: %s\n",program); - - execlp(program,program,(void *)NULL); - } - else - { - if(DBG_EXTPROG) - log_debug("execlp: %s -c %s\n",shell,(*info)->command); - - execlp(shell,shell,"-c",(*info)->command,(void *)NULL); - } - - /* If we get this far the exec failed. Clean up and return. */ - - log_error(_("unable to execute %s \"%s\": %s\n"), - args_in==NULL?"program":"shell", - args_in==NULL?program:shell, - strerror(errno)); - - /* This mimics the POSIX sh behavior - 127 means "not found" - from the shell. */ - if(errno==ENOENT) - _exit(127); - - _exit(1); - } - - /* I'm the parent */ - - close(to[0]); - - (*info)->tochild=fdopen(to[1],binary?"wb":"w"); - if((*info)->tochild==NULL) - { - ret = gpg_error_from_errno (errno); - close(to[1]); - goto fail; - } - - close(from[1]); - - (*info)->fromchild=iobuf_fdopen(from[0],"r"); - if((*info)->fromchild==NULL) - { - ret = gpg_error_from_errno (errno); - close(from[0]); - goto fail; - } - - /* fd iobufs are cached?! */ - iobuf_ioctl((*info)->fromchild,3,1,NULL); - - return 0; - } -#endif /* !EXEC_TEMPFILE_ONLY */ - - if(DBG_EXTPROG) - log_debug("using temp file `%s'\n",(*info)->tempfile_in); - - /* It's not fork/exec/pipe, so create a temp file */ - (*info)->tochild=fopen((*info)->tempfile_in,binary?"wb":"w"); - if((*info)->tochild==NULL) - { - ret = gpg_error_from_errno (errno); - log_error(_("can't create `%s': %s\n"), - (*info)->tempfile_in,strerror(errno)); - goto fail; - } - - ret=0; - - fail: - return ret; -} - -int exec_read(struct exec_info *info) -{ - int ret=GPG_ERR_GENERAL; - - fclose(info->tochild); - info->tochild=NULL; - - if(info->use_temp_files) - { - if(DBG_EXTPROG) - log_debug("system() command is %s\n",info->command); - -#if defined (_WIN32) - info->progreturn=win_system(info->command); -#else - info->progreturn=system(info->command); -#endif - - if(info->progreturn==-1) - { - log_error(_("system error while calling external program: %s\n"), - strerror(errno)); - info->progreturn=127; - goto fail; - } - -#if defined(WIFEXITED) && defined(WEXITSTATUS) - if(WIFEXITED(info->progreturn)) - info->progreturn=WEXITSTATUS(info->progreturn); - else - { - log_error(_("unnatural exit of external program\n")); - info->progreturn=127; - goto fail; - } -#else - /* If we don't have the macros, do the best we can. */ - info->progreturn = (info->progreturn & 0xff00) >> 8; -#endif - - /* 127 is the magic value returned from system() to indicate - that the shell could not be executed, or from /bin/sh to - indicate that the program could not be executed. */ - - if(info->progreturn==127) - { - log_error(_("unable to execute external program\n")); - goto fail; - } - - if(!info->writeonly) - { - info->fromchild=iobuf_open(info->tempfile_out); - if(info->fromchild==NULL) - { - ret = gpg_error_from_errno (errno); - log_error(_("unable to read external program response: %s\n"), - strerror(errno)); - goto fail; - } - - /* Do not cache this iobuf on close */ - iobuf_ioctl(info->fromchild,3,1,NULL); - } - } - - ret=0; - - fail: - return ret; -} - -int exec_finish(struct exec_info *info) -{ - int ret=info->progreturn; - - if(info->fromchild) - iobuf_close(info->fromchild); - - if(info->tochild) - fclose(info->tochild); - -#ifndef EXEC_TEMPFILE_ONLY - if(info->child>0) - { - if(waitpid(info->child,&info->progreturn,0)!=0 && - WIFEXITED(info->progreturn)) - ret=WEXITSTATUS(info->progreturn); - else - { - log_error(_("unnatural exit of external program\n")); - ret=127; - } - } -#endif - - if(info->madedir && !info->keep_temp_files) - { - if(info->tempfile_in) - { - if(unlink(info->tempfile_in)==-1) - log_info(_("WARNING: unable to remove tempfile (%s) `%s': %s\n"), - "in",info->tempfile_in,strerror(errno)); - } - - if(info->tempfile_out) - { - if(unlink(info->tempfile_out)==-1) - log_info(_("WARNING: unable to remove tempfile (%s) `%s': %s\n"), - "out",info->tempfile_out,strerror(errno)); - } - - if(rmdir(info->tempdir)==-1) - log_info(_("WARNING: unable to remove temp directory `%s': %s\n"), - info->tempdir,strerror(errno)); - } - - xfree (info->command); - xfree (info->name); - xfree (info->tempdir); - xfree (info->tempfile_in); - xfree (info->tempfile_out); - xfree (info); - - return ret; -} -#endif /* ! NO_EXEC */ diff --git a/g10/exec.h b/g10/exec.h deleted file mode 100644 index eda406894..000000000 --- a/g10/exec.h +++ /dev/null @@ -1,43 +0,0 @@ -/* exec.h - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef _EXEC_H_ -#define _EXEC_H_ - -#include <unistd.h> -#include <stdio.h> -#include "../common/iobuf.h" - -struct exec_info -{ - int progreturn,binary,writeonly,madedir,use_temp_files,keep_temp_files; - pid_t child; - FILE *tochild; - iobuf_t fromchild; - char *command,*name,*tempdir,*tempfile_in,*tempfile_out; -}; - -int exec_write(struct exec_info **info,const char *program, - const char *args_in,const char *name,int writeonly,int binary); -int exec_read(struct exec_info *info); -int exec_finish(struct exec_info *info); -int set_exec_path(const char *path,int method); - -#endif /* !_EXEC_H_ */ diff --git a/g10/export.c b/g10/export.c deleted file mode 100644 index 43d1b21ed..000000000 --- a/g10/export.c +++ /dev/null @@ -1,546 +0,0 @@ -/* export.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "i18n.h" - -static int do_export( STRLIST users, int secret, unsigned int options ); -static int do_export_stream( iobuf_t out, STRLIST users, int secret, - KBNODE *keyblock_out, unsigned int options, - int *any ); -static int build_sexp (iobuf_t out, PACKET *pkt, int *indent); - -int -parse_export_options(char *str,unsigned int *options) -{ - struct parse_options export_opts[]= - { - {"include-non-rfc",EXPORT_INCLUDE_NON_RFC}, - {"include-local-sigs",EXPORT_INCLUDE_LOCAL_SIGS}, - {"include-attributes",EXPORT_INCLUDE_ATTRIBUTES}, - {"include-sensitive-revkeys",EXPORT_INCLUDE_SENSITIVE_REVKEYS}, - {"sexp-format",EXPORT_SEXP_FORMAT}, - {NULL,0} - /* add tags for include revoked and disabled? */ - }; - - return parse_options(str,options,export_opts); -} - -/**************** - * Export the public keys (to standard out or --output). - * Depending on opt.armor the output is armored. - * options are defined in main.h. - * If USERS is NULL, the complete ring will be exported. */ -int -export_pubkeys( STRLIST users, unsigned int options ) -{ - return do_export( users, 0, options ); -} - -/**************** - * Export to an already opened stream; return -1 if no keys have - * been exported - */ -int -export_pubkeys_stream( iobuf_t out, STRLIST users, - KBNODE *keyblock_out, unsigned int options ) -{ - int any, rc; - - rc = do_export_stream( out, users, 0, keyblock_out, options, &any ); - if( !rc && !any ) - rc = -1; - return rc; -} - -int -export_seckeys( STRLIST users ) -{ - /* Use only relevant options for the secret key. */ - unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT); - return do_export (users, 1, options); -} - -int -export_secsubkeys( STRLIST users ) -{ - /* Use only relevant options for the secret key. */ - unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT); - return do_export( users, 2, options); -} - -static int -do_export (STRLIST users, int secret, unsigned int options) -{ - iobuf_t out = NULL; - int any, rc; - armor_filter_context_t afx; - compress_filter_context_t zfx; - - memset (&afx, 0, sizeof afx); - memset (&zfx, 0, sizeof zfx); - - rc = open_outfile (NULL, 0, &out); - if (rc) - return rc; - - if (!(options & EXPORT_SEXP_FORMAT)) - { - if (opt.armor) - { - afx.what = secret?5:1; - iobuf_push_filter( out, armor_filter, &afx ); - } - if (opt.compress_keys && opt.compress) - iobuf_push_filter( out, compress_filter, &zfx ); - } - rc = do_export_stream (out, users, secret, NULL, options, &any ); - - if (rc || !any) - iobuf_cancel (out); - else - iobuf_close (out); - return rc; -} - - -/* If keyblock_out is non-NULL, AND the exit code is zero, then it - contains a pointer to the first keyblock found and exported. No - other keyblocks are exported. The caller must free it. */ -static int -do_export_stream( iobuf_t out, STRLIST users, int secret, - KBNODE *keyblock_out, unsigned int options, int *any ) -{ - int rc = 0; - PACKET pkt; - KBNODE keyblock = NULL; - KBNODE kbctx, node; - size_t ndesc, descindex; - KEYDB_SEARCH_DESC *desc = NULL; - KEYDB_HANDLE kdbhd; - STRLIST sl; - int indent = 0; - - *any = 0; - init_packet( &pkt ); - kdbhd = keydb_new (secret); - - if (!users) { - ndesc = 1; - desc = xcalloc (1, ndesc * sizeof *desc); - desc[0].mode = KEYDB_SEARCH_MODE_FIRST; - } - else { - for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) - ; - desc = xmalloc ( ndesc * sizeof *desc); - - for (ndesc=0, sl=users; sl; sl = sl->next) { - if (classify_user_id (sl->d, desc+ndesc)) - ndesc++; - else - log_error (_("key `%s' not found: %s\n"), - sl->d, gpg_strerror (GPG_ERR_INV_USER_ID)); - } - - /* it would be nice to see which of the given users did - actually match one in the keyring. To implement this we - need to have a found flag for each entry in desc and to set - this we must check all those entries after a match to mark - all matched one - currently we stop at the first match. To - do this we need an extra flag to enable this feature so */ - } - - while (!(rc = keydb_search2 (kdbhd, desc, ndesc, &descindex))) { - int sha1_warned=0,skip_until_subkey=0; - u32 sk_keyid[2]; - - if (!users) - desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - - /* read the keyblock */ - rc = keydb_get_keyblock (kdbhd, &keyblock ); - if( rc ) { - log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - /* do not export keys which are incompatible with rfc2440 */ - if( !(options&EXPORT_INCLUDE_NON_RFC) && - (node = find_kbnode( keyblock, PKT_PUBLIC_KEY )) ) { - PKT_public_key *pk = node->pkt->pkt.public_key; - if( pk->version == 3 && pk->pubkey_algo > 3 ) { - log_info(_("key %08lX: not a rfc2440 key - skipped\n"), - (ulong)keyid_from_pk( pk, NULL) ); - continue; - } - } - - node=find_kbnode( keyblock, PKT_SECRET_KEY ); - if(node) - { - PKT_secret_key *sk=node->pkt->pkt.secret_key; - - keyid_from_sk(sk,sk_keyid); - - /* we can't apply GNU mode 1001 on an unprotected key */ - if( secret == 2 && !sk->is_protected ) - { - log_info(_("key %08lX: not protected - skipped\n"), - (ulong)sk_keyid[1]); - continue; - } - - /* no v3 keys with GNU mode 1001 */ - if( secret == 2 && sk->version == 3 ) - { - log_info(_("key %08lX: PGP 2.x style key - skipped\n"), - (ulong)sk_keyid[1]); - continue; - } - } - - /* and write it */ - for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) { - if( skip_until_subkey ) - { - if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY - || node->pkt->pkttype==PKT_SECRET_SUBKEY) - skip_until_subkey=0; - else - continue; - } - - /* don't export any comment packets but those in the - * secret keyring */ - if( !secret && node->pkt->pkttype == PKT_COMMENT ) - continue; - - /* make sure that ring_trust packets never get exported */ - if (node->pkt->pkttype == PKT_RING_TRUST) - continue; - - /* If exact is set, then we only export what was requested - (plus the primary key, if the user didn't specifically - request it) */ - if(desc[descindex].exact - && (node->pkt->pkttype==PKT_PUBLIC_SUBKEY - || node->pkt->pkttype==PKT_SECRET_SUBKEY)) - { - u32 kid[2]; - byte fpr[MAX_FINGERPRINT_LEN]; - size_t fprlen; - - switch(desc[descindex].mode) - { - case KEYDB_SEARCH_MODE_SHORT_KID: - case KEYDB_SEARCH_MODE_LONG_KID: - if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY) - keyid_from_pk(node->pkt->pkt.public_key,kid); - else - keyid_from_sk(node->pkt->pkt.secret_key,kid); - break; - - case KEYDB_SEARCH_MODE_FPR16: - case KEYDB_SEARCH_MODE_FPR20: - case KEYDB_SEARCH_MODE_FPR: - if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY) - fingerprint_from_pk(node->pkt->pkt.public_key, - fpr,&fprlen); - else - fingerprint_from_sk(node->pkt->pkt.secret_key, - fpr,&fprlen); - break; - - default: - break; - } - - switch(desc[descindex].mode) - { - case KEYDB_SEARCH_MODE_SHORT_KID: - if (desc[descindex].u.kid[1] != kid[1]) - skip_until_subkey=1; - break; - case KEYDB_SEARCH_MODE_LONG_KID: - if (desc[descindex].u.kid[0] != kid[0] - || desc[descindex].u.kid[1] != kid[1]) - skip_until_subkey=1; - break; - case KEYDB_SEARCH_MODE_FPR16: - if (memcmp (desc[descindex].u.fpr, fpr, 16)) - skip_until_subkey=1; - break; - case KEYDB_SEARCH_MODE_FPR20: - case KEYDB_SEARCH_MODE_FPR: - if (memcmp (desc[descindex].u.fpr, fpr, 20)) - skip_until_subkey=1; - break; - default: - break; - } - - if(skip_until_subkey) - continue; - } - - if( node->pkt->pkttype == PKT_SIGNATURE ) { - /* do not export packets which are marked as not exportable */ - if( !(options&EXPORT_INCLUDE_LOCAL_SIGS) && - !node->pkt->pkt.signature->flags.exportable ) - continue; /* not exportable */ - - /* Do not export packets with a "sensitive" revocation - key unless the user wants us to. Note that we do - export these when issuing the actual revocation (see - revoke.c). */ - if( !(options&EXPORT_INCLUDE_SENSITIVE_REVKEYS) && - node->pkt->pkt.signature->revkey ) { - int i; - - for(i=0;i<node->pkt->pkt.signature->numrevkeys;i++) - if(node->pkt->pkt.signature->revkey[i]->class & 0x40) - break; - - if(i<node->pkt->pkt.signature->numrevkeys) - continue; - } - } - - /* Don't export attribs? */ - if( !(options&EXPORT_INCLUDE_ATTRIBUTES) && - node->pkt->pkttype == PKT_USER_ID && - node->pkt->pkt.user_id->attrib_data ) { - /* Skip until we get to something that is not an attrib - or a signature on an attrib */ - while(kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE) { - kbctx=kbctx->next; - } - - continue; - } - - if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY ) { - /* we don't want to export the secret parts of the - * primary key, this is done by using GNU protection mode 1001 - */ - int save_mode = node->pkt->pkt.secret_key->protect.s2k.mode; - node->pkt->pkt.secret_key->protect.s2k.mode = 1001; - if ((options&EXPORT_SEXP_FORMAT)) - rc = build_sexp (out, node->pkt, &indent); - else - rc = build_packet (out, node->pkt); - node->pkt->pkt.secret_key->protect.s2k.mode = save_mode; - } - else { - /* Warn the user if the secret key or any of the secret - subkeys are protected with SHA1 and we have - simple_sk_checksum set. */ - if(!sha1_warned && opt.simple_sk_checksum && - (node->pkt->pkttype==PKT_SECRET_KEY || - node->pkt->pkttype==PKT_SECRET_SUBKEY) && - node->pkt->pkt.secret_key->protect.sha1chk) - { - /* I hope this warning doesn't confuse people. */ - log_info(_("WARNING: secret key %08lX does not have a " - "simple SK checksum\n"),(ulong)sk_keyid[1]); - - sha1_warned=1; - } - - if ((options&EXPORT_SEXP_FORMAT)) - rc = build_sexp (out, node->pkt, &indent); - else - rc = build_packet (out, node->pkt); - } - - if( rc ) { - log_error("build_packet(%d) failed: %s\n", - node->pkt->pkttype, gpg_strerror (rc) ); - goto leave; - } - } - if ((options&EXPORT_SEXP_FORMAT) && indent) - { - for (; indent; indent--) - iobuf_put (out, ')'); - iobuf_put (out, '\n'); - } - - ++*any; - if(keyblock_out) - { - *keyblock_out=keyblock; - break; - } - } - if ((options&EXPORT_SEXP_FORMAT) && indent) - { - for (; indent; indent--) - iobuf_put (out, ')'); - iobuf_put (out, '\n'); - } - if( rc == -1 ) - rc = 0; - - leave: - xfree (desc); - keydb_release (kdbhd); - if(rc || keyblock_out==NULL) - release_kbnode( keyblock ); - if( !*any ) - log_info(_("WARNING: nothing exported\n")); - return rc; -} - - -static int -write_sexp_line (iobuf_t out, int *indent, const char *text) -{ - int i; - - for (i=0; i < *indent; i++) - iobuf_put (out, ' '); - iobuf_writestr (out, text); - return 0; -} - -static int -write_sexp_keyparm (iobuf_t out, int *indent, const char *name, gcry_mpi_t a) -{ - int rc; - unsigned char *buffer; - - write_sexp_line (out, indent, "("); - iobuf_writestr (out, name); - iobuf_writestr (out, " #"); - - rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a); - assert (!rc); - iobuf_writestr (out, buffer); - iobuf_writestr (out, "#)"); - gcry_free (buffer); - return 0; -} - -static int -build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent) -{ - PKT_secret_key *sk = pkt->pkt.secret_key; - char tmpbuf[100]; - - if (pkt->pkttype == PKT_SECRET_KEY) - { - iobuf_writestr (out, "(openpgp-key\n"); - (*indent)++; - } - else - { - iobuf_writestr (out, " (subkey\n"); - (*indent)++; - } - (*indent)++; - write_sexp_line (out, indent, "(private-key\n"); - (*indent)++; - if (is_RSA (sk->pubkey_algo) && !sk->is_protected) - { - write_sexp_line (out, indent, "(rsa\n"); - (*indent)++; - write_sexp_keyparm (out, indent, "n", sk->skey[0]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "e", sk->skey[1]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "d", sk->skey[2]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "p", sk->skey[3]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "q", sk->skey[4]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "u", sk->skey[5]); - iobuf_put (out,')'); iobuf_put (out,'\n'); - (*indent)--; - } - else if (sk->pubkey_algo == PUBKEY_ALGO_DSA && !sk->is_protected) - { - write_sexp_line (out, indent, "(dsa\n"); - (*indent)++; - write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "q", sk->skey[1]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "x", sk->skey[4]); - iobuf_put (out,')'); iobuf_put (out,'\n'); - (*indent)--; - } - else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected) - { - write_sexp_line (out, indent, "(elg\n"); - (*indent)++; - write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "x", sk->skey[4]); - iobuf_put (out,')'); iobuf_put (out,'\n'); - (*indent)--; - } - write_sexp_line (out, indent, "(attrib\n"); (*indent)++; - sprintf (tmpbuf, "(created \"%lu\"", (unsigned long)sk->timestamp); - write_sexp_line (out, indent, tmpbuf); - iobuf_put (out,')'); (*indent)--; /* close created */ - iobuf_put (out,')'); (*indent)--; /* close attrib */ - iobuf_put (out,')'); (*indent)--; /* close private-key */ - if (pkt->pkttype != PKT_SECRET_KEY) - iobuf_put (out,')'), (*indent)--; /* close subkey */ - iobuf_put (out,'\n'); - - return 0; -} - - -/* For some packet types we write them in a S-Exp like format. This is - still EXPERIMENTAL and subject to change. */ -static int -build_sexp (iobuf_t out, PACKET *pkt, int *indent) -{ - int rc; - - switch (pkt->pkttype) - { - case PKT_SECRET_KEY: - case PKT_SECRET_SUBKEY: - rc = build_sexp_seckey (out, pkt, indent); - break; - default: - rc = 0; - break; - } - return rc; -} - diff --git a/g10/filter.h b/g10/filter.h deleted file mode 100644 index 12c5cebed..000000000 --- a/g10/filter.h +++ /dev/null @@ -1,155 +0,0 @@ -/* filter.h - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_FILTER_H -#define G10_FILTER_H - -#include "types.h" -#include "cipher.h" -#include "iobuf.h" - -typedef struct { - MD_HANDLE md; /* catch all */ - MD_HANDLE md2; /* if we want to calculate an alternate hash */ - size_t maxbuf_size; -} md_filter_context_t; - -typedef struct { - /* these fields may be initialized */ - int what; /* what kind of armor headers to write */ - int only_keyblocks; /* skip all headers but ".... key block" */ - const char *hdrlines; /* write these headerlines */ - - /* these fileds must be initialized to zero */ - int no_openpgp_data; /* output flag: "No valid OpenPGP data found" */ - - /* the following fields must be initialized to zero */ - int inp_checked; /* set if the input has been checked */ - int inp_bypass; /* set if the input is not armored */ - int in_cleartext; /* clear text message */ - int not_dash_escaped; /* clear text is not dash escaped */ - int hashes; /* detected hash algorithms */ - int faked; /* we are faking a literal data packet */ - int truncated; /* number of truncated lines */ - int qp_detected; - int pgp2mode; - - byte *buffer; /* malloced buffer */ - unsigned buffer_size; /* and size of this buffer */ - unsigned buffer_len; /* used length of the buffer */ - unsigned buffer_pos; /* read position */ - - byte radbuf[4]; - int idx, idx2; - u32 crc; - - int status; /* an internal state flag */ - int cancel; - int any_data; /* any valid armored data seen */ - int pending_lf; /* used together with faked */ -} armor_filter_context_t; - -struct unarmor_pump_s; -typedef struct unarmor_pump_s *UnarmorPump; - - -struct compress_filter_context_s { - int status; - void *opaque; /* (used for z_stream) */ - byte *inbuf; - unsigned inbufsize; - byte *outbuf; - unsigned outbufsize; - int algo; /* compress algo */ - int algo1hack; - int new_ctb; - void (*release)(struct compress_filter_context_s*); -}; -typedef struct compress_filter_context_s compress_filter_context_t; - - -typedef struct { - DEK *dek; - u32 datalen; - CIPHER_HANDLE cipher_hd; - int header; - MD_HANDLE mdc_hash; - byte enchash[20]; - int create_mdc; /* flag will be set by the cipher filter */ -} cipher_filter_context_t; - - - -typedef struct { - byte *buffer; /* malloced buffer */ - unsigned buffer_size; /* and size of this buffer */ - unsigned buffer_len; /* used length of the buffer */ - unsigned buffer_pos; /* read position */ - int truncated; /* number of truncated lines */ - int not_dash_escaped; - int escape_from; - MD_HANDLE md; - int pending_lf; - int pending_esc; -} text_filter_context_t; - - -typedef struct { - char *what; /* description */ - u32 last_time; /* last time reported */ - unsigned long last; /* last amount reported */ - unsigned long offset; /* current amount */ - unsigned long total; /* total amount */ -} progress_filter_context_t; - -/* encrypt_filter_context_t defined in main.h */ - -/*-- mdfilter.c --*/ -int md_filter( void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len); -void free_md_filter_context( md_filter_context_t *mfx ); - -/*-- armor.c --*/ -int use_armor_filter( iobuf_t a ); -int armor_filter( void *opaque, int control, - iobuf_t chain, byte *buf, size_t *ret_len); -UnarmorPump unarmor_pump_new (void); -void unarmor_pump_release (UnarmorPump x); -int unarmor_pump (UnarmorPump x, int c); - -/*-- compress.c --*/ -int compress_filter( void *opaque, int control, - iobuf_t chain, byte *buf, size_t *ret_len); - -/*-- cipher.c --*/ -int cipher_filter( void *opaque, int control, - iobuf_t chain, byte *buf, size_t *ret_len); - -/*-- textfilter.c --*/ -int text_filter( void *opaque, int control, - iobuf_t chain, byte *buf, size_t *ret_len); -int copy_clearsig_text( iobuf_t out, iobuf_t inp, MD_HANDLE md, - int escape_dash, int escape_from, int pgp2mode ); - -/*-- progress.c --*/ -int progress_filter (void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len); -void handle_progress (progress_filter_context_t *pfx, - iobuf_t inp, const char *name); - -#endif /*G10_FILTER_H*/ diff --git a/g10/free-packet.c b/g10/free-packet.c deleted file mode 100644 index 7ced327f5..000000000 --- a/g10/free-packet.c +++ /dev/null @@ -1,542 +0,0 @@ -/* free-packet.c - cleanup stuff for packets - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 - * Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "packet.h" -#include "iobuf.h" -#include "mpi.h" -#include "util.h" -#include "cipher.h" -#include "memory.h" -#include "options.h" - -void -free_symkey_enc( PKT_symkey_enc *enc ) -{ - xfree (enc); -} - -void -free_pubkey_enc( PKT_pubkey_enc *enc ) -{ - int n, i; - n = pubkey_get_nenc( enc->pubkey_algo ); - if( !n ) - mpi_release (enc->data[0]); - for(i=0; i < n; i++ ) - mpi_release ( enc->data[i] ); - xfree (enc); -} - -void -free_seckey_enc( PKT_signature *sig ) -{ - int n, i; - - n = pubkey_get_nsig( sig->pubkey_algo ); - if( !n ) - mpi_release (sig->data[0]); - for(i=0; i < n; i++ ) - mpi_release ( sig->data[i] ); - - xfree (sig->revkey); - xfree (sig->hashed); - xfree (sig->unhashed); - xfree (sig); -} - - -void -release_public_key_parts( PKT_public_key *pk ) -{ - int n, i; - n = pubkey_get_npkey( pk->pubkey_algo ); - if( !n ) - mpi_release (pk->pkey[0]); - for(i=0; i < n; i++ ) { - mpi_release ( pk->pkey[i] ); - pk->pkey[i] = NULL; - } - if (pk->prefs) { - xfree (pk->prefs); - pk->prefs = NULL; - } - if (pk->user_id) { - free_user_id (pk->user_id); - pk->user_id = NULL; - } - if (pk->revkey) { - xfree (pk->revkey); - pk->revkey=NULL; - pk->numrevkeys=0; - } -} - - -void -free_public_key( PKT_public_key *pk ) -{ - release_public_key_parts( pk ); - xfree (pk); -} - - -static subpktarea_t * -cp_subpktarea (subpktarea_t *s ) -{ - subpktarea_t *d; - - if( !s ) - return NULL; - d = xmalloc (sizeof (*d) + s->size - 1 ); - d->size = s->size; - d->len = s->len; - memcpy (d->data, s->data, s->len); - return d; -} - -/* - * Return a copy of the preferences - */ -prefitem_t * -copy_prefs (const prefitem_t *prefs) -{ - size_t n; - prefitem_t *new; - - if (!prefs) - return NULL; - - for (n=0; prefs[n].type; n++) - ; - new = xmalloc ( sizeof (*new) * (n+1)); - for (n=0; prefs[n].type; n++) { - new[n].type = prefs[n].type; - new[n].value = prefs[n].value; - } - new[n].type = PREFTYPE_NONE; - new[n].value = 0; - - return new; -} - - -PKT_public_key * -copy_public_key ( PKT_public_key *d, PKT_public_key *s) -{ - int n, i; - - if( !d ) - d = xmalloc (sizeof *d); - memcpy( d, s, sizeof *d ); - d->user_id = scopy_user_id (s->user_id); - d->prefs = copy_prefs (s->prefs); - n = pubkey_get_npkey( s->pubkey_algo ); - if( !n ) - d->pkey[0] = mpi_copy(s->pkey[0]); - else { - for(i=0; i < n; i++ ) - d->pkey[i] = mpi_copy( s->pkey[i] ); - } - if( !s->revkey && s->numrevkeys ) - BUG(); - if( s->numrevkeys ) { - d->revkey = xmalloc (sizeof(struct revocation_key)*s->numrevkeys); - memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys); - } - else - d->revkey = NULL; - return d; -} - -/**************** - * Replace all common parts of a sk by the one from the public key. - * This is a hack and a better solution will be to just store the real secret - * parts somewhere and don't duplicate all the other stuff. - */ -void -copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk ) -{ - sk->expiredate = pk->expiredate; - sk->pubkey_algo = pk->pubkey_algo; - sk->pubkey_usage= pk->pubkey_usage; - sk->req_usage = pk->req_usage; - sk->req_algo = pk->req_algo; - sk->has_expired = pk->has_expired; - sk->is_revoked = pk->is_revoked; - sk->is_valid = pk->is_valid; - sk->main_keyid[0]= pk->main_keyid[0]; - sk->main_keyid[1]= pk->main_keyid[1]; - sk->keyid[0] = pk->keyid[0]; - sk->keyid[1] = pk->keyid[1]; -} - -PKT_signature * -copy_signature( PKT_signature *d, PKT_signature *s ) -{ - int n, i; - - if( !d ) - d = xmalloc (sizeof *d); - memcpy( d, s, sizeof *d ); - n = pubkey_get_nsig( s->pubkey_algo ); - if( !n ) - d->data[0] = mpi_copy(s->data[0]); - else { - for(i=0; i < n; i++ ) - d->data[i] = mpi_copy( s->data[i] ); - } - d->hashed = cp_subpktarea (s->hashed); - d->unhashed = cp_subpktarea (s->unhashed); - if(s->numrevkeys) - { - d->revkey=NULL; - d->numrevkeys=0; - parse_revkeys(d); - } - return d; -} - - -/* - * shallow copy of the user ID - */ -PKT_user_id * -scopy_user_id (PKT_user_id *s) -{ - if (s) - s->ref++; - return s; -} - - - -void -release_secret_key_parts( PKT_secret_key *sk ) -{ - int n, i; - - n = pubkey_get_nskey( sk->pubkey_algo ); - if( !n ) - mpi_release (sk->skey[0]); - for(i=0; i < n; i++ ) { - mpi_release ( sk->skey[i] ); - sk->skey[i] = NULL; - } -} - -void -free_secret_key( PKT_secret_key *sk ) -{ - release_secret_key_parts( sk ); - xfree (sk); -} - -PKT_secret_key * -copy_secret_key( PKT_secret_key *d, PKT_secret_key *s ) -{ - int n, i; - - if( !d ) - d = xmalloc (sizeof *d); - memcpy( d, s, sizeof *d ); - n = pubkey_get_nskey( s->pubkey_algo ); - if( !n ) - d->skey[0] = mpi_copy(s->skey[0]); - else { - for(i=0; i < n; i++ ) - d->skey[i] = mpi_copy( s->skey[i] ); - } - return d; -} - -void -free_comment( PKT_comment *rem ) -{ - xfree (rem); -} - -void -free_attributes(PKT_user_id *uid) -{ - xfree (uid->attribs); - xfree (uid->attrib_data); - - uid->attribs=NULL; - uid->attrib_data=NULL; - uid->attrib_len=0; -} - -void -free_user_id (PKT_user_id *uid) -{ - assert (uid->ref > 0); - if (--uid->ref) - return; - - free_attributes(uid); - xfree (uid->prefs); - xfree (uid->namehash); - xfree (uid); -} - -void -free_compressed( PKT_compressed *zd ) -{ - if( zd->buf ) { /* have to skip some bytes */ - /* don't have any information about the length, so - * we assume this is the last packet */ - while( iobuf_read( zd->buf, NULL, 1<<30 ) != -1 ) - ; - } - xfree (zd); -} - -void -free_encrypted( PKT_encrypted *ed ) -{ - if( ed->buf ) { /* have to skip some bytes */ - if( iobuf_in_block_mode(ed->buf) ) { - while( iobuf_read( ed->buf, NULL, 1<<30 ) != -1 ) - ; - } - else { - while( ed->len ) { /* skip the packet */ - int n = iobuf_read( ed->buf, NULL, ed->len ); - if( n == -1 ) - ed->len = 0; - else - ed->len -= n; - } - } - } - xfree (ed); -} - - -void -free_plaintext( PKT_plaintext *pt ) -{ - if( pt->buf ) { /* have to skip some bytes */ - if( iobuf_in_block_mode(pt->buf) ) { - while( iobuf_read( pt->buf, NULL, 1<<30 ) != -1 ) - ; - } - else { - while( pt->len ) { /* skip the packet */ - int n = iobuf_read( pt->buf, NULL, pt->len ); - if( n == -1 ) - pt->len = 0; - else - pt->len -= n; - } - } - } - xfree (pt); -} - -/**************** - * Free the packet in pkt. - */ -void -free_packet( PACKET *pkt ) -{ - if( !pkt || !pkt->pkt.generic ) - return; - - if( DBG_MEMORY ) - log_debug("free_packet() type=%d\n", pkt->pkttype ); - - switch( pkt->pkttype ) { - case PKT_SIGNATURE: - free_seckey_enc( pkt->pkt.signature ); - break; - case PKT_PUBKEY_ENC: - free_pubkey_enc( pkt->pkt.pubkey_enc ); - break; - case PKT_SYMKEY_ENC: - free_symkey_enc( pkt->pkt.symkey_enc ); - break; - case PKT_PUBLIC_KEY: - case PKT_PUBLIC_SUBKEY: - free_public_key( pkt->pkt.public_key ); - break; - case PKT_SECRET_KEY: - case PKT_SECRET_SUBKEY: - free_secret_key( pkt->pkt.secret_key ); - break; - case PKT_COMMENT: - free_comment( pkt->pkt.comment ); - break; - case PKT_USER_ID: - free_user_id( pkt->pkt.user_id ); - break; - case PKT_COMPRESSED: - free_compressed( pkt->pkt.compressed); - break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: - free_encrypted( pkt->pkt.encrypted ); - break; - case PKT_PLAINTEXT: - free_plaintext( pkt->pkt.plaintext ); - break; - default: - xfree ( pkt->pkt.generic ); - break; - } - pkt->pkt.generic = NULL; -} - -/**************** - * returns 0 if they match. - */ -int -cmp_public_keys( PKT_public_key *a, PKT_public_key *b ) -{ - int n, i; - - if( a->timestamp != b->timestamp ) - return -1; - if( a->version < 4 && a->expiredate != b->expiredate ) - return -1; - if( a->pubkey_algo != b->pubkey_algo ) - return -1; - - n = pubkey_get_npkey( b->pubkey_algo ); - if( !n ) - return -1; /* can't compare due to unknown algorithm */ - for(i=0; i < n; i++ ) { - if( mpi_cmp( a->pkey[i], b->pkey[i] ) ) - return -1; - } - - return 0; -} - -/**************** - * Returns 0 if they match. - * We only compare the public parts. - */ -int -cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b ) -{ - int n, i; - - if( a->timestamp != b->timestamp ) - return -1; - if( a->version < 4 && a->expiredate != b->expiredate ) - return -1; - if( a->pubkey_algo != b->pubkey_algo ) - return -1; - - n = pubkey_get_npkey( b->pubkey_algo ); - if( !n ) - return -1; /* can't compare due to unknown algorithm */ - for(i=0; i < n; i++ ) { - if( mpi_cmp( a->skey[i], b->skey[i] ) ) - return -1; - } - - return 0; -} - -/**************** - * Returns 0 if they match. - */ -int -cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk ) -{ - int n, i; - - if( pk->timestamp != sk->timestamp ) - return -1; - if( pk->version < 4 && pk->expiredate != sk->expiredate ) - return -1; - if( pk->pubkey_algo != sk->pubkey_algo ) - return -1; - - n = pubkey_get_npkey( pk->pubkey_algo ); - if( !n ) - return -1; /* can't compare due to unknown algorithm */ - for(i=0; i < n; i++ ) { - if( mpi_cmp( pk->pkey[i] , sk->skey[i] ) ) - return -1; - } - return 0; -} - - - -int -cmp_signatures( PKT_signature *a, PKT_signature *b ) -{ - int n, i; - - if( a->keyid[0] != b->keyid[0] ) - return -1; - if( a->keyid[1] != b->keyid[1] ) - return -1; - if( a->pubkey_algo != b->pubkey_algo ) - return -1; - - n = pubkey_get_nsig( a->pubkey_algo ); - if( !n ) - return -1; /* can't compare due to unknown algorithm */ - for(i=0; i < n; i++ ) { - if( mpi_cmp( a->data[i] , b->data[i] ) ) - return -1; - } - return 0; -} - - -/**************** - * Returns: true if the user ids do not match - */ -int -cmp_user_ids( PKT_user_id *a, PKT_user_id *b ) -{ - int res=1; - - if( a == b ) - return 0; - - if( a->attrib_data && b->attrib_data ) - { - res = a->attrib_len - b->attrib_len; - if( !res ) - res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len ); - } - else if( !a->attrib_data && !b->attrib_data ) - { - res = a->len - b->len; - if( !res ) - res = memcmp( a->name, b->name, a->len ); - } - - return res; -} diff --git a/g10/g10.c b/g10/g10.c deleted file mode 100644 index 915011026..000000000 --- a/g10/g10.c +++ /dev/null @@ -1,3367 +0,0 @@ -/* g10.c - The GnuPG utility (main for gpg) - * Copyright (C) 1998,1999,2000,2001,2002,2003 - * 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#include <assert.h> -#ifdef HAVE_DOSISH_SYSTEM -#include <fcntl.h> /* for setmode() */ -#endif -#ifdef HAVE_STAT -#include <sys/stat.h> /* for stat() */ -#endif -#include <assuan.h> - -#define INCLUDED_BY_MAIN_MODULE 1 -#include "gpg.h" -#include "packet.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "options.h" -#include "keydb.h" -#include "trustdb.h" -#include "mpi.h" -#include "cipher.h" -#include "filter.h" -#include "ttyio.h" -#include "i18n.h" -#include "status.h" -#include "keyserver-internal.h" -#include "exec.h" - -enum cmd_and_opt_values { aNull = 0, - oArmor = 'a', - aDetachedSign = 'b', - aSym = 'c', - aDecrypt = 'd', - aEncr = 'e', - oInteractive = 'i', - aListKeys = 'k', - aListSecretKeys = 'K', - oDryRun = 'n', - oOutput = 'o', - oQuiet = 'q', - oRecipient = 'r', - oHiddenRecipient = 'R', - aSign = 's', - oTextmodeShort= 't', - oUser = 'u', - oVerbose = 'v', - oCompress = 'z', - oSetNotation = 'N', - oBatch = 500, - aGPGConfList, - oSigNotation, - oCertNotation, - oShowNotation, - oNoShowNotation, - aEncrFiles, - aDecryptFiles, - aClearsign, - aStore, - aKeygen, - aSignEncr, - aSignSym, - aSignKey, - aLSignKey, - aNRSignKey, - aNRLSignKey, - aListPackets, - aEditKey, - aDeleteKeys, - aDeleteSecretKeys, - aDeleteSecretAndPublicKeys, - aImport, - aFastImport, - aVerify, - aVerifyFiles, - aListSigs, - aSendKeys, - aRecvKeys, - aSearchKeys, - aExport, - aExportAll, - aExportSecret, - aExportSecretSub, - aCheckKeys, - aGenRevoke, - aDesigRevoke, - aPrimegen, - aPrintMD, - aPrintMDs, - aCheckTrustDB, - aUpdateTrustDB, - aFixTrustDB, - aListTrustDB, - aListTrustPath, - aExportOwnerTrust, - aListOwnerTrust, - aImportOwnerTrust, - aDeArmor, - aEnArmor, - aGenRandom, - aPipeMode, - aRebuildKeydbCaches, - aRefreshKeys, - aCardStatus, - aCardEdit, - aChangePIN, - - oTextmode, - oNoTextmode, - oExpert, - oNoExpert, - oAskSigExpire, - oNoAskSigExpire, - oAskCertExpire, - oNoAskCertExpire, - oFingerprint, - oWithFingerprint, - oAnswerYes, - oAnswerNo, - oDefCertCheckLevel, - oKeyring, - oPrimaryKeyring, - oSecretKeyring, - oShowKeyring, - oDefaultKey, - oDefRecipient, - oDefRecipientSelf, - oNoDefRecipient, - oOptions, - oDebug, - oDebugLevel, - oDebugAll, - oStatusFD, -#ifdef __riscos__ - oStatusFile, -#endif /* __riscos__ */ - oAttributeFD, -#ifdef __riscos__ - oAttributeFile, -#endif /* __riscos__ */ - oSKComments, - oNoSKComments, - oEmitVersion, - oNoEmitVersion, - oCompletesNeeded, - oMarginalsNeeded, - oMaxCertDepth, - oLoadExtension, - oGnuPG, - oRFC1991, - oRFC2440, - oOpenPGP, - oPGP2, - oPGP6, - oPGP7, - oPGP8, - oCipherAlgo, - oDigestAlgo, - oCertDigestAlgo, - oCompressAlgo, - oPasswdFD, -#ifdef __riscos__ - oPasswdFile, -#endif /* __riscos__ */ - oCommandFD, -#ifdef __riscos__ - oCommandFile, -#endif /* __riscos__ */ - oQuickRandom, - oNoVerbose, - oTrustDBName, - oNoSecmemWarn, - oNoPermissionWarn, - oNoMDCWarn, - oNoArmor, - oNoDefKeyring, - oNoGreeting, - oNoTTY, - oNoOptions, - oNoBatch, - oHomedir, - oWithColons, - oWithKeyData, - oSkipVerify, - oCompressKeys, - oCompressSigs, - oAlwaysTrust, - oTrustModel, - oForceOwnertrust, - oEmuChecksumBug, - oSetFilename, - oForYourEyesOnly, - oNoForYourEyesOnly, - oSetPolicyURL, - oSigPolicyURL, - oCertPolicyURL, - oShowPolicyURL, - oNoShowPolicyURL, - oSigKeyserverURL, - oUseEmbeddedFilename, - oComment, - oDefaultComment, - oNoComments, - oThrowKeyid, - oNoThrowKeyid, - oShowPhotos, - oNoShowPhotos, - oPhotoViewer, - oForceV3Sigs, - oNoForceV3Sigs, - oForceV4Certs, - oNoForceV4Certs, - oForceMDC, - oNoForceMDC, - oDisableMDC, - oNoDisableMDC, - oS2KMode, - oS2KDigest, - oS2KCipher, - oSimpleSKChecksum, - oCharset, - oNotDashEscaped, - oEscapeFrom, - oNoEscapeFrom, - oLockOnce, - oLockMultiple, - oLockNever, - oKeyServer, - oKeyServerOptions, - oImportOptions, - oExportOptions, - oListOptions, - oVerifyOptions, - oTempDir, - oExecPath, - oEncryptTo, - oHiddenEncryptTo, - oNoEncryptTo, - oLogFile, - oLoggerFD, -#ifdef __riscos__ - oLoggerFile, -#endif /* __riscos__ */ - oUtf8Strings, - oNoUtf8Strings, - oDisableCipherAlgo, - oDisablePubkeyAlgo, - oAllowNonSelfsignedUID, - oNoAllowNonSelfsignedUID, - oAllowFreeformUID, - oNoAllowFreeformUID, - oAllowSecretKeyImport, - oEnableSpecialFilenames, - oNoLiteral, - oSetFilesize, - oHonorHttpProxy, - oFastListMode, - oListOnly, - oIgnoreTimeConflict, - oIgnoreValidFrom, - oIgnoreCrcError, - oIgnoreMDCError, - oShowSessionKey, - oOverrideSessionKey, - oNoRandomSeedFile, - oAutoKeyRetrieve, - oNoAutoKeyRetrieve, - oUseAgent, - oNoUseAgent, - oGpgAgentInfo, - oMergeOnly, - oTryAllSecrets, - oTrustedKey, - oNoExpensiveTrustChecks, - oFixedListMode, - oNoSigCache, - oNoSigCreateCheck, - oAutoCheckTrustDB, - oNoAutoCheckTrustDB, - oPreservePermissions, - oDefaultPreferenceList, - oPersonalCipherPreferences, - oPersonalDigestPreferences, - oPersonalCompressPreferences, - oEmuMDEncodeBug, - oAgentProgram, - oDisplay, - oTTYname, - oTTYtype, - oLCctype, - oLCmessages, - oGroup, - oStrict, - oNoStrict, - oMangleDosFilenames, - oNoMangleDosFilenames, - oEnableProgressFilter, - oMultifile, -aTest }; - - -static ARGPARSE_OPTS opts[] = { - - { 300, NULL, 0, N_("@Commands:\n ") }, - - { aSign, "sign", 256, N_("|[file]|make a signature")}, - { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature") }, - { aDetachedSign, "detach-sign", 256, N_("make a detached signature")}, - { aEncr, "encrypt", 256, N_("encrypt data")}, - { aEncrFiles, "encrypt-files", 256, "@"}, - { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")}, - { aStore, "store", 256, "@"}, - { aDecrypt, "decrypt", 256, N_("decrypt data (default)")}, - { aDecryptFiles, "decrypt-files", 256, "@"}, - { aVerify, "verify" , 256, N_("verify a signature")}, - { aVerifyFiles, "verify-files" , 256, "@" }, - { aListKeys, "list-keys", 256, N_("list keys")}, - { aListKeys, "list-public-keys", 256, "@" }, - { aListSigs, "list-sigs", 256, N_("list keys and signatures")}, - { aCheckKeys, "check-sigs",256, N_("list and check key signatures")}, - { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")}, - { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")}, - { aKeygen, "gen-key", 256, N_("generate a new key pair")}, - { aDeleteKeys,"delete-keys",256,N_("remove keys from the public keyring")}, - { aDeleteSecretKeys, "delete-secret-keys",256, - N_("remove keys from the secret keyring")}, - { aSignKey, "sign-key" ,256, N_("sign a key")}, - { aLSignKey, "lsign-key" ,256, N_("sign a key locally")}, - { aNRSignKey, "nrsign-key" ,256, "@"}, - { aNRLSignKey, "nrlsign-key" ,256, "@"}, - { aEditKey, "edit-key" ,256, N_("sign or edit a key")}, - { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")}, - { aDesigRevoke, "desig-revoke",256, "@" }, - { aExport, "export" , 256, N_("export keys") }, - { aSendKeys, "send-keys" , 256, N_("export keys to a key server") }, - { aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") }, - { aSearchKeys, "search-keys" , 256, - N_("search for keys on a key server") }, - { aRefreshKeys, "refresh-keys", 256, - N_("update all keys from a keyserver")}, - { aExportAll, "export-all" , 256, "@" }, - { aExportSecret, "export-secret-keys" , 256, "@" }, - { aExportSecretSub, "export-secret-subkeys" , 256, "@" }, - { aImport, "import", 256 , N_("import/merge keys")}, - { aFastImport, "fast-import", 256 , "@"}, - { aCardStatus, "card-status", 256, N_("print the card status")}, - { aCardEdit, "card-edit", 256, N_("change data on a card")}, - { aChangePIN, "change-pin", 256, N_("change a card's PIN")}, - - { aListPackets, "list-packets",256, "@"}, - { aExportOwnerTrust, "export-ownertrust", 256, "@"}, - { aImportOwnerTrust, "import-ownertrust", 256, "@"}, - { aUpdateTrustDB, "update-trustdb",0 , N_("update the trust database")}, - { aCheckTrustDB, "check-trustdb",0 , "@"}, - { aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")}, - { aDeArmor, "dearmor", 256, "@" }, - { aDeArmor, "dearmour", 256, "@" }, - { aEnArmor, "enarmor", 256, "@" }, - { aEnArmor, "enarmour", 256, "@" }, - { aPrintMD, "print-md" , 256, N_("|algo [files]|print message digests")}, - { aPrimegen, "gen-prime" , 256, "@" }, - { aGenRandom, "gen-random" , 256, "@" }, - { aGPGConfList, "gpgconf-list", 256, "@" }, - - { 301, NULL, 0, N_("@\nOptions:\n ") }, - - { oArmor, "armor", 0, N_("create ascii armored output")}, - { oArmor, "armour", 0, "@" }, - { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")}, - { oHiddenRecipient, "hidden-recipient", 2, "@" }, - { oRecipient, "remote-user", 2, "@"}, /* old option name */ - { oDefRecipient, "default-recipient" ,2, "@" }, - { oDefRecipientSelf, "default-recipient-self" ,0, "@" }, - { oNoDefRecipient, "no-default-recipient", 0, "@" }, - { oTempDir, "temp-directory", 2, "@" }, - { oExecPath, "exec-path", 2, "@" }, - { oEncryptTo, "encrypt-to", 2, "@" }, - { oHiddenEncryptTo, "hidden-encrypt-to", 2, "@" }, - { oNoEncryptTo, "no-encrypt-to", 0, "@" }, - { oUser, "local-user",2, N_("use this user-id to sign or decrypt")}, - { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") }, - { oTextmodeShort, NULL, 0, "@"}, - { oTextmode, "textmode", 0, N_("use canonical text mode")}, - { oNoTextmode, "no-textmode", 0, "@"}, - { oExpert, "expert", 0, "@"}, - { oNoExpert, "no-expert", 0, "@"}, - { oAskSigExpire, "ask-sig-expire", 0, "@"}, - { oNoAskSigExpire, "no-ask-sig-expire", 0, "@"}, - { oAskCertExpire, "ask-cert-expire", 0, "@"}, - { oNoAskCertExpire, "no-ask-cert-expire", 0, "@"}, - { oOutput, "output", 2, N_("use as output file")}, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, "@" }, - { oNoTTY, "no-tty", 0, "@" }, - { oLogFile, "log-file" ,2, "@" }, - { oForceV3Sigs, "force-v3-sigs", 0, "@" }, - { oNoForceV3Sigs, "no-force-v3-sigs", 0, "@" }, - { oForceV4Certs, "force-v4-certs", 0, "@" }, - { oNoForceV4Certs, "no-force-v4-certs", 0, "@" }, - { oForceMDC, "force-mdc", 0, "@" }, - { oNoForceMDC, "no-force-mdc", 0, "@" }, - { oDisableMDC, "disable-mdc", 0, "@" }, - { oNoDisableMDC, "no-disable-mdc", 0, "@" }, - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - { oInteractive, "interactive", 0, N_("prompt before overwriting") }, - { oUseAgent, "use-agent",0, "@"}, - { oNoUseAgent, "no-use-agent",0, "@"}, - { oGpgAgentInfo, "gpg-agent-info",2, "@"}, - { oBatch, "batch", 0, "@"}, - { oAnswerYes, "yes", 0, "@"}, - { oAnswerNo, "no", 0, "@"}, - { oKeyring, "keyring" , 2, "@"}, - { oPrimaryKeyring, "primary-keyring",2, "@" }, - { oSecretKeyring, "secret-keyring" ,2, "@"}, - { oShowKeyring, "show-keyring", 0, "@"}, - { oDefaultKey, "default-key" , 2, "@"}, - { oKeyServer, "keyserver", 2, "@"}, - { oKeyServerOptions, "keyserver-options",2,"@"}, - { oImportOptions, "import-options",2,"@"}, - { oExportOptions, "export-options",2,"@"}, - { oListOptions, "list-options",2,"@"}, - { oVerifyOptions, "verify-options",2,"@"}, - { oCharset, "charset" , 2, "@" }, - { oOptions, "options" , 2, "@"}, - - { oDebug, "debug" ,4|16, "@"}, - { oDebugLevel, "debug-level" ,2, "@"}, - { oDebugAll, "debug-all" ,0, "@"}, - { oStatusFD, "status-fd" ,1, "@" }, -#ifdef __riscos__ - { oStatusFile, "status-file" ,2, "@" }, -#endif /* __riscos__ */ - { oAttributeFD, "attribute-fd" ,1, "@" }, -#ifdef __riscos__ - { oAttributeFile, "attribute-file" ,2, "@" }, -#endif /* __riscos__ */ - { oNoSKComments, "no-sk-comments", 0, "@"}, - { oSKComments, "sk-comments", 0, "@"}, - { oCompletesNeeded, "completes-needed", 1, "@"}, - { oMarginalsNeeded, "marginals-needed", 1, "@"}, - { oMaxCertDepth, "max-cert-depth", 1, "@" }, - { oTrustedKey, "trusted-key", 2, "@"}, - { oLoadExtension, "load-extension" ,2, "@"}, - { oGnuPG, "gnupg", 0, "@"}, - { oGnuPG, "no-pgp2", 0, "@"}, - { oGnuPG, "no-pgp6", 0, "@"}, - { oGnuPG, "no-pgp7", 0, "@"}, - { oGnuPG, "no-pgp8", 0, "@"}, - { oRFC1991, "rfc1991", 0, "@"}, - { oRFC2440, "rfc2440", 0, "@"}, - { oOpenPGP, "openpgp", 0, N_("use strict OpenPGP behavior")}, - { oPGP2, "pgp2", 0, N_("generate PGP 2.x compatible messages")}, - { oPGP6, "pgp6", 0, "@"}, - { oPGP7, "pgp7", 0, "@"}, - { oPGP8, "pgp8", 0, "@"}, - { oS2KMode, "s2k-mode", 1, "@"}, - { oS2KDigest, "s2k-digest-algo",2, "@"}, - { oS2KCipher, "s2k-cipher-algo",2, "@"}, - { oSimpleSKChecksum, "simple-sk-checksum", 0, "@"}, - { oCipherAlgo, "cipher-algo", 2 , "@"}, - { oDigestAlgo, "digest-algo", 2 , "@"}, - { oCertDigestAlgo, "cert-digest-algo", 2 , "@" }, - { oCompressAlgo,"compress-algo",2, "@"}, - { oThrowKeyid, "throw-keyid", 0, "@"}, - { oNoThrowKeyid, "no-throw-keyid", 0, "@" }, - { oShowPhotos, "show-photos", 0, "@" }, - { oNoShowPhotos, "no-show-photos", 0, "@" }, - { oPhotoViewer, "photo-viewer", 2, "@" }, - { oSetNotation, "set-notation", 2, "@" }, - { oSetNotation, "notation-data", 2, "@" }, /* Alias */ - { oSigNotation, "sig-notation", 2, "@" }, - { oCertNotation, "cert-notation", 2, "@" }, - - { 302, NULL, 0, N_( - "@\n(See the man page for a complete listing of all commands and options)\n" - )}, - - { 303, NULL, 0, N_("@\nExamples:\n\n" - " -se -r Bob [file] sign and encrypt for user Bob\n" - " --clearsign [file] make a clear text signature\n" - " --detach-sign [file] make a detached signature\n" - " --list-keys [names] show keys\n" - " --fingerprint [names] show fingerprints\n" ) }, - - /* hidden options */ - { aListOwnerTrust, "list-ownertrust", 256, "@"}, /* deprecated */ - { oCompressAlgo, "compression-algo", 1, "@"}, /* alias */ - { aPrintMDs, "print-mds" , 256, "@"}, /* old */ - { aListTrustDB, "list-trustdb",0 , "@"}, - /* Not yet used */ - /* { aListTrustPath, "list-trust-path",0, "@"}, */ - { aPipeMode, "pipemode", 0, "@" }, - { oPasswdFD, "passphrase-fd",1, "@" }, -#ifdef __riscos__ - { oPasswdFile, "passphrase-file",2, "@" }, -#endif /* __riscos__ */ - { oCommandFD, "command-fd",1, "@" }, -#ifdef __riscos__ - { oCommandFile, "command-file",2, "@" }, -#endif /* __riscos__ */ - { oQuickRandom, "quick-random", 0, "@"}, - { oNoVerbose, "no-verbose", 0, "@"}, - { oTrustDBName, "trustdb-name", 2, "@" }, - { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */ - { oNoPermissionWarn, "no-permission-warning", 0, "@" }, - { oNoMDCWarn, "no-mdc-warning", 0, "@" }, - { oNoArmor, "no-armor", 0, "@"}, - { oNoArmor, "no-armour", 0, "@"}, - { oNoDefKeyring, "no-default-keyring", 0, "@" }, - { oNoGreeting, "no-greeting", 0, "@" }, - { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */ - { oHomedir, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */ - { oNoBatch, "no-batch", 0, "@" }, - { oWithColons, "with-colons", 0, "@"}, - { oWithKeyData,"with-key-data", 0, "@"}, - { aListKeys, "list-key", 0, "@" }, /* alias */ - { aListSigs, "list-sig", 0, "@" }, /* alias */ - { aCheckKeys, "check-sig",0, "@" }, /* alias */ - { oSkipVerify, "skip-verify",0, "@" }, - { oCompressKeys, "compress-keys",0, "@"}, - { oCompressSigs, "compress-sigs",0, "@"}, - { oDefCertCheckLevel, "default-cert-check-level", 1, "@"}, - { oAlwaysTrust, "always-trust", 0, "@"}, - { oTrustModel, "trust-model", 2, "@"}, - { oForceOwnertrust, "force-ownertrust", 2, "@"}, - { oEmuChecksumBug, "emulate-checksum-bug", 0, "@"}, - { oSetFilename, "set-filename", 2, "@" }, - { oForYourEyesOnly, "for-your-eyes-only", 0, "@" }, - { oNoForYourEyesOnly, "no-for-your-eyes-only", 0, "@" }, - { oSetPolicyURL, "set-policy-url", 2, "@" }, - { oSigPolicyURL, "sig-policy-url", 2, "@" }, - { oCertPolicyURL, "cert-policy-url", 2, "@" }, - { oShowPolicyURL, "show-policy-url", 0, "@" }, - { oNoShowPolicyURL, "no-show-policy-url", 0, "@" }, - { oShowNotation, "show-notation", 0, "@" }, - { oNoShowNotation, "no-show-notation", 0, "@" }, - { oSigKeyserverURL, "sig-keyserver-url", 2, "@" }, - { oComment, "comment", 2, "@" }, - { oDefaultComment, "default-comment", 0, "@" }, - { oNoComments, "no-comments", 0, "@" }, - { oEmitVersion, "emit-version", 0, "@"}, - { oNoEmitVersion, "no-emit-version", 0, "@"}, - { oNoEmitVersion, "no-version", 0, "@"}, /* alias */ - { oNotDashEscaped, "not-dash-escaped", 0, "@" }, - { oEscapeFrom, "escape-from-lines", 0, "@" }, - { oNoEscapeFrom, "no-escape-from-lines", 0, "@" }, - { oLockOnce, "lock-once", 0, "@" }, - { oLockMultiple, "lock-multiple", 0, "@" }, - { oLockNever, "lock-never", 0, "@" }, - { oLoggerFD, "logger-fd",1, "@" }, -#ifdef __riscos__ - { oLoggerFile, "logger-file",2, "@" }, -#endif /* __riscos__ */ - { oUseEmbeddedFilename, "use-embedded-filename", 0, "@" }, - { oUtf8Strings, "utf8-strings", 0, "@" }, - { oNoUtf8Strings, "no-utf8-strings", 0, "@" }, - { oWithFingerprint, "with-fingerprint", 0, "@" }, - { oDisableCipherAlgo, "disable-cipher-algo", 2, "@" }, - { oDisablePubkeyAlgo, "disable-pubkey-algo", 2, "@" }, - { oAllowNonSelfsignedUID, "allow-non-selfsigned-uid", 0, "@" }, - { oNoAllowNonSelfsignedUID, "no-allow-non-selfsigned-uid", 0, "@" }, - { oAllowFreeformUID, "allow-freeform-uid", 0, "@" }, - { oNoAllowFreeformUID, "no-allow-freeform-uid", 0, "@" }, - { oNoLiteral, "no-literal", 0, "@" }, - { oSetFilesize, "set-filesize", 20, "@" }, - { oHonorHttpProxy,"honor-http-proxy", 0, "@" }, - { oFastListMode,"fast-list-mode", 0, "@" }, - { oFixedListMode,"fixed-list-mode", 0, "@" }, - { oListOnly, "list-only", 0, "@"}, - { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" }, - { oIgnoreValidFrom, "ignore-valid-from", 0, "@" }, - { oIgnoreCrcError, "ignore-crc-error", 0,"@" }, - { oIgnoreMDCError, "ignore-mdc-error", 0,"@" }, - { oShowSessionKey, "show-session-key", 0, "@" }, - { oOverrideSessionKey, "override-session-key", 2, "@" }, - { oNoRandomSeedFile, "no-random-seed-file", 0, "@" }, - { oAutoKeyRetrieve, "auto-key-retrieve", 0, "@" }, - { oNoAutoKeyRetrieve, "no-auto-key-retrieve", 0, "@" }, - { oNoSigCache, "no-sig-cache", 0, "@" }, - { oNoSigCreateCheck, "no-sig-create-check", 0, "@" }, - { oAutoCheckTrustDB, "auto-check-trustdb", 0, "@"}, - { oNoAutoCheckTrustDB, "no-auto-check-trustdb", 0, "@"}, - { oMergeOnly, "merge-only", 0, "@" }, - { oAllowSecretKeyImport, "allow-secret-key-import", 0, "@" }, - { oTryAllSecrets, "try-all-secrets", 0, "@" }, - { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" }, - { oNoExpensiveTrustChecks, "no-expensive-trust-checks", 0, "@" }, - { aDeleteSecretAndPublicKeys, "delete-secret-and-public-keys",256, "@" }, - { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"}, - { oPreservePermissions, "preserve-permissions", 0, "@"}, - { oDefaultPreferenceList, "default-preference-list", 2, "@"}, - { oPersonalCipherPreferences, "personal-cipher-preferences", 2, "@"}, - { oPersonalDigestPreferences, "personal-digest-preferences", 2, "@"}, - { oPersonalCompressPreferences, "personal-compress-preferences", 2, "@"}, - { oEmuMDEncodeBug, "emulate-md-encode-bug", 0, "@"}, - { oAgentProgram, "agent-program", 2 , "@" }, - { oDisplay, "display", 2, "@" }, - { oTTYname, "ttyname", 2, "@" }, - { oTTYtype, "ttytype", 2, "@" }, - { oLCctype, "lc-ctype", 2, "@" }, - { oLCmessages, "lc-messages", 2, "@" }, - { oGroup, "group", 2, "@" }, - { oStrict, "strict", 0, "@" }, - { oNoStrict, "no-strict", 0, "@" }, - { oMangleDosFilenames, "mangle-dos-filenames", 0, "@" }, - { oNoMangleDosFilenames, "no-mangle-dos-filenames", 0, "@" }, - { oEnableProgressFilter, "enable-progress-filter", 0, "@" }, - { oMultifile, "multifile", 0, "@" }, -{0} }; - - - -int g10_errors_seen = 0; - -static int utf8_strings = 0; -static int maybe_setuid = 1; - -static char *build_list( const char *text, char letter, - const char *(*mapf)(int), int (*chkf)(int) ); -static void set_cmd( enum cmd_and_opt_values *ret_cmd, - enum cmd_and_opt_values new_cmd ); -static void print_mds( const char *fname, int algo ); -static void add_notation_data( const char *string, int which ); -static void add_policy_url( const char *string, int which ); -static void add_keyserver_url( const char *string, int which ); -static void emergency_cleanup (void); - -#ifdef __riscos__ -RISCOS_GLOBAL_STATICS("GnuPG Heap") -#endif /* __riscos__ */ - -static int -pk_test_algo (int algo) -{ - return openpgp_pk_test_algo (algo, 0); -} - - -static const char * -my_strusage( int level ) -{ - static char *digests, *pubkeys, *ciphers, *zips; - const char *p; - switch( level ) { - case 11: p = "gpg (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = - _("Please report bugs to <gnupg-bugs@gnu.org>.\n"); - break; - case 1: - case 40: p = - _("Usage: gpg [options] [files] (-h for help)"); - break; - case 41: p = - _("Syntax: gpg [options] [files]\n" - "sign, check, encrypt or decrypt\n" - "default operation depends on the input data\n"); - break; - - case 31: p = "\nHome: "; break; -#ifndef __riscos__ - case 32: p = opt.homedir; break; -#else /* __riscos__ */ - case 32: p = make_filename(opt.homedir, NULL); break; -#endif /* __riscos__ */ - case 33: p = _("\nSupported algorithms:\n"); break; - case 34: - if( !pubkeys ) - pubkeys = build_list(_("Pubkey: "), 0, gcry_pk_algo_name, - pk_test_algo ); - p = pubkeys; - break; - case 35: - if( !ciphers ) - ciphers = build_list(_("Cipher: "), 'S', gcry_cipher_algo_name, - openpgp_cipher_test_algo ); - p = ciphers; - break; - case 36: - if( !digests ) - digests = build_list(_("Hash: "), 'H', gcry_md_algo_name, - openpgp_md_test_algo ); - p = digests; - break; - case 37: - if( !zips ) - zips = build_list(_("Compression: "),'Z',compress_algo_to_string, - check_compress_algo); - p = zips; - break; - - default: p = NULL; - } - return p; -} - - -static char * -build_list( const char *text, char letter, - const char * (*mapf)(int), int (*chkf)(int) ) -{ - int i; - const char *s; - size_t n=strlen(text)+2; - char *list, *p, *line=NULL; - - if( maybe_setuid ) - gcry_control (GCRYCTL_INIT_SECMEM, 0, 0); /* drop setuid */ - - for(i=0; i <= 110; i++ ) - if( !chkf(i) && (s=mapf(i)) ) - n += strlen(s) + 7 + 2; - list = xmalloc ( 21 + n ); *list = 0; - for(p=NULL, i=0; i <= 110; i++ ) { - if( !chkf(i) && (s=mapf(i)) ) { - if( !p ) { - p = stpcpy( list, text ); - line=p; - } - else - p = stpcpy( p, ", "); - - if(strlen(line)>60) { - int spaces=strlen(text); - - list = xrealloc(list,n+spaces+1); - /* realloc could move the block, so find the end again */ - p=list; - while(*p) - p++; - - p=stpcpy(p, "\n"); - line=p; - for(;spaces;spaces--) - p=stpcpy(p, " "); - } - - p = stpcpy(p, s ); - if(opt.verbose && letter) - { - char num[8]; - sprintf(num," (%c%d)",letter,i); - p = stpcpy(p,num); - } - } - } - if( p ) - p = stpcpy(p, "\n" ); - return list; -} - - -static void -i18n_init(void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE_GT ); -#else -#ifdef ENABLE_NLS - setlocale( LC_ALL, "" ); - bindtextdomain( PACKAGE_GT, LOCALEDIR ); - textdomain( PACKAGE_GT ); -#endif -#endif -} - -static void -wrong_args( const char *text) -{ - fputs(_("usage: gpg [options] "),stderr); - fputs(text,stderr); - putc('\n',stderr); - g10_exit(2); -} - - -static void -log_set_strict (int yesno) -{ - /* FIXME-XXX*/ -} - -static char * -make_username( const char *string ) -{ - char *p; - if( utf8_strings ) - p = xstrdup (string); - else - p = native_to_utf8( string ); - return p; -} - - -/* - * same as add_to_strlist() but if is_utf8 is *not* set a conversion - * to UTF8 is done - */ -static STRLIST -add_to_strlist2 ( STRLIST *list, const char *string, int is_utf8) -{ - STRLIST sl; - - if (is_utf8) - sl = add_to_strlist( list, string ); - else - { - char *p = native_to_utf8( string ); - sl = add_to_strlist( list, p ); - xfree( p ); - } - return sl; -} - - -/* Setup the debugging. With a LEVEL of NULL only the active debug - flags are propagated to the subsystems. With LEVEL set, a specific - set of debug flags is set; thus overriding all flags already - set. */ -static void -set_debug (const char *level) -{ - if (!level) - ; - else if (!strcmp (level, "none")) - opt.debug = 0; - else if (!strcmp (level, "basic")) - opt.debug = DBG_MEMSTAT_VALUE; - else if (!strcmp (level, "advanced")) - opt.debug = DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE; - else if (!strcmp (level, "expert")) - opt.debug = (DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE - |DBG_CACHE_VALUE|DBG_FILTER_VALUE|DBG_PACKET_VALUE); - else if (!strcmp (level, "guru")) - opt.debug = ~0; - else - { - log_error (_("invalid debug-level `%s' given\n"), level); - g10_exit (2); - } - - if (opt.debug & DBG_MEMORY_VALUE ) - memory_debug_mode = 1; - if (opt.debug & DBG_MEMSTAT_VALUE ) - memory_stat_debug_mode = 1; - if (opt.debug & DBG_MPI_VALUE) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2); - if (opt.debug & DBG_CIPHER_VALUE ) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1); - if (opt.debug & DBG_IOBUF_VALUE ) - iobuf_debug_mode = 1; -} - - -/* We need the home directory also in some other directories, so make - sure that both variables are always in sync. */ -static void -set_homedir (char *dir) -{ - if (!dir) - dir = ""; - g10_opt_homedir = opt.homedir = dir; -} - - -static void -set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd ) -{ - enum cmd_and_opt_values cmd = *ret_cmd; - - if( !cmd || cmd == new_cmd ) - cmd = new_cmd; - else if( cmd == aSign && new_cmd == aEncr ) - cmd = aSignEncr; - else if( cmd == aEncr && new_cmd == aSign ) - cmd = aSignEncr; - else if( cmd == aSign && new_cmd == aSym ) - cmd = aSignSym; - else if( cmd == aSym && new_cmd == aSign ) - cmd = aSignSym; - else if( ( cmd == aSign && new_cmd == aClearsign ) - || ( cmd == aClearsign && new_cmd == aSign ) ) - cmd = aClearsign; - else { - log_error(_("conflicting commands\n")); - g10_exit(2); - } - - *ret_cmd = cmd; -} - - -static void add_group(char *string) -{ - char *name,*value; - struct groupitem *item; - STRLIST values=NULL; - - /* Break off the group name */ - name=strsep(&string,"="); - if(string==NULL) - { - log_error(_("no = sign found in group definition \"%s\"\n"),name); - return; - } - - trim_trailing_ws(name,strlen(name)); - - /* Break apart the values */ - while ((value= strsep(&string," \t"))) - { - if (*value) - add_to_strlist2 (&values,value,utf8_strings); - } - - item=xmalloc (sizeof(struct groupitem)); - item->name=name; - item->values=values; - item->next=opt.grouplist; - - opt.grouplist=item; -} - -/* We need to check three things. - - 0) The homedir. It must be x00, a directory, and owned by the - user. - - 1) The options file. Okay unless it or its containing directory is - group or other writable or not owned by us. disable exec in this - case. - - 2) Extensions. Same as #2. - - Returns true if the item is unsafe. */ -static int -check_permissions(const char *path,int item) -{ -#if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM) - static int homedir_cache=-1; - char *tmppath,*dir; - struct stat statbuf,dirbuf; - int homedir=0,ret=0,checkonly=0; - int perm=0,own=0,enc_dir_perm=0,enc_dir_own=0; - - if(opt.no_perm_warn) - return 0; - - assert(item==0 || item==1 || item==2); - - /* extensions may attach a path */ - if(item==2 && path[0]!=DIRSEP_C) - { - if(strchr(path,DIRSEP_C)) - tmppath=make_filename(path,NULL); - else - tmppath=make_filename(GNUPG_LIBDIR,path,NULL); - } - else - tmppath=xstrdup (path); - - /* If the item is located in the homedir, but isn't the homedir, - don't continue if we already checked the homedir itself. This is - to avoid user confusion with an extra options file warning which - could be rectified if the homedir itself had proper - permissions. */ - if(item!=0 && homedir_cache>-1 - && ascii_strncasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0) - { - ret=homedir_cache; - goto end; - } - - /* It's okay if the file or directory doesn't exist */ - if(stat(tmppath,&statbuf)!=0) - { - ret=0; - goto end; - } - - /* Now check the enclosing directory. Theoretically, we could walk - this test up to the root directory /, but for the sake of sanity, - I'm stopping at one level down. */ - dir=make_dirname(tmppath); - - if(stat(dir,&dirbuf)!=0 || !S_ISDIR(dirbuf.st_mode)) - { - /* Weird error */ - ret=1; - goto end; - } - - xfree (dir); - - /* Assume failure */ - ret=1; - - if(item==0) - { - /* The homedir must be x00, a directory, and owned by the user. */ - - if(S_ISDIR(statbuf.st_mode)) - { - if(statbuf.st_uid==getuid()) - { - if((statbuf.st_mode & (S_IRWXG|S_IRWXO))==0) - ret=0; - else - perm=1; - } - else - own=1; - - homedir_cache=ret; - } - } - else if(item==1 || item==2) - { - /* The options or extension file. Okay unless it or its - containing directory is group or other writable or not owned - by us or root. */ - - if(S_ISREG(statbuf.st_mode)) - { - if(statbuf.st_uid==getuid() || statbuf.st_uid==0) - { - if((statbuf.st_mode & (S_IWGRP|S_IWOTH))==0) - { - /* it's not writable, so make sure the enclosing - directory is also not writable */ - if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0) - { - if((dirbuf.st_mode & (S_IWGRP|S_IWOTH))==0) - ret=0; - else - enc_dir_perm=1; - } - else - enc_dir_own=1; - } - else - { - /* it's writable, so the enclosing directory had - better not let people get to it. */ - if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0) - { - if((dirbuf.st_mode & (S_IRWXG|S_IRWXO))==0) - ret=0; - else - perm=enc_dir_perm=1; /* unclear which one to fix! */ - } - else - enc_dir_own=1; - } - } - else - own=1; - } - } - else - BUG(); - - if(!checkonly) - { - if(own) - { - if(item==0) - log_info(_("WARNING: unsafe ownership on " - "homedir \"%s\"\n"),tmppath); - else if(item==1) - log_info(_("WARNING: unsafe ownership on " - "configuration file \"%s\"\n"),tmppath); - else - log_info(_("WARNING: unsafe ownership on " - "extension \"%s\"\n"),tmppath); - } - if(perm) - { - if(item==0) - log_info(_("WARNING: unsafe permissions on " - "homedir \"%s\"\n"),tmppath); - else if(item==1) - log_info(_("WARNING: unsafe permissions on " - "configuration file \"%s\"\n"),tmppath); - else - log_info(_("WARNING: unsafe permissions on " - "extension \"%s\"\n"),tmppath); - } - if(enc_dir_own) - { - if(item==0) - log_info(_("WARNING: unsafe enclosing directory ownership on " - "homedir \"%s\"\n"),tmppath); - else if(item==1) - log_info(_("WARNING: unsafe enclosing directory ownership on " - "configuration file \"%s\"\n"),tmppath); - else - log_info(_("WARNING: unsafe enclosing directory ownership on " - "extension \"%s\"\n"),tmppath); - } - if(enc_dir_perm) - { - if(item==0) - log_info(_("WARNING: unsafe enclosing directory permissions on " - "homedir \"%s\"\n"),tmppath); - else if(item==1) - log_info(_("WARNING: unsafe enclosing directory permissions on " - "configuration file \"%s\"\n"),tmppath); - else - log_info(_("WARNING: unsafe enclosing directory permissions on " - "extension \"%s\"\n"),tmppath); - } - } - - end: - xfree (tmppath); - - if(homedir) - homedir_cache=ret; - - return ret; - -#endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */ - - return 0; -} - -int -main( int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - iobuf_t a; - int rc=0; - int orig_argc; - char **orig_argv; - const char *fname; - char *username; - int may_coredump; - STRLIST sl, remusr= NULL, locusr=NULL; - STRLIST nrings=NULL, sec_nrings=NULL; - armor_filter_context_t afx; - int detached_sig = 0; - FILE *configfp = NULL; - char *configname = NULL; - const char *config_filename = NULL; - unsigned configlineno; - int parse_debug = 0; - int default_config = 1; - int default_keyring = 1; - int greeting = 0; - int nogreeting = 0; - char *logfile = NULL; - int use_random_seed = 1; - enum cmd_and_opt_values cmd = 0; - const char *debug_level = NULL; - const char *trustdb_name = NULL; - char *def_cipher_string = NULL; - char *def_digest_string = NULL; - char *def_compress_string = NULL; - char *cert_digest_string = NULL; - char *s2k_cipher_string = NULL; - char *s2k_digest_string = NULL; - char *pers_cipher_list = NULL; - char *pers_digest_list = NULL; - char *pers_compress_list = NULL; - int eyes_only=0; - int multifile=0; - int pwfd = -1; - int with_fpr = 0; /* make an option out of --fingerprint */ - int any_explicit_recipient = 0; - -#ifdef __riscos__ - riscos_global_defaults(); - opt.lock_once = 1; -#endif /* __riscos__ */ - - trap_unaligned(); - set_strusage (my_strusage); - gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - /* We don't need any locking in libgcrypt unless we use any kind of - threading. */ - gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING); - /* Please note that we may running SUID(ROOT), so be very CAREFUL - * when adding any stuff between here and the call to - * secmem_init() somewhere after the option parsing - */ - log_set_prefix ("gpg", 1); - /* check that the libraries are suitable. Do it here because the - option parse may need services of the library */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal( _("libgcrypt is too old (need %s, have %s)\n"), - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - - gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); - - may_coredump = disable_core_dumps(); - gnupg_init_signals (0, emergency_cleanup); - create_dotlock (NULL); /* register locking cleanup */ - i18n_init(); - - opt.command_fd = -1; /* no command fd */ - opt.compress = -1; /* defaults to standard compress level */ - /* note: if you change these lines, look at oOpenPGP */ - opt.def_cipher_algo = 0; - opt.def_digest_algo = 0; - opt.cert_digest_algo = 0; - opt.def_compress_algo = -1; - opt.s2k_mode = 3; /* iterated+salted */ - opt.s2k_digest_algo = DIGEST_ALGO_SHA1; -#ifdef USE_CAST5 - opt.s2k_cipher_algo = CIPHER_ALGO_CAST5; -#else - opt.s2k_cipher_algo = CIPHER_ALGO_3DES; -#endif - opt.completes_needed = 1; - opt.marginals_needed = 3; - opt.max_cert_depth = 5; - opt.pgp2_workarounds = 1; - opt.force_v3_sigs = 1; - opt.escape_from = 1; - opt.import_options=IMPORT_SK2PK; - opt.export_options= - EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES; - opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG; - opt.keyserver_options.export_options= - EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES; - opt.keyserver_options.include_subkeys=1; - opt.keyserver_options.include_revoked=1; - opt.keyserver_options.try_dns_srv=1; - opt.verify_options= - VERIFY_SHOW_POLICY|VERIFY_SHOW_NOTATION|VERIFY_SHOW_KEYSERVER; - opt.trust_model=TM_AUTO; - opt.mangle_dos_filenames = 1; - opt.use_agent = 1; - -#if defined (_WIN32) - set_homedir ( read_w32_registry_string( NULL, - "Software\\GNU\\GnuPG", "HomeDir" )); -#else - set_homedir ( getenv("GNUPGHOME") ); -#endif - if( !*opt.homedir ) - set_homedir ( GNUPG_DEFAULT_HOMEDIR ); - - /* check whether we have a config file on the commandline */ - orig_argc = argc; - orig_argv = argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */ - while( arg_parse( &pargs, opts) ) { - if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll ) - parse_debug++; - else if( pargs.r_opt == oOptions ) { - /* yes there is one, so we do not try the default one, but - * read the option file when it is encountered at the commandline - */ - default_config = 0; - } - else if( pargs.r_opt == oNoOptions ) - default_config = 0; /* --no-options */ - else if( pargs.r_opt == oHomedir ) - set_homedir ( pargs.r.ret_str ); - else if( pargs.r_opt == oNoPermissionWarn ) - opt.no_perm_warn=1; - else if (pargs.r_opt == oStrict ) - { - opt.strict=1; - log_set_strict(1); - } - else if (pargs.r_opt == oNoStrict ) - { - opt.strict=0; - log_set_strict(0); - } - } - -#ifdef HAVE_DOSISH_SYSTEM - if ( strchr (opt.homedir,'\\') ) { - char *d, *buf = xmalloc (strlen (opt.homedir)+1); - const char *s = opt.homedir; - for (d=buf,s=opt.homedir; *s; s++) - *d++ = *s == '\\'? '/': *s; - *d = 0; - set_homedir (buf); - } -#endif - - /* Initialize the secure memory. */ - gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0); - maybe_setuid = 0; - /* Okay, we are now working under our real uid */ - - /* malloc hooks go here ... */ - assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - - set_native_charset (NULL); /* Try to auto set the character set */ - - /* Try for a version specific config file first */ - if( default_config ) - { - char *name = xstrdup ("gpg" EXTSEP_S "conf-" SAFE_VERSION); - char *ver = name + strlen("gpg" EXTSEP_S "conf-"); - - do - { - if(configname) - { - char *tok; - - xfree (configname); - configname=NULL; - - if((tok=strrchr (ver,SAFE_VERSION_DASH))) - *tok='\0'; - else if((tok=strrchr (ver,SAFE_VERSION_DOT))) - *tok='\0'; - else - break; - } - - configname = make_filename (opt.homedir, name, NULL); - } - while ( access(configname,R_OK) ); - xfree(name); - - if (!access (configname, R_OK)) - { /* Print a warning when both config files are present. */ - char *p = make_filename(opt.homedir, "options", NULL ); - if (!access (p, R_OK)) - log_info (_("NOTE: old default options file `%s' ignored\n"), p); - xfree (p); - } - else - { /* Keep on using the old default one. */ - xfree (configname); - configname = make_filename(opt.homedir, "options", NULL ); - } - } - argc = orig_argc; - argv = orig_argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - - /* By this point we have a homedir, and cannot change it. */ - check_permissions(opt.homedir,0); - - next_pass: - if( configname ) { - if(check_permissions(configname,1)) - { - /* If any options file is unsafe, then disable any external - programs for keyserver calls or photo IDs. Since the - external program to call is set in the options file, a - unsafe options file can lead to an arbitrary program - being run. */ - - opt.exec_disable=1; - } - - configlineno = 0; - configfp = fopen( configname, "r" ); - if( !configfp ) { - if( default_config ) { - if( parse_debug ) - log_info(_("NOTE: no default option file `%s'\n"), - configname ); - } - else { - log_error(_("option file `%s': %s\n"), - configname, strerror(errno) ); - g10_exit(2); - } - xfree (configname); configname = NULL; - } - if( parse_debug && configname ) - log_info(_("reading options from `%s'\n"), configname ); - default_config = 0; - } - - while( optfile_parse( configfp, configname, &configlineno, - &pargs, opts) ) { - switch( pargs.r_opt ) { - case aCheckKeys: set_cmd( &cmd, aCheckKeys); break; - case aListPackets: set_cmd( &cmd, aListPackets); break; - case aImport: set_cmd( &cmd, aImport); break; - case aFastImport: set_cmd( &cmd, aFastImport); break; - case aSendKeys: set_cmd( &cmd, aSendKeys); break; - case aRecvKeys: set_cmd( &cmd, aRecvKeys); break; - case aSearchKeys: set_cmd( &cmd, aSearchKeys); break; - case aRefreshKeys: set_cmd( &cmd, aRefreshKeys); break; - case aExport: set_cmd( &cmd, aExport); break; - case aExportAll: set_cmd( &cmd, aExportAll); break; - case aListKeys: set_cmd( &cmd, aListKeys); break; - case aListSigs: set_cmd( &cmd, aListSigs); break; - case aExportSecret: set_cmd( &cmd, aExportSecret); break; - case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break; - case aDeleteSecretKeys: set_cmd( &cmd, aDeleteSecretKeys); - greeting=1; break; - case aDeleteSecretAndPublicKeys: - set_cmd( &cmd, aDeleteSecretAndPublicKeys); - greeting=1; - break; - case aDeleteKeys: set_cmd( &cmd, aDeleteKeys); greeting=1; break; - - case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break; - case aSym: set_cmd( &cmd, aSym); break; - - case aDecryptFiles: multifile=1; /* fall through */ - case aDecrypt: set_cmd( &cmd, aDecrypt); break; - - case aEncrFiles: multifile=1; /* fall through */ - case aEncr: set_cmd( &cmd, aEncr); break; - - case aVerifyFiles: multifile=1; /* fall through */ - case aVerify: set_cmd( &cmd, aVerify); break; - - case aSign: set_cmd( &cmd, aSign ); break; - case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break; - case aSignKey: set_cmd( &cmd, aSignKey); break; - case aLSignKey: set_cmd( &cmd, aLSignKey); break; - case aNRSignKey: set_cmd( &cmd, aNRSignKey); break; - case aNRLSignKey: set_cmd( &cmd, aNRLSignKey); break; - case aStore: set_cmd( &cmd, aStore); break; - case aEditKey: set_cmd( &cmd, aEditKey); greeting=1; break; - case aClearsign: set_cmd( &cmd, aClearsign); break; - case aGenRevoke: set_cmd( &cmd, aGenRevoke); break; - case aDesigRevoke: set_cmd( &cmd, aDesigRevoke); break; - - case aPrimegen: set_cmd( &cmd, aPrimegen); break; - case aGenRandom: set_cmd( &cmd, aGenRandom); break; - case aPrintMD: set_cmd( &cmd, aPrintMD); break; - case aPrintMDs: set_cmd( &cmd, aPrintMDs); break; - case aListTrustDB: set_cmd( &cmd, aListTrustDB); break; - case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break; - case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break; - case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break; - case aListTrustPath: set_cmd( &cmd, aListTrustPath); break; - case aDeArmor: set_cmd( &cmd, aDeArmor); break; - case aEnArmor: set_cmd( &cmd, aEnArmor); break; - case aListOwnerTrust: - deprecated_warning(configname,configlineno, - "--list-ownertrust","--export-ownertrust",""); - case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break; - case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break; - case aPipeMode: set_cmd( &cmd, aPipeMode); break; - case aRebuildKeydbCaches: set_cmd( &cmd, aRebuildKeydbCaches); break; - - case aCardStatus: set_cmd (&cmd, aCardStatus); break; - case aCardEdit: set_cmd (&cmd, aCardEdit); break; - case aChangePIN: set_cmd (&cmd, aChangePIN); break; - case aGPGConfList: - set_cmd (&cmd, aGPGConfList); - nogreeting = 1; - break; - - case oArmor: opt.armor = 1; opt.no_armor=0; break; - case oOutput: opt.outfile = pargs.r.ret_str; break; - case oQuiet: opt.quiet = 1; break; - case oNoTTY: tty_no_terminal(1); break; - case oDryRun: opt.dry_run = 1; break; - case oInteractive: opt.interactive = 1; break; - case oVerbose: g10_opt_verbose++; - opt.verbose++; opt.list_sigs=1; break; - - case oLogFile: logfile = pargs.r.ret_str; break; - - case oBatch: opt.batch = 1; nogreeting = 1; break; - case oUseAgent: -#ifndef __riscos__ - opt.use_agent = 1; -#else /* __riscos__ */ - opt.use_agent = 0; - riscos_not_implemented("use-agent"); -#endif /* __riscos__ */ - break; - case oNoUseAgent: opt.use_agent = 0; break; - case oGpgAgentInfo: opt.gpg_agent_info = pargs.r.ret_str; break; - case oAnswerYes: opt.answer_yes = 1; break; - case oAnswerNo: opt.answer_no = 1; break; - case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; - case oPrimaryKeyring: - sl=append_to_strlist( &nrings, pargs.r.ret_str); - sl->flags=2; - break; - case oShowKeyring: opt.list_options|=LIST_SHOW_KEYRING; break; - case oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oDebugLevel: debug_level = pargs.r.ret_str; break; - case oStatusFD: - set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) ); - break; -#ifdef __riscos__ - case oStatusFile: - set_status_fd( iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) ); - break; -#endif /* __riscos__ */ - case oAttributeFD: - set_attrib_fd(iobuf_translate_file_handle (pargs.r.ret_int, 1)); - break; -#ifdef __riscos__ - case oAttributeFile: - set_attrib_fd(iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) ); - break; -#endif /* __riscos__ */ - case oLoggerFD: - log_set_fd (iobuf_translate_file_handle (pargs.r.ret_int, 1)); - break; -#ifdef __riscos__ - case oLoggerFile: - log_set_logfile( NULL, - iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) ); - break; -#endif /* __riscos__ */ - case oWithFingerprint: - opt.with_fingerprint = 1; - with_fpr=1; /*fall thru*/ - case oFingerprint: opt.fingerprint++; break; - case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break; - case oOptions: - /* config files may not be nested (silently ignore them) */ - if( !configfp ) { - xfree (configname); - configname = xstrdup (pargs.r.ret_str); - goto next_pass; - } - break; - case oNoArmor: opt.no_armor=1; opt.armor=0; break; - case oNoDefKeyring: default_keyring = 0; break; - case oDefCertCheckLevel: opt.def_cert_check_level=pargs.r.ret_int; break; - case oNoGreeting: nogreeting = 1; break; - case oNoVerbose: g10_opt_verbose = 0; - opt.verbose = 0; opt.list_sigs=0; break; - /* disabled for now: - case oQuickRandom: quick_random_gen(1); break; */ - case oSKComments: opt.sk_comments=1; break; - case oNoSKComments: opt.sk_comments=0; break; - case oEmitVersion: opt.no_version=0; break; - case oNoEmitVersion: opt.no_version=1; break; - case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break; - case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break; - case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break; - case oTrustDBName: trustdb_name = pargs.r.ret_str; break; - case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break; - case oDefRecipient: - if( *pargs.r.ret_str ) - opt.def_recipient = make_username(pargs.r.ret_str); - break; - case oDefRecipientSelf: - xfree (opt.def_recipient); opt.def_recipient = NULL; - opt.def_recipient_self = 1; - break; - case oNoDefRecipient: - xfree (opt.def_recipient); opt.def_recipient = NULL; - opt.def_recipient_self = 0; - break; - case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */ - case oHomedir: break; - case oNoBatch: opt.batch = 0; break; - case oWithKeyData: opt.with_key_data=1; /* fall thru */ - case oWithColons: opt.with_colons=':'; break; - - case oSkipVerify: opt.skip_verify=1; break; - case oCompressKeys: opt.compress_keys = 1; break; - case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break; - /* There are many programs (like mutt) that call gpg with - --always-trust so keep this option around for a long - time. */ - case oAlwaysTrust: opt.trust_model=TM_ALWAYS; break; - case oTrustModel: - if(ascii_strcasecmp(pargs.r.ret_str,"pgp")==0) - opt.trust_model=TM_PGP; - else if(ascii_strcasecmp(pargs.r.ret_str,"classic")==0) - opt.trust_model=TM_CLASSIC; - else if(ascii_strcasecmp(pargs.r.ret_str,"always")==0) - opt.trust_model=TM_ALWAYS; - else if(ascii_strcasecmp(pargs.r.ret_str,"auto")==0) - opt.trust_model=TM_AUTO; - else - log_error("unknown trust model \"%s\"\n",pargs.r.ret_str); - break; - case oForceOwnertrust: - log_info(_("NOTE: %s is not for normal use!\n"), - "--force-ownertrust"); - opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str); - if(opt.force_ownertrust==-1) - { - log_error("invalid ownertrust \"%s\"\n",pargs.r.ret_str); - opt.force_ownertrust=0; - } - break; - case oLoadExtension: -#ifndef __riscos__ -#if defined(USE_DYNAMIC_LINKING) || defined(_WIN32) - if(check_permissions(pargs.r.ret_str,2)) - log_info(_("cipher extension \"%s\" not loaded due to " - "unsafe permissions\n"),pargs.r.ret_str); - else - register_cipher_extension(orig_argc? *orig_argv:NULL, - pargs.r.ret_str); -#endif -#else /* __riscos__ */ - riscos_not_implemented("load-extension"); -#endif /* __riscos__ */ - break; - case oRFC1991: - opt.compliance = CO_RFC1991; - opt.force_v4_certs = 0; - opt.escape_from = 1; - break; - case oRFC2440: - case oOpenPGP: - /* TODO: When 2440bis becomes a RFC, these may need - changing. */ - opt.compliance = CO_RFC2440; - opt.allow_non_selfsigned_uid = 1; - opt.allow_freeform_uid = 1; - opt.pgp2_workarounds = 0; - opt.escape_from = 0; - opt.force_v3_sigs = 0; - opt.compress_keys = 0; /* not mandated but we do it */ - opt.compress_sigs = 0; /* ditto. */ - opt.not_dash_escaped = 0; - opt.def_cipher_algo = 0; - opt.def_digest_algo = 0; - opt.cert_digest_algo = 0; - opt.def_compress_algo = -1; - opt.s2k_mode = 3; /* iterated+salted */ - opt.s2k_digest_algo = DIGEST_ALGO_SHA1; - opt.s2k_cipher_algo = CIPHER_ALGO_3DES; - break; - case oPGP2: opt.compliance = CO_PGP2; break; - case oPGP6: opt.compliance = CO_PGP6; break; - case oPGP7: opt.compliance = CO_PGP7; break; - case oPGP8: opt.compliance = CO_PGP8; break; - case oGnuPG: opt.compliance = CO_GNUPG; break; - case oEmuMDEncodeBug: opt.emulate_bugs |= EMUBUG_MDENCODE; break; - case oCompressSigs: opt.compress_sigs = 1; break; - case oSetFilename: opt.set_filename = pargs.r.ret_str; break; - case oForYourEyesOnly: eyes_only = 1; break; - case oNoForYourEyesOnly: eyes_only = 0; break; - case oSetPolicyURL: - add_policy_url(pargs.r.ret_str,0); - add_policy_url(pargs.r.ret_str,1); - break; - case oSigPolicyURL: add_policy_url(pargs.r.ret_str,0); break; - case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break; - case oShowPolicyURL: - opt.list_options|=LIST_SHOW_POLICY; - opt.verify_options|=VERIFY_SHOW_POLICY; - break; - case oNoShowPolicyURL: - opt.list_options&=~LIST_SHOW_POLICY; - opt.verify_options&=~VERIFY_SHOW_POLICY; - break; - case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break; - case oUseEmbeddedFilename: opt.use_embedded_filename = 1; break; - - case oComment: add_to_strlist(&opt.comments,pargs.r.ret_str); break; - case oDefaultComment: - deprecated_warning(configname,configlineno, - "--default-comment","--no-comments",""); - /* fall through */ - case oNoComments: - free_strlist(opt.comments); - opt.comments=NULL; - break; - - case oThrowKeyid: opt.throw_keyid = 1; break; - case oNoThrowKeyid: opt.throw_keyid = 0; break; - case oShowPhotos: - opt.list_options|=LIST_SHOW_PHOTOS; - opt.verify_options|=VERIFY_SHOW_PHOTOS; - break; - case oNoShowPhotos: - opt.list_options&=~LIST_SHOW_PHOTOS; - opt.verify_options&=~VERIFY_SHOW_PHOTOS; - break; - case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break; - case oForceV3Sigs: opt.force_v3_sigs = 1; break; - case oNoForceV3Sigs: opt.force_v3_sigs = 0; break; - case oForceV4Certs: opt.force_v4_certs = 1; break; - case oNoForceV4Certs: opt.force_v4_certs = 0; break; - case oForceMDC: opt.force_mdc = 1; break; - case oNoForceMDC: opt.force_mdc = 0; break; - case oDisableMDC: opt.disable_mdc = 1; break; - case oNoDisableMDC: opt.disable_mdc = 0; break; - case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break; - case oS2KDigest: s2k_digest_string = xstrdup (pargs.r.ret_str); break; - case oS2KCipher: s2k_cipher_string = xstrdup (pargs.r.ret_str); break; - case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break; - case oNoEncryptTo: opt.no_encrypt_to = 1; break; - case oEncryptTo: /* store the recipient in the second list */ - sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = 1; - break; - case oHiddenEncryptTo: /* store the recipient in the second list */ - sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = 1|2; - break; - case oRecipient: /* store the recipient */ - add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - any_explicit_recipient = 1; - break; - case oHiddenRecipient: /* store the recipient with a flag */ - sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = 2; - any_explicit_recipient = 1; - break; - case oTextmodeShort: opt.textmode = 2; break; - case oTextmode: opt.textmode=1; break; - case oNoTextmode: opt.textmode=0; break; - case oExpert: opt.expert = 1; break; - case oNoExpert: opt.expert = 0; break; - case oAskSigExpire: opt.ask_sig_expire = 1; break; - case oNoAskSigExpire: opt.ask_sig_expire = 0; break; - case oAskCertExpire: opt.ask_cert_expire = 1; break; - case oNoAskCertExpire: opt.ask_cert_expire = 0; break; - case oUser: /* store the local users */ - add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings ); - break; - case oCompress: opt.compress = pargs.r.ret_int; break; - case oPasswdFD: - pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0); - opt.use_agent = 0; - break; -#ifdef __riscos__ - case oPasswdFile: - pwfd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0); - break; -#endif /* __riscos__ */ - case oCommandFD: - opt.command_fd = iobuf_translate_file_handle (pargs.r.ret_int, 0); - break; -#ifdef __riscos__ - case oCommandFile: - opt.command_fd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0); - break; -#endif /* __riscos__ */ - case oCipherAlgo: def_cipher_string = xstrdup (pargs.r.ret_str); break; - case oDigestAlgo: def_digest_string = xstrdup (pargs.r.ret_str); break; - case oCompressAlgo: - /* If it is all digits, stick a Z in front of it for - later. This is for backwards compatibility with - versions that took the compress algorithm number. */ - { - char *pt=pargs.r.ret_str; - while(*pt) - { - if(!isdigit(*pt)) - break; - - pt++; - } - - if(*pt=='\0') - { - def_compress_string=xmalloc (strlen(pargs.r.ret_str)+2); - strcpy(def_compress_string,"Z"); - strcat(def_compress_string,pargs.r.ret_str); - } - else - def_compress_string = xstrdup (pargs.r.ret_str); - } - break; - case oCertDigestAlgo: cert_digest_string = xstrdup (pargs.r.ret_str); break; - case oNoSecmemWarn: - gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); - break; - case oNoPermissionWarn: opt.no_perm_warn=1; break; - case oNoMDCWarn: opt.no_mdc_warn=1; break; - case oCharset: - if( set_native_charset( pargs.r.ret_str ) ) - log_error(_("%s is not a valid character set\n"), - pargs.r.ret_str); - break; - case oNotDashEscaped: opt.not_dash_escaped = 1; break; - case oEscapeFrom: opt.escape_from = 1; break; - case oNoEscapeFrom: opt.escape_from = 0; break; - case oLockOnce: opt.lock_once = 1; break; - case oLockNever: disable_dotlock(); break; - case oLockMultiple: -#ifndef __riscos__ - opt.lock_once = 0; -#else /* __riscos__ */ - riscos_not_implemented("lock-multiple"); -#endif /* __riscos__ */ - break; - case oKeyServer: - opt.keyserver_uri=xstrdup (pargs.r.ret_str); - if(parse_keyserver_uri(pargs.r.ret_str,configname,configlineno)) - log_error(_("could not parse keyserver URI\n")); - break; - case oKeyServerOptions: - parse_keyserver_options(pargs.r.ret_str); - break; - case oImportOptions: - if(!parse_import_options(pargs.r.ret_str,&opt.import_options)) - { - if(configname) - log_error(_("%s:%d: invalid import options\n"), - configname,configlineno); - else - log_error(_("invalid import options\n")); - } - break; - case oExportOptions: - if(!parse_export_options(pargs.r.ret_str,&opt.export_options)) - { - if(configname) - log_error(_("%s:%d: invalid export options\n"), - configname,configlineno); - else - log_error(_("invalid export options\n")); - } - break; - case oListOptions: - { - struct parse_options lopts[]= - { - {"show-photos",LIST_SHOW_PHOTOS}, - {"show-policy-url",LIST_SHOW_POLICY}, - {"show-notation",LIST_SHOW_NOTATION}, - {"show-keyserver-url",LIST_SHOW_KEYSERVER}, - {"show-validity",LIST_SHOW_VALIDITY}, - {"show-long-keyid",LIST_SHOW_LONG_KEYID}, - {"show-keyring",LIST_SHOW_KEYRING}, - {"show-sig-expire",LIST_SHOW_SIG_EXPIRE}, - {NULL,0} - }; - - if(!parse_options(pargs.r.ret_str,&opt.list_options,lopts)) - { - if(configname) - log_error(_("%s:%d: invalid list options\n"), - configname,configlineno); - else - log_error(_("invalid list options\n")); - } - } - break; - case oVerifyOptions: - { - struct parse_options vopts[]= - { - {"show-photos",VERIFY_SHOW_PHOTOS}, - {"show-policy-url",VERIFY_SHOW_POLICY}, - {"show-notation",VERIFY_SHOW_NOTATION}, - {"show-keyserver-url",VERIFY_SHOW_KEYSERVER}, - {"show-validity",VERIFY_SHOW_VALIDITY}, - {"show-long-keyid",VERIFY_SHOW_LONG_KEYID}, - {NULL,0} - }; - - if(!parse_options(pargs.r.ret_str,&opt.verify_options,vopts)) - { - if(configname) - log_error(_("%s:%d: invalid verify options\n"), - configname,configlineno); - else - log_error(_("invalid verify options\n")); - } - } - break; - case oTempDir: opt.temp_dir=pargs.r.ret_str; break; - case oExecPath: - if(set_exec_path(pargs.r.ret_str,0)) - log_error(_("unable to set exec-path to %s\n"),pargs.r.ret_str); - else - opt.exec_path_set=1; - break; - case oSetNotation: - add_notation_data( pargs.r.ret_str, 0 ); - add_notation_data( pargs.r.ret_str, 1 ); - break; - case oSigNotation: add_notation_data( pargs.r.ret_str, 0 ); break; - case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break; - case oShowNotation: - opt.list_options|=LIST_SHOW_NOTATION; - opt.verify_options|=VERIFY_SHOW_NOTATION; - break; - case oNoShowNotation: - opt.list_options&=~LIST_SHOW_NOTATION; - opt.verify_options&=~VERIFY_SHOW_NOTATION; - break; - case oUtf8Strings: utf8_strings = 1; break; - case oNoUtf8Strings: utf8_strings = 0; break; - case oDisableCipherAlgo: - { - int algo = gcry_cipher_map_name (pargs.r.ret_str); - gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, - &algo, sizeof algo); - } - break; - case oDisablePubkeyAlgo: - { - int algo = gcry_pk_map_name (pargs.r.ret_str); - gcry_pk_ctl (GCRYCTL_DISABLE_ALGO, - &algo, sizeof algo ); - } - break; - case oNoSigCache: opt.no_sig_cache = 1; break; - case oNoSigCreateCheck: opt.no_sig_create_check = 1; break; - case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break; - case oNoAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid=0; break; - case oAllowFreeformUID: opt.allow_freeform_uid = 1; break; - case oNoAllowFreeformUID: opt.allow_freeform_uid = 0; break; - case oNoLiteral: opt.no_literal = 1; break; - case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break; - case oHonorHttpProxy: - opt.keyserver_options.honor_http_proxy = 1; - deprecated_warning(configname,configlineno, - "--honor-http-proxy", - "--keyserver-options ", - "honor-http-proxy"); - break; - case oFastListMode: opt.fast_list_mode = 1; break; - case oFixedListMode: opt.fixed_list_mode = 1; break; - case oListOnly: opt.list_only=1; break; - case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break; - case oIgnoreValidFrom: opt.ignore_valid_from = 1; break; - case oIgnoreCrcError: opt.ignore_crc_error = 1; break; - case oIgnoreMDCError: opt.ignore_mdc_error = 1; break; - case oNoRandomSeedFile: use_random_seed = 0; break; - case oAutoKeyRetrieve: - case oNoAutoKeyRetrieve: - opt.keyserver_options.auto_key_retrieve= - (pargs.r_opt==oAutoKeyRetrieve); - deprecated_warning(configname,configlineno, - pargs.r_opt==oAutoKeyRetrieve?"--auto-key-retrieve": - "--no-auto-key-retrieve","--keyserver-options ", - pargs.r_opt==oAutoKeyRetrieve?"auto-key-retrieve": - "no-auto-key-retrieve"); - break; - case oShowSessionKey: opt.show_session_key = 1; break; - case oOverrideSessionKey: - opt.override_session_key = pargs.r.ret_str; - break; - case oMergeOnly: opt.merge_only = 1; break; - case oAllowSecretKeyImport: /* obsolete */ break; - case oTryAllSecrets: opt.try_all_secrets = 1; break; - case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break; - case oEnableSpecialFilenames: - iobuf_enable_special_filenames (1); - break; - case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break; - case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break; - case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break; - case oPreservePermissions: opt.preserve_permissions=1; break; - case oDefaultPreferenceList: - opt.def_preference_list = pargs.r.ret_str; - break; - case oPersonalCipherPreferences: - pers_cipher_list=pargs.r.ret_str; - break; - case oPersonalDigestPreferences: - pers_digest_list=pargs.r.ret_str; - break; - case oPersonalCompressPreferences: - pers_compress_list=pargs.r.ret_str; - break; - case oAgentProgram: opt.agent_program = pargs.r.ret_str; break; - case oDisplay: opt.display = pargs.r.ret_str; break; - case oTTYname: opt.ttyname = pargs.r.ret_str; break; - case oTTYtype: opt.ttytype = pargs.r.ret_str; break; - case oLCctype: opt.lc_ctype = pargs.r.ret_str; break; - case oLCmessages: opt.lc_messages = pargs.r.ret_str; break; - case oGroup: add_group(pargs.r.ret_str); break; - case oStrict: opt.strict=1; log_set_strict(1); break; - case oNoStrict: opt.strict=0; log_set_strict(0); break; - - case oMangleDosFilenames: opt.mangle_dos_filenames = 1; break; - case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break; - - case oEnableProgressFilter: opt.enable_progress_filter = 1; break; - case oMultifile: multifile=1; break; - - default : pargs.err = configfp? 1:2; break; - } - } - - if( configfp ) { - fclose( configfp ); - configfp = NULL; - config_filename = configname; /* Keep a copy of the config - file name. */ - configname = NULL; - goto next_pass; - } - xfree ( configname ); configname = NULL; - if( log_get_errorcount(0) ) - g10_exit(2); - if( nogreeting ) - greeting = 0; - - if( greeting ) { - fprintf(stderr, "%s %s; %s\n", - strusage(11), strusage(13), strusage(14) ); - fprintf(stderr, "%s\n", strusage(15) ); - } -#ifdef IS_DEVELOPMENT_VERSION - if( !opt.batch ) { - log_info("NOTE: THIS IS A DEVELOPMENT VERSION!\n"); - log_info("It is only intended for test purposes and should NOT be\n"); - log_info("used in a production environment or with production keys!\n"); - } -#endif - - /* FIXME: We should use the lggging to a file only in server mode; - however we have not yet implemetyed that thus we try to get - away with --batch as indication for logging to file required. */ - if (logfile && opt.batch) - { - log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); - } - - if (opt.verbose > 2) - log_info ("using character set `%s'\n", get_native_charset ()); - - if( may_coredump && !opt.quiet ) - log_info(_("WARNING: program may create a core file!\n")); - - if (eyes_only) { - if (opt.set_filename) - log_info(_("WARNING: %s overrides %s\n"), - "--for-your-eyes-only","--set-filename"); - - opt.set_filename="_CONSOLE"; - } - - if (opt.no_literal) { - log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal"); - if (opt.textmode) - log_error(_("%s not allowed with %s!\n"), - "--textmode", "--no-literal" ); - if (opt.set_filename) - log_error(_("%s makes no sense with %s!\n"), - eyes_only?"--for-your-eyes-only":"--set-filename", - "--no-literal" ); - } - - if (opt.set_filesize) - log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize"); - if( opt.batch ) - tty_batchmode( 1 ); - - gcry_control (GCRYCTL_RESUME_SECMEM_WARN); - set_debug (debug_level); - - /* Do these after the switch(), so they can override settings. */ - if(PGP2) - { - int unusable=0; - - if(cmd==aSign && !detached_sig) - { - log_info(_("you can only make detached or clear signatures " - "while in --pgp2 mode\n")); - unusable=1; - } - else if(cmd==aSignEncr || cmd==aSignSym) - { - log_info(_("you can't sign and encrypt at the " - "same time while in --pgp2 mode\n")); - unusable=1; - } - else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym)) - { - log_info(_("you must use files (and not a pipe) when " - "working with --pgp2 enabled.\n")); - unusable=1; - } - else if(cmd==aEncr || cmd==aSym) - { - /* Everything else should work without IDEA (except using - a secret key encrypted with IDEA and setting an IDEA - preference, but those have their own error - messages). */ - - if(openpgp_cipher_test_algo (CIPHER_ALGO_IDEA)) - { - log_info(_("encrypting a message in --pgp2 mode requires " - "the IDEA cipher\n")); - idea_cipher_warn(1); - unusable=1; - } - else if(cmd==aSym) - { - /* This only sets IDEA for symmetric encryption - since it is set via select_algo_from_prefs for - pk encryption. */ - xfree (def_cipher_string); - def_cipher_string = xstrdup ("idea"); - } - - /* PGP2 can't handle the output from the textmode - filter, so we disable it for anything that could - create a literal packet (only encryption and - symmetric encryption, since we disable signing - above). */ - if(!unusable) - opt.textmode=0; - } - - if(unusable) - compliance_failure(); - else - { - opt.force_v4_certs = 0; - opt.sk_comments = 0; - opt.escape_from = 1; - opt.force_v3_sigs = 1; - opt.pgp2_workarounds = 1; - opt.ask_sig_expire = 0; - opt.ask_cert_expire = 0; - xfree (def_digest_string); - def_digest_string = xstrdup ("md5"); - opt.def_compress_algo = 1; - } - } - else if(PGP6) - { - opt.sk_comments=0; - opt.escape_from=1; - opt.force_v3_sigs=1; - opt.ask_sig_expire=0; - } - else if(PGP7) - { - opt.sk_comments=0; - opt.escape_from=1; - opt.force_v3_sigs=1; - opt.ask_sig_expire=0; - } - else if(PGP8) - { - opt.escape_from=1; - } - - /* must do this after dropping setuid, because string_to... - * may try to load an module */ - if( def_cipher_string ) { - opt.def_cipher_algo = gcry_cipher_map_name (def_cipher_string); - if(opt.def_cipher_algo==0 && - (ascii_strcasecmp(def_cipher_string,"idea")==0 - || ascii_strcasecmp(def_cipher_string,"s1")==0)) - idea_cipher_warn(1); - xfree (def_cipher_string); def_cipher_string = NULL; - if( openpgp_cipher_test_algo (opt.def_cipher_algo) ) - log_error(_("selected cipher algorithm is invalid\n")); - } - if( def_digest_string ) { - opt.def_digest_algo = gcry_md_map_name (def_digest_string); - xfree (def_digest_string); def_digest_string = NULL; - if( openpgp_md_test_algo (opt.def_digest_algo) ) - log_error(_("selected digest algorithm is invalid\n")); - } - if( def_compress_string ) { - opt.def_compress_algo = string_to_compress_algo(def_compress_string); - xfree (def_compress_string); def_compress_string = NULL; - if( check_compress_algo(opt.def_compress_algo) ) - log_error(_("selected compression algorithm is invalid\n")); - } - if( cert_digest_string ) { - opt.cert_digest_algo = gcry_md_map_name (cert_digest_string); - xfree (cert_digest_string); cert_digest_string = NULL; - if( openpgp_md_test_algo(opt.cert_digest_algo) ) - log_error(_("selected certification digest algorithm is invalid\n")); - } - if( s2k_cipher_string ) { - opt.s2k_cipher_algo = gcry_cipher_map_name (s2k_cipher_string); - xfree (s2k_cipher_string); s2k_cipher_string = NULL; - if( openpgp_cipher_test_algo (opt.s2k_cipher_algo) ) - log_error(_("selected cipher algorithm is invalid\n")); - } - if( s2k_digest_string ) { - opt.s2k_digest_algo = gcry_md_map_name (s2k_digest_string); - xfree (s2k_digest_string); s2k_digest_string = NULL; - if( openpgp_md_test_algo (opt.s2k_digest_algo) ) - log_error(_("selected digest algorithm is invalid\n")); - } - if( opt.completes_needed < 1 ) - log_error(_("completes-needed must be greater than 0\n")); - if( opt.marginals_needed < 2 ) - log_error(_("marginals-needed must be greater than 1\n")); - if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 ) - log_error(_("max-cert-depth must be in range 1 to 255\n")); - switch( opt.s2k_mode ) { - case 0: - log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n")); - break; - case 1: case 3: break; - default: - log_error(_("invalid S2K mode; must be 0, 1 or 3\n")); - } - - if(opt.def_cert_check_level<0 || opt.def_cert_check_level>3) - log_error(_("invalid default-check-level; must be 0, 1, 2, or 3\n")); - - /* This isn't actually needed, but does serve to error out if the - string is invalid. */ - if(opt.def_preference_list && - keygen_set_std_prefs(opt.def_preference_list,0)) - log_error(_("invalid default preferences\n")); - - /* We provide defaults for the personal digest list */ - if(!pers_digest_list) - pers_digest_list="h2"; - - if(pers_cipher_list && - keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM)) - log_error(_("invalid personal cipher preferences\n")); - - if(pers_digest_list && - keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH)) - log_error(_("invalid personal digest preferences\n")); - - if(pers_compress_list && - keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP)) - log_error(_("invalid personal compress preferences\n")); - - /* We don't support all possible commands with multifile yet */ - if(multifile) - { - char *cmdname; - - switch(cmd) - { - case aSign: - cmdname="--sign"; - break; - case aClearsign: - cmdname="--clearsign"; - break; - case aDetachedSign: - cmdname="--detach-sign"; - break; - case aSym: - cmdname="--symmetric"; - break; - case aStore: - cmdname="--store"; - break; - default: - cmdname=NULL; - break; - } - - if(cmdname) - log_error(_("%s does not yet work with %s\n"),cmdname,"--multifile"); - } - - if( log_get_errorcount(0) ) - g10_exit(2); - - /* Check our chosen algorithms against the list of legal - algorithms. */ - - if(!GNUPG) - { - const char *badalg=NULL; - preftype_t badtype=PREFTYPE_NONE; - - if (opt.def_cipher_algo - && !algo_available (PREFTYPE_SYM,opt.def_cipher_algo,NULL)) - { - badalg = gcry_cipher_algo_name (opt.def_cipher_algo); - badtype = PREFTYPE_SYM; - } - else if (opt.def_digest_algo - && !algo_available (PREFTYPE_HASH,opt.def_digest_algo,NULL)) - { - badalg = gcry_md_algo_name (opt.def_digest_algo); - badtype = PREFTYPE_HASH; - } - else if (opt.cert_digest_algo - && !algo_available (PREFTYPE_HASH,opt.cert_digest_algo,NULL)) - { - badalg = gcry_md_algo_name (opt.cert_digest_algo); - badtype = PREFTYPE_HASH; - } - else if (opt.def_compress_algo!=-1 - && !algo_available (PREFTYPE_ZIP,opt.def_compress_algo,NULL)) - { - badalg = compress_algo_to_string (opt.def_compress_algo); - badtype = PREFTYPE_ZIP; - } - - if (badalg) - { - switch(badtype) - { - case PREFTYPE_SYM: - log_info(_("you may not use cipher algorithm \"%s\" " - "while in %s mode\n"), - badalg,compliance_option_string()); - break; - case PREFTYPE_HASH: - log_info(_("you may not use digest algorithm \"%s\" " - "while in %s mode\n"), - badalg,compliance_option_string()); - break; - case PREFTYPE_ZIP: - log_info(_("you may not use compression algorithm \"%s\" " - "while in %s mode\n"), - badalg,compliance_option_string()); - break; - default: - BUG(); - } - - compliance_failure(); - } - } - - /* set the random seed file */ - if( use_random_seed ) { - char *p = make_filename(opt.homedir, "random_seed", NULL ); - gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p); - xfree (p); - } - - if( !cmd && opt.fingerprint && !with_fpr ) { - set_cmd( &cmd, aListKeys); - } - - /* Compression algorithm 0 means no compression at all */ - if( opt.def_compress_algo == 0) - opt.compress = 0; - - /* kludge to let -sat generate a clear text signature */ - if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign ) - cmd = aClearsign; - - if( opt.verbose > 1 ) - set_packet_list_mode(1); - - /* Add the keyrings, but not for some special commands. 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 != aGPGConfList ) - { - if (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); - for (sl = sec_nrings; sl; sl = sl->next) - keydb_add_resource ( sl->d, 0, 1 ); - } - if( !nrings || default_keyring ) /* add default ring */ - keydb_add_resource ("pubring" EXTSEP_S "gpg", 0, 0); - for(sl = nrings; sl; sl = sl->next ) - keydb_add_resource ( sl->d, sl->flags, 0 ); - } - FREE_STRLIST(nrings); - FREE_STRLIST(sec_nrings); - - - if( pwfd != -1 ) /* read the passphrase now. */ - read_passphrase_from_fd( pwfd ); - - fname = argc? *argv : NULL; - - switch( cmd ) { - case aPrimegen: - case aPrintMD: - case aPrintMDs: - case aGenRandom: - case aDeArmor: - case aEnArmor: - case aFixTrustDB: - case aCardStatus: - case aCardEdit: - case aChangePIN: - case aGPGConfList: - break; - case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break; - case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break; - default: rc = setup_trustdb(1, trustdb_name ); break; - } - if( rc ) - log_error(_("failed to initialize the TrustDB: %s\n"), gpg_strerror (rc)); - - - switch (cmd) { - case aStore: - case aSym: - case aSign: - case aSignSym: - case aClearsign: - if (!opt.quiet && any_explicit_recipient) - log_info (_("WARNING: recipients (-r) given " - "without using public key encryption\n")); - break; - default: - break; - } - - switch( cmd ) { - case aStore: /* only store the file */ - if( argc > 1 ) - wrong_args(_("--store [filename]")); - if( (rc = encode_store(fname)) ) - log_error ("\b%s: store failed: %s\n", - print_fname_stdin(fname), gpg_strerror (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 ("\b%s: symmetric encryption failed: %s\n", - print_fname_stdin(fname), gpg_strerror (rc) ); - break; - - case aEncr: /* encrypt the given file */ - if(multifile) - encode_crypt_files(argc, argv, remusr); - else - { - if( argc > 1 ) - wrong_args(_("--encrypt [filename]")); - if( (rc = encode_crypt(fname,remusr)) ) - log_error("%s: encryption failed: %s\n", - print_fname_stdin(fname), gpg_strerror (rc) ); - } - break; - - case aSign: /* sign the given file */ - sl = NULL; - if( detached_sig ) { /* sign all files */ - for( ; argc; argc--, argv++ ) - add_to_strlist( &sl, *argv ); - } - else { - if( argc > 1 ) - wrong_args(_("--sign [filename]")); - if( argc ) { - sl = xcalloc (1, sizeof *sl + strlen(fname)); - strcpy(sl->d, fname); - } - } - if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) ) - log_error("signing failed: %s\n", gpg_strerror (rc) ); - free_strlist(sl); - break; - - case aSignEncr: /* sign and encrypt the given file */ - if( argc > 1 ) - wrong_args(_("--sign --encrypt [filename]")); - if( argc ) { - sl = xcalloc (1, sizeof *sl + strlen(fname)); - strcpy(sl->d, fname); - } - else - sl = NULL; - if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) ) - log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), gpg_strerror (rc) ); - free_strlist(sl); - break; - - case aSignSym: /* sign and conventionally encrypt the given file */ - if (argc > 1) - wrong_args(_("--sign --symmetric [filename]")); - rc = sign_symencrypt_file (fname, locusr); - if (rc) - log_error("%s: sign+symmetric failed: %s\n", - print_fname_stdin(fname), gpg_strerror (rc) ); - break; - - case aClearsign: /* make a clearsig */ - if( argc > 1 ) - wrong_args(_("--clearsign [filename]")); - if( (rc = clearsign_file(fname, locusr, NULL)) ) - log_error("%s: clearsign failed: %s\n", - print_fname_stdin(fname), gpg_strerror (rc) ); - break; - - case aVerify: - if(multifile) - { - if( (rc = verify_files( argc, argv ) )) - log_error("verify files failed: %s\n", gpg_strerror (rc) ); - } - else - { - if( (rc = verify_signatures( argc, argv ) )) - log_error("verify signatures failed: %s\n", gpg_strerror (rc) ); - } - break; - - case aDecrypt: - if(multifile) - decrypt_messages(argc, argv); - else - { - if( argc > 1 ) - wrong_args(_("--decrypt [filename]")); - if( (rc = decrypt_message( fname ) )) - log_error("decrypt_message failed: %s\n", gpg_strerror (rc) ); - } - break; - - case aSignKey: /* sign the key given as argument */ - if( argc != 1 ) - wrong_args(_("--sign-key user-id")); - username = make_username( fname ); - keyedit_menu(fname, locusr, NULL, 1 ); - xfree (username); - break; - - case aLSignKey: - if( argc != 1 ) - wrong_args(_("--lsign-key user-id")); - username = make_username( fname ); - keyedit_menu(fname, locusr, NULL, 2 ); - xfree (username); - break; - - case aNRSignKey: - if( argc != 1 ) - wrong_args(_("--nrsign-key user-id")); - username = make_username( fname ); - keyedit_menu(fname, locusr, NULL, 3 ); - xfree (username); - break; - - case aNRLSignKey: - if( argc != 1 ) - wrong_args(_("--nrlsign-key user-id")); - username = make_username( fname ); - keyedit_menu(fname, locusr, NULL, 4 ); - xfree (username); - break; - - case aEditKey: /* Edit a key signature */ - if( !argc ) - wrong_args(_("--edit-key user-id [commands]")); - username = make_username( fname ); - if( argc > 1 ) { - sl = NULL; - for( argc--, argv++ ; argc; argc--, argv++ ) - append_to_strlist( &sl, *argv ); - keyedit_menu( username, locusr, sl, 0 ); - free_strlist(sl); - } - else - keyedit_menu(username, locusr, NULL, 0 ); - xfree (username); - break; - - case aDeleteKeys: - case aDeleteSecretKeys: - case aDeleteSecretAndPublicKeys: - sl = NULL; - /* I'm adding these in reverse order as add_to_strlist2 - reverses them again, and it's easier to understand in the - proper order :) */ - for( ; argc; argc-- ) - add_to_strlist2( &sl, argv[argc-1], utf8_strings ); - delete_keys(sl,cmd==aDeleteSecretKeys,cmd==aDeleteSecretAndPublicKeys); - free_strlist(sl); - break; - - case aCheckKeys: - opt.check_sigs = 1; - case aListSigs: - opt.list_sigs = 1; - case aListKeys: - sl = NULL; - for( ; argc; argc--, argv++ ) - add_to_strlist2( &sl, *argv, utf8_strings ); - public_key_list( sl ); - free_strlist(sl); - break; - case aListSecretKeys: - sl = NULL; - for( ; argc; argc--, argv++ ) - add_to_strlist2( &sl, *argv, utf8_strings ); - secret_key_list( sl ); - free_strlist(sl); - break; - - case aKeygen: /* generate a key */ - if( opt.batch ) { - if( argc > 1 ) - wrong_args("--gen-key [parameterfile]"); - generate_keypair( argc? *argv : NULL, NULL ); - } - else { - if( argc ) - wrong_args("--gen-key"); - generate_keypair(NULL, NULL); - } - break; - - case aFastImport: - opt.import_options |= IMPORT_FAST_IMPORT; - case aImport: - import_keys( argc? argv:NULL, argc, NULL, opt.import_options ); - break; - - case aExport: - case aExportAll: - case aSendKeys: - case aRecvKeys: - sl = NULL; - for( ; argc; argc--, argv++ ) - add_to_strlist2( &sl, *argv, utf8_strings ); - if( cmd == aSendKeys ) - rc=keyserver_export( sl ); - else if( cmd == aRecvKeys ) - rc=keyserver_import( sl ); - else - rc=export_pubkeys( sl, opt.export_options ); - if(rc) - { - if(cmd==aSendKeys) - log_error(_("keyserver send failed: %s\n"),gpg_strerror (rc)); - else if(cmd==aRecvKeys) - log_error(_("keyserver receive failed: %s\n"),gpg_strerror (rc)); - else - log_error(_("key export failed: %s\n"),gpg_strerror (rc)); - } - free_strlist(sl); - break; - - case aSearchKeys: - sl = NULL; - for( ; argc; argc--, argv++ ) - { - if (utf8_strings) - sl = append_to_strlist ( &sl, *argv ); - else - { - char *p = native_to_utf8 ( *argv ); - sl = append_to_strlist( &sl, p ); - xfree( p ); - } - } - - rc=keyserver_search( sl ); - if(rc) - log_error(_("keyserver search failed: %s\n"),gpg_strerror (rc)); - free_strlist(sl); - break; - - case aRefreshKeys: - sl = NULL; - for( ; argc; argc--, argv++ ) - add_to_strlist2( &sl, *argv, utf8_strings ); - rc=keyserver_refresh(sl); - if(rc) - log_error(_("keyserver refresh failed: %s\n"),gpg_strerror (rc)); - free_strlist(sl); - break; - - case aExportSecret: - sl = NULL; - for( ; argc; argc--, argv++ ) - add_to_strlist2( &sl, *argv, utf8_strings ); - export_seckeys( sl ); - free_strlist(sl); - break; - - case aExportSecretSub: - sl = NULL; - for( ; argc; argc--, argv++ ) - add_to_strlist2( &sl, *argv, utf8_strings ); - export_secsubkeys( sl ); - free_strlist(sl); - break; - - case aGenRevoke: - if( argc != 1 ) - wrong_args("--gen-revoke user-id"); - username = make_username(*argv); - gen_revoke( username ); - xfree ( username ); - break; - - case aDesigRevoke: - if( argc != 1 ) - wrong_args("--desig-revoke user-id"); - username = make_username(*argv); - gen_desig_revoke( username ); - xfree ( username ); - break; - - case aDeArmor: - if( argc > 1 ) - wrong_args("--dearmor [file]"); - rc = dearmor_file( argc? *argv: NULL ); - if( rc ) - log_error(_("dearmoring failed: %s\n"), gpg_strerror (rc)); - break; - - case aEnArmor: - if( argc > 1 ) - wrong_args("--enarmor [file]"); - rc = enarmor_file( argc? *argv: NULL ); - if( rc ) - log_error(_("enarmoring failed: %s\n"), gpg_strerror (rc)); - break; - - - case aPrimegen: -#if 0 /*FIXME-XXX*/ - { int mode = argc < 2 ? 0 : atoi(*argv); - - if( mode == 1 && argc == 2 ) { - mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1); - } - else if( mode == 2 && argc == 3 ) { - mpi_print( stdout, generate_elg_prime( - 0, atoi(argv[1]), - atoi(argv[2]), NULL,NULL ), 1); - } - else if( mode == 3 && argc == 3 ) { - gcry_mpi_t *factors; - mpi_print( stdout, generate_elg_prime( - 1, atoi(argv[1]), - atoi(argv[2]), NULL,&factors ), 1); - putchar('\n'); - mpi_print( stdout, factors[0], 1 ); /* print q */ - } - else if( mode == 4 && argc == 3 ) { - gcry_mpi_t g = mpi_alloc(1); - mpi_print( stdout, generate_elg_prime( - 0, atoi(argv[1]), - atoi(argv[2]), g, NULL ), 1); - putchar('\n'); - mpi_print( stdout, g, 1 ); - mpi_free(g); - } - else - wrong_args("--gen-prime mode bits [qbits] "); - putchar('\n'); - } -#endif - break; - - case aGenRandom: - { - int level = argc ? atoi(*argv):0; - int count = argc > 1 ? atoi(argv[1]): 0; - int endless = !count; - - if( argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0 ) - wrong_args("--gen-random 0|1|2 [count]"); - - while( endless || count ) { - byte *p; - /* Wee need a multiple of 3, so that in case of - armored output we get a correct string. No - linefolding is done, as it is best to levae this to - other tools */ - size_t n = !endless && count < 99? count : 99; - - p = gcry_random_bytes (n, level); -#ifdef HAVE_DOSISH_SYSTEM - setmode ( fileno(stdout), O_BINARY ); -#endif - if (opt.armor) { - char *tmp = make_radix64_string (p, n); - fputs (tmp, stdout); - xfree (tmp); - if (n%3 == 1) - putchar ('='); - if (n%3) - putchar ('='); - } else { - fwrite( p, n, 1, stdout ); - } - xfree (p); - if( !endless ) - count -= n; - } - if (opt.armor) - putchar ('\n'); - } - break; - - case aPrintMD: - if( argc < 1) - wrong_args("--print-md algo [files]"); - { - int all_algos = (**argv=='*' && !(*argv)[1]); - int algo = all_algos? 0 : gcry_md_map_name (*argv); - - if( !algo && !all_algos ) - log_error(_("invalid hash algorithm `%s'\n"), *argv ); - else { - argc--; argv++; - if( !argc ) - print_mds(NULL, algo); - else { - for(; argc; argc--, argv++ ) - print_mds(*argv, algo); - } - } - } - break; - - case aPrintMDs: /* old option */ - if( !argc ) - print_mds(NULL,0); - else { - for(; argc; argc--, argv++ ) - print_mds(*argv,0); - } - break; - - case aListTrustDB: - if( !argc ) - list_trustdb(NULL); - else { - for( ; argc; argc--, argv++ ) - list_trustdb( *argv ); - } - break; - - case aUpdateTrustDB: - if( argc ) - wrong_args("--update-trustdb"); - update_trustdb(); - break; - - case aCheckTrustDB: - /* Old versions allowed for arguments - ignore them */ - check_trustdb(); - break; - - case aFixTrustDB: - log_error("this command is not yet implemented.\n"); - log_error("A workaround is to use \"--export-ownertrust\", remove\n"); - log_error("the trustdb file and do an \"--import-ownertrust\".\n" ); - break; - - case aListTrustPath: - if( !argc ) - wrong_args("--list-trust-path <user-ids>"); - for( ; argc; argc--, argv++ ) { - username = make_username( *argv ); - list_trust_path( username ); - xfree (username); - } - break; - - case aExportOwnerTrust: - if( argc ) - wrong_args("--export-ownertrust"); - export_ownertrust(); - break; - - case aImportOwnerTrust: - if( argc > 1 ) - wrong_args("--import-ownertrust [file]"); - import_ownertrust( argc? *argv:NULL ); - break; - - case aPipeMode: - if ( argc ) - wrong_args ("--pipemode"); - run_in_pipemode (); - break; - - case aRebuildKeydbCaches: - if (argc) - wrong_args ("--rebuild-keydb-caches"); - keydb_rebuild_caches (); - break; - - case aCardStatus: - if (argc) - wrong_args ("--card-status"); - card_status (stdout, NULL, 0); - break; - - case aCardEdit: - if (argc) - { - sl = NULL; - for (argc--, argv++ ; argc; argc--, argv++) - append_to_strlist (&sl, *argv); - card_edit (sl); - free_strlist (sl); - } - else - card_edit (NULL); - break; - - case aChangePIN: - if (!argc) - change_pin (0); - else if (argc == 1) - change_pin ( atoi (*argv)); - else - wrong_args ("--change-pin [no]"); - break; - - case aGPGConfList: - { /* List options and default values in the GPG Conf format. */ - - /* The following list is taken from gnupg/tools/gpgconf-comp.c. */ - /* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING - FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */ -#define GC_OPT_FLAG_NONE 0UL - /* The RUNTIME flag for an option indicates that the option can be - changed at runtime. */ -#define GC_OPT_FLAG_RUNTIME (1UL << 3) - /* The DEFAULT flag for an option indicates that the option has a - default value. */ -#define GC_OPT_FLAG_DEFAULT (1UL << 4) - /* The DEF_DESC flag for an option indicates that the option has a - default, which is described by the value of the default field. */ -#define GC_OPT_FLAG_DEF_DESC (1UL << 5) - /* The NO_ARG_DESC flag for an option indicates that the argument has - a default, which is described by the value of the ARGDEF field. */ -#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) - - if (!config_filename) - config_filename = make_filename (opt.homedir, "gpg.conf", NULL); - - printf ("gpgconf-gpg.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, config_filename); - - printf ("verbose:%lu:\n" - "quiet:%lu:\n" - "debug-level:%lu:\"none:\n" - "log-file:%lu:\n", - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_DEFAULT, - GC_OPT_FLAG_NONE ); - printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE); - - } - break; - - case aListPackets: - opt.list_packets=2; - default: - if( argc > 1 ) - wrong_args(_("[filename]")); - /* Issue some output for the unix newbie */ - if( !fname && !opt.outfile && isatty( fileno(stdin) ) - && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) ) - log_info(_("Go ahead and type your message ...\n")); - - if( !(a = iobuf_open(fname)) ) - log_error(_("can't open `%s'\n"), print_fname_stdin(fname)); - else { - - if( !opt.no_armor ) { - if( use_armor_filter( a ) ) { - memset( &afx, 0, sizeof afx); - iobuf_push_filter( a, armor_filter, &afx ); - } - } - if( cmd == aListPackets ) { - set_packet_list_mode(1); - opt.list_packets=1; - } - rc = proc_packets(NULL, a ); - if( rc ) - log_error("processing message failed: %s\n", gpg_strerror (rc) ); - iobuf_close(a); - } - break; - } - - /* cleanup */ - FREE_STRLIST(remusr); - FREE_STRLIST(locusr); - g10_exit(0); - return 8; /*NEVER REACHED*/ -} - -/* Note: This function is used by signal handlers!. */ -static void -emergency_cleanup (void) -{ - gcry_control (GCRYCTL_TERM_SECMEM ); -} - - -void -g10_exit( int rc ) -{ - gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); - if (opt.debug & DBG_MEMSTAT_VALUE) - { - gcry_control( GCRYCTL_DUMP_MEMORY_STATS ); - gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); - } - if (opt.debug) - gcry_control (GCRYCTL_DUMP_SECMEM_STATS ); - emergency_cleanup (); - rc = rc? rc : log_get_errorcount(0)? 2 : - g10_errors_seen? 1 : 0; - exit (rc ); -} - - -/* Pretty-print hex hashes. This assumes at least an 80-character - display, but there are a few other similar assumptions in the - display code. */ -static void -print_hex( MD_HANDLE md, int algo, const char *fname ) -{ - int i,n,count,indent=0; - const byte *p; - - if(fname) - indent=printf("%s: ",fname); - - if(indent>40) - { - printf("\n"); - indent=0; - } - - if(algo==DIGEST_ALGO_RMD160) - indent+=printf("RMD160 = "); - else if(algo>0) - indent+=printf("%6s = ", gcry_md_algo_name (algo)); - else - algo=abs(algo); - - count=indent; - - p = gcry_md_read (md, algo); - n = gcry_md_get_algo_dlen (algo); - - count+=printf("%02X",*p++); - - for(i=1;i<n;i++,p++) - { - if(n==16) - { - if(count+2>79) - { - printf("\n%*s",indent," "); - count=indent; - } - else - count+=printf(" "); - - if(!(i%8)) - count+=printf(" "); - } - else if (n==20) - { - if(!(i%2)) - { - if(count+4>79) - { - printf("\n%*s",indent," "); - count=indent; - } - else - count+=printf(" "); - } - - if(!(i%10)) - count+=printf(" "); - } - else - { - if(!(i%4)) - { - if(count+8>79) - { - printf("\n%*s",indent," "); - count=indent; - } - else - count+=printf(" "); - } - } - - count+=printf("%02X",*p); - } - - printf("\n"); -} - -static void -print_hashline( MD_HANDLE md, int algo, const char *fname ) -{ - int i, n; - const byte *p; - - if ( fname ) { - for (p = fname; *p; p++ ) { - if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' ) - printf("%%%02X", *p ); - else - putchar( *p ); - } - } - putchar(':'); - printf("%d:", algo ); - p = gcry_md_read (md, algo ); - n = gcry_md_get_algo_dlen (algo); - for(i=0; i < n ; i++, p++ ) - printf("%02X", *p ); - putchar(':'); - putchar('\n'); -} - -static void -print_mds( const char *fname, int algo ) -{ - FILE *fp; - char buf[1024]; - size_t n; - MD_HANDLE md; - - if( !fname ) { - fp = stdin; -#ifdef HAVE_DOSISH_SYSTEM - setmode ( fileno(fp) , O_BINARY ); -#endif - } - else { - fp = fopen( fname, "rb" ); - } - if( !fp ) { - log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) ); - return; - } - - gcry_md_open (&md, 0, 0 ); - if( algo ) - gcry_md_enable ( md, algo ); - else { - gcry_md_enable (md, GCRY_MD_MD5 ); - gcry_md_enable (md, GCRY_MD_SHA1 ); - gcry_md_enable (md, GCRY_MD_RMD160 ); -#ifdef USE_SHA256 - gcry_md_enable (md, GCRY_MD_SHA256 ); -#endif -#ifdef USE_SHA512 - gcry_md_enable (md, GCRY_MD_SHA384 ); - gcry_md_enable (md, GCRY_MD_SHA512 ); -#endif - } - - while( (n=fread( buf, 1, DIM(buf), fp )) ) - gcry_md_write (md, buf, n); - if( ferror(fp) ) - log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) ); - else { - gcry_md_final (md); - if ( opt.with_colons ) { - if ( algo ) - print_hashline( md, algo, fname ); - else { - print_hashline( md, GCRY_MD_MD5, fname ); - print_hashline( md, GCRY_MD_SHA1, fname ); - print_hashline( md, GCRY_MD_RMD160, fname ); -#ifdef USE_SHA256 - print_hashline( md, GCRY_MD_SHA256, fname ); -#endif -#ifdef USE_SHA512 - print_hashline( md, GCRY_MD_SHA384, fname ); - print_hashline( md, GCRY_MD_SHA512, fname ); -#endif - } - } - else { - if( algo ) - print_hex(md,-algo,fname); - else { - print_hex( md, GCRY_MD_MD5, fname ); - print_hex( md, GCRY_MD_SHA1, fname ); - print_hex( md, GCRY_MD_RMD160, fname ); -#ifdef USE_SHA256 - print_hex( md, GCRY_MD_SHA256, fname ); -#endif -#ifdef USE_SHA512 - print_hex( md, GCRY_MD_SHA384, fname ); - print_hex( md, GCRY_MD_SHA512, fname ); -#endif - } - } - } - gcry_md_close (md); - - if( fp != stdin ) - fclose(fp); -} - - -/**************** - * Check the supplied name,value string and add it to the notation - * data to be used for signatures. which==0 for sig notations, and 1 - * for cert notations. -*/ -static void -add_notation_data( const char *string, int which ) -{ - const char *s; - STRLIST sl,*notation_data; - int critical=0; - int highbit=0; - int saw_at=0; - - if(which) - notation_data=&opt.cert_notation_data; - else - notation_data=&opt.sig_notation_data; - - if( *string == '!' ) { - critical = 1; - string++; - } - - /* If and when the IETF assigns some official name tags, we'll - have to add them here. */ - - for( s=string ; *s != '='; s++ ) - { - if( *s=='@') - saw_at=1; - - if( !*s || (*s & 0x80) || (!isgraph(*s) && !isspace(*s)) ) - { - log_error(_("a notation name must have only printable characters " - "or spaces, and end with an '='\n") ); - return; - } - } - - if(!saw_at && !opt.expert) - { - log_error( - _("a user notation name must contain the '@' character\n")); - return; - } - - /* we only support printable text - therefore we enforce the use - * of only printable characters (an empty value is valid) */ - for( s++; *s ; s++ ) { - if( *s & 0x80 ) - highbit = 1; - else if( iscntrl(*s) ) { - log_error(_("a notation value must not use " - "any control characters\n") ); - return; - } - } - - if( highbit ) /* must use UTF8 encoding */ - sl = add_to_strlist2( notation_data, string, utf8_strings ); - else - sl = add_to_strlist( notation_data, string ); - - if( critical ) - sl->flags |= 1; -} - - -static void -add_policy_url( const char *string, int which ) -{ - int i,critical=0; - STRLIST sl; - - if(*string=='!') - { - string++; - critical=1; - } - - for(i=0;i<strlen(string);i++) - if(string[i]&0x80 || iscntrl(string[i])) - break; - - if(i==0 || i<strlen(string)) - { - if(which) - log_error(_("the given certification policy URL is invalid\n")); - else - log_error(_("the given signature policy URL is invalid\n")); - } - - if(which) - sl=add_to_strlist( &opt.cert_policy_url, string ); - else - sl=add_to_strlist( &opt.sig_policy_url, string ); - - if(critical) - sl->flags |= 1; -} - - -static void -add_keyserver_url( const char *string, int which ) -{ - int i,critical=0; - STRLIST sl; - - if(*string=='!') - { - string++; - critical=1; - } - - for(i=0;i<strlen(string);i++) - if(string[i]&0x80 || iscntrl(string[i])) - break; - - if(i==0 || i<strlen(string)) - { - if(which) - BUG(); - else - log_error(_("the given signature preferred" - " keyserver URL is invalid\n")); - } - - if(which) - BUG(); - else - sl=add_to_strlist( &opt.sig_keyserver_url, string ); - - if(critical) - sl->flags |= 1; -} - diff --git a/g10/getkey.c b/g10/getkey.c deleted file mode 100644 index f51b8f2df..000000000 --- a/g10/getkey.c +++ /dev/null @@ -1,2618 +0,0 @@ -/* getkey.c - Get a key from the database - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <ctype.h> - -#include "gpg.h" -#include "util.h" -#include "packet.h" -#include "memory.h" -#include "iobuf.h" -#include "keydb.h" -#include "options.h" -#include "main.h" -#include "trustdb.h" -#include "i18n.h" - -#define MAX_PK_CACHE_ENTRIES 200 -#define MAX_UID_CACHE_ENTRIES 200 - -#if MAX_PK_CACHE_ENTRIES < 2 -#error We need the cache for key creation -#endif - - -struct getkey_ctx_s { - int exact; - KBNODE keyblock; - KBPOS kbpos; - KBNODE found_key; /* pointer into some keyblock */ - int last_rc; - int req_usage; - int req_algo; - KEYDB_HANDLE kr_handle; - int not_allocated; - int nitems; - KEYDB_SEARCH_DESC items[1]; -}; - -#if 0 -static struct { - int any; - int okay_count; - int nokey_count; - int error_count; -} lkup_stats[21]; -#endif - -typedef struct keyid_list { - struct keyid_list *next; - u32 keyid[2]; -} *keyid_list_t; - - -#if MAX_PK_CACHE_ENTRIES - typedef struct pk_cache_entry { - struct pk_cache_entry *next; - u32 keyid[2]; - PKT_public_key *pk; - } *pk_cache_entry_t; - static pk_cache_entry_t pk_cache; - static int pk_cache_entries; /* number of entries in pk cache */ - static int pk_cache_disabled; -#endif - -#if MAX_UID_CACHE_ENTRIES < 5 -#error we really need the userid cache -#endif -typedef struct user_id_db { - struct user_id_db *next; - keyid_list_t keyids; - int len; - char name[1]; -} *user_id_db_t; -static user_id_db_t user_id_db; -static int uid_cache_entries; /* number of entries in uid cache */ - -static void merge_selfsigs( KBNODE keyblock ); -static int lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode ); - -#if 0 -static void -print_stats() -{ - int i; - for(i=0; i < DIM(lkup_stats); i++ ) { - if( lkup_stats[i].any ) - fprintf(stderr, - "lookup stats: mode=%-2d ok=%-6d nokey=%-6d err=%-6d\n", - i, - lkup_stats[i].okay_count, - lkup_stats[i].nokey_count, - lkup_stats[i].error_count ); - } -} -#endif - - -void -cache_public_key( PKT_public_key *pk ) -{ -#if MAX_PK_CACHE_ENTRIES - pk_cache_entry_t ce; - u32 keyid[2]; - - if( pk_cache_disabled ) - return; - - if( pk->dont_cache ) - return; - - if( is_ELGAMAL(pk->pubkey_algo) - || pk->pubkey_algo == PUBKEY_ALGO_DSA - || is_RSA(pk->pubkey_algo) ) { - keyid_from_pk( pk, keyid ); - } - else - return; /* don't know how to get the keyid */ - - for( ce = pk_cache; ce; ce = ce->next ) - if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) { - if( DBG_CACHE ) - log_debug("cache_public_key: already in cache\n"); - return; - } - - if( pk_cache_entries >= MAX_PK_CACHE_ENTRIES ) { - /* fixme: use another algorithm to free some cache slots */ - pk_cache_disabled=1; - if( opt.verbose > 1 ) - log_info(_("too many entries in pk cache - disabled\n")); - return; - } - pk_cache_entries++; - ce = xmalloc ( sizeof *ce ); - ce->next = pk_cache; - pk_cache = ce; - ce->pk = copy_public_key( NULL, pk ); - ce->keyid[0] = keyid[0]; - ce->keyid[1] = keyid[1]; -#endif -} - - -/* - * Return the user ID from the given keyblock. - * We use the primary uid flag which has been set by the merge_selfsigs - * function. The returned value is only valid as long as then given - * keyblock is not changed - */ -static const char * -get_primary_uid ( KBNODE keyblock, size_t *uidlen ) -{ - KBNODE k; - const char *s; - - for (k=keyblock; k; k=k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID - && !k->pkt->pkt.user_id->attrib_data - && k->pkt->pkt.user_id->is_primary ) { - *uidlen = k->pkt->pkt.user_id->len; - return k->pkt->pkt.user_id->name; - } - } - /* fixme: returning translatable constants instead of a user ID is - * not good because they are probably not utf-8 encoded. */ - s = _("[User id not found]"); - *uidlen = strlen (s); - return s; -} - - -static void -release_keyid_list ( keyid_list_t k ) -{ - while ( k ) { - keyid_list_t k2 = k->next; - xfree (k); - k = k2; - } -} - -/**************** - * Store the association of keyid and userid - * Feed only public keys to this function. - */ -static void -cache_user_id( KBNODE keyblock ) -{ - user_id_db_t r; - const char *uid; - size_t uidlen; - keyid_list_t keyids = NULL; - KBNODE k; - - for (k=keyblock; k; k = k->next ) { - if ( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - keyid_list_t a = xcalloc (1, sizeof *a ); - /* Hmmm: For a long list of keyids it might be an advantage - * to append the keys */ - keyid_from_pk( k->pkt->pkt.public_key, a->keyid ); - /* first check for duplicates */ - for(r=user_id_db; r; r = r->next ) { - keyid_list_t b = r->keyids; - for ( b = r->keyids; b; b = b->next ) { - if( b->keyid[0] == a->keyid[0] - && b->keyid[1] == a->keyid[1] ) { - if( DBG_CACHE ) - log_debug("cache_user_id: already in cache\n"); - release_keyid_list ( keyids ); - xfree ( a ); - return; - } - } - } - /* now put it into the cache */ - a->next = keyids; - keyids = a; - } - } - if ( !keyids ) - BUG (); /* No key no fun */ - - - uid = get_primary_uid ( keyblock, &uidlen ); - - if( uid_cache_entries >= MAX_UID_CACHE_ENTRIES ) { - /* fixme: use another algorithm to free some cache slots */ - r = user_id_db; - user_id_db = r->next; - release_keyid_list ( r->keyids ); - xfree (r); - uid_cache_entries--; - } - r = xmalloc ( sizeof *r + uidlen-1 ); - r->keyids = keyids; - r->len = uidlen; - memcpy(r->name, uid, r->len); - r->next = user_id_db; - user_id_db = r; - uid_cache_entries++; -} - - -void -getkey_disable_caches() -{ -#if MAX_PK_CACHE_ENTRIES - { - pk_cache_entry_t ce, ce2; - - for( ce = pk_cache; ce; ce = ce2 ) { - ce2 = ce->next; - free_public_key( ce->pk ); - xfree ( ce ); - } - pk_cache_disabled=1; - pk_cache_entries = 0; - pk_cache = NULL; - } -#endif - /* fixme: disable user id cache ? */ -} - - -static void -pk_from_block ( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE keyblock ) -{ - KBNODE a = ctx->found_key ? ctx->found_key : keyblock; - - assert ( a->pkt->pkttype == PKT_PUBLIC_KEY - || a->pkt->pkttype == PKT_PUBLIC_SUBKEY ); - - copy_public_key ( pk, a->pkt->pkt.public_key ); -} - -static void -sk_from_block ( GETKEY_CTX ctx, - PKT_secret_key *sk, KBNODE keyblock ) -{ - KBNODE a = ctx->found_key ? ctx->found_key : keyblock; - - assert ( a->pkt->pkttype == PKT_SECRET_KEY - || a->pkt->pkttype == PKT_SECRET_SUBKEY ); - - copy_secret_key( sk, a->pkt->pkt.secret_key); -} - - -/**************** - * Get a public key and store it into the allocated pk - * can be called with PK set to NULL to just read it into some - * internal structures. - */ -int -get_pubkey( PKT_public_key *pk, u32 *keyid ) -{ - int internal = 0; - int rc = 0; - -#if MAX_PK_CACHE_ENTRIES - { /* Try to get it from the cache */ - pk_cache_entry_t ce; - for( ce = pk_cache; ce; ce = ce->next ) { - if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) { - if( pk ) - copy_public_key( pk, ce->pk ); - return 0; - } - } - } -#endif - /* more init stuff */ - if( !pk ) { - pk = xcalloc (1, sizeof *pk ); - internal++; - } - - - /* do a lookup */ - { struct getkey_ctx_s ctx; - KBNODE kb = NULL; - memset( &ctx, 0, sizeof ctx ); - ctx.exact = 1; /* use the key ID exactly as given */ - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (0); - ctx.nitems = 1; - ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; - ctx.items[0].u.kid[0] = keyid[0]; - ctx.items[0].u.kid[1] = keyid[1]; - ctx.req_algo = pk->req_algo; - ctx.req_usage = pk->req_usage; - rc = lookup( &ctx, &kb, 0 ); - if ( !rc ) { - pk_from_block ( &ctx, pk, kb ); - } - get_pubkey_end( &ctx ); - release_kbnode ( kb ); - } - if( !rc ) - goto leave; - - rc = GPG_ERR_NO_PUBKEY; - - leave: - if( !rc ) - cache_public_key( pk ); - if( internal ) - free_public_key(pk); - return rc; -} - - -/* Get a public key and store it into the allocated pk. This function - differs from get_pubkey() in that it does not do a check of the key - to avoid recursion. It should be used only in very certain cases. */ -int -get_pubkey_fast (PKT_public_key *pk, u32 *keyid) -{ - int rc = 0; - KEYDB_HANDLE hd; - KBNODE keyblock; - - assert (pk); -#if MAX_PK_CACHE_ENTRIES - { /* Try to get it from the cache */ - pk_cache_entry_t ce; - - for (ce = pk_cache; ce; ce = ce->next) - { - if (ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1]) - { - if (pk) - copy_public_key (pk, ce->pk); - return 0; - } - } - } -#endif - - hd = keydb_new (0); - rc = keydb_search_kid (hd, keyid); - if (rc == -1) - { - keydb_release (hd); - return GPG_ERR_NO_PUBKEY; - } - rc = keydb_get_keyblock (hd, &keyblock); - keydb_release (hd); - if (rc) - { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - return GPG_ERR_NO_PUBKEY; - } - - assert ( keyblock->pkt->pkttype == PKT_PUBLIC_KEY - || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY ); - copy_public_key (pk, keyblock->pkt->pkt.public_key ); - release_kbnode (keyblock); - - /* Not caching key here since it won't have all of the fields - properly set. */ - - return 0; -} - - - -KBNODE -get_pubkeyblock( u32 *keyid ) -{ - struct getkey_ctx_s ctx; - int rc = 0; - KBNODE keyblock = NULL; - - memset( &ctx, 0, sizeof ctx ); - /* no need to set exact here because we want the entire block */ - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (0); - ctx.nitems = 1; - ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; - ctx.items[0].u.kid[0] = keyid[0]; - ctx.items[0].u.kid[1] = keyid[1]; - rc = lookup( &ctx, &keyblock, 0 ); - get_pubkey_end( &ctx ); - - return rc ? NULL : keyblock; -} - - - - -/**************** - * Get a secret key and store it into sk - */ -int -get_seckey( PKT_secret_key *sk, u32 *keyid ) -{ - int rc; - struct getkey_ctx_s ctx; - KBNODE kb = NULL; - - memset( &ctx, 0, sizeof ctx ); - ctx.exact = 1; /* use the key ID exactly as given */ - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (1); - ctx.nitems = 1; - ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; - ctx.items[0].u.kid[0] = keyid[0]; - ctx.items[0].u.kid[1] = keyid[1]; - ctx.req_algo = sk->req_algo; - ctx.req_usage = sk->req_usage; - rc = lookup( &ctx, &kb, 1 ); - if ( !rc ) { - sk_from_block ( &ctx, sk, kb ); - } - get_seckey_end( &ctx ); - release_kbnode ( kb ); - - if( !rc ) { - /* check the secret key (this may prompt for a passprase to - * unlock the secret key - */ - rc = check_secret_key( sk, 0 ); - } - - return rc; -} - - -/**************** - * Check whether the secret key is available. This is just a fast - * check and does not tell us whether the secret key is valid. It - * merely tells other whether there is some secret key. - * Returns: 0 := key is available - * GPG_ERR_NO_SECKEY := not availabe - */ -int -seckey_available( u32 *keyid ) -{ - int rc; - KEYDB_HANDLE hd = keydb_new (1); - - rc = keydb_search_kid (hd, keyid); - if ( rc == -1 ) - rc = GPG_ERR_NO_SECKEY; - keydb_release (hd); - return rc; -} - - -/**************** - * Return the type of the user id: - * - * Please use the constants KEYDB_SERCH_MODE_xxx - * 0 = Invalid user ID - * 1 = exact match - * 2 = match a substring - * 3 = match an email address - * 4 = match a substring of an email address - * 5 = match an email address, but compare from end - * 6 = word match mode - * 10 = it is a short KEYID (don't care about keyid[0]) - * 11 = it is a long KEYID - * 12 = it is a trustdb index (keyid is looked up) - * 16 = it is a 16 byte fingerprint - * 20 = it is a 20 byte fingerprint - * 21 = Unified fingerprint :fpr:pk_algo: - * (We don't use pk_algo yet) - * - * Rules used: - * - If the username starts with 8,9,16 or 17 hex-digits (the first one - * must be in the range 0..9), this is considered a keyid; depending - * on the length a short or complete one. - * - If the username starts with 32,33,40 or 41 hex-digits (the first one - * must be in the range 0..9), this is considered a fingerprint. - * - If the username starts with a left angle, we assume it is a complete - * email address and look only at this part. - * - If the username starts with a colon we assume it is a unified - * key specfification. - * - If the username starts with a '.', we assume it is the ending - * part of an email address - * - If the username starts with an '@', we assume it is a part of an - * email address - * - If the userid start with an '=' an exact compare is done. - * - If the userid starts with a '*' a case insensitive substring search is - * done (This is the default). - * - If the userid starts with a '+' we will compare individual words - * and a match requires that all the words are in the userid. - * Words are delimited by white space or "()<>[]{}.@-+_,;/&!" - * (note that you can't search for these characters). Compare - * is not case sensitive. - */ - -int -classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc ) -{ - const char *s; - int hexprefix = 0; - int hexlength; - int mode = 0; - KEYDB_SEARCH_DESC dummy_desc; - - if (!desc) - desc = &dummy_desc; - - /* clear the structure so that the mode field is set to zero unless - * we set it to the correct value right at the end of this function */ - memset (desc, 0, sizeof *desc); - - /* skip leading spaces. Fixme: what is with trailing spaces? */ - for(s = name; *s && spacep (s); s++ ) - ; - - switch (*s) { - case 0: /* empty string is an error */ - return 0; - - case '.': /* an email address, compare from end */ - mode = KEYDB_SEARCH_MODE_MAILEND; - s++; - desc->u.name = s; - break; - - case '<': /* an email address */ - mode = KEYDB_SEARCH_MODE_MAIL; - desc->u.name = s; - break; - - case '@': /* part of an email address */ - mode = KEYDB_SEARCH_MODE_MAILSUB; - s++; - desc->u.name = s; - break; - - case '=': /* exact compare */ - mode = KEYDB_SEARCH_MODE_EXACT; - s++; - desc->u.name = s; - break; - - case '*': /* case insensitive substring search */ - mode = KEYDB_SEARCH_MODE_SUBSTR; - s++; - desc->u.name = s; - break; - - case '+': /* compare individual words */ - mode = KEYDB_SEARCH_MODE_WORDS; - s++; - desc->u.name = s; - break; - - case '#': /* local user id */ - return 0; /* This is now obsolete and van't not be used anymore*/ - - case ':': /*Unified fingerprint */ - { - const char *se, *si; - int i; - - se = strchr( ++s,':'); - if ( !se ) - return 0; - for (i=0,si=s; si < se; si++, i++ ) { - if ( !strchr("01234567890abcdefABCDEF", *si ) ) - return 0; /* invalid digit */ - } - if (i != 32 && i != 40) - return 0; /* invalid length of fpr*/ - for (i=0,si=s; si < se; i++, si +=2) - desc->u.fpr[i] = hextobyte(si); - for ( ; i < 20; i++) - desc->u.fpr[i]= 0; - s = se + 1; - mode = KEYDB_SEARCH_MODE_FPR; - } - break; - - default: - if (s[0] == '0' && s[1] == 'x') { - hexprefix = 1; - s += 2; - } - - hexlength = strspn(s, "0123456789abcdefABCDEF"); - if (hexlength >= 8 && s[hexlength] =='!') { - desc->exact = 1; - hexlength++; /* just for the following check */ - } - - /* check if a hexadecimal number is terminated by EOS or blank */ - if (hexlength && s[hexlength] && !spacep (s+hexlength)) { - if (hexprefix) /* a "0x" prefix without correct */ - return 0; /* termination is an error */ - else /* The first chars looked like */ - hexlength = 0; /* a hex number, but really were not. */ - } - - if (desc->exact) - hexlength--; - - if (hexlength == 8 - || (!hexprefix && hexlength == 9 && *s == '0')){ - /* short keyid */ - if (hexlength == 9) - s++; - desc->u.kid[0] = 0; - desc->u.kid[1] = strtoul( s, NULL, 16 ); - mode = KEYDB_SEARCH_MODE_SHORT_KID; - } - else if (hexlength == 16 - || (!hexprefix && hexlength == 17 && *s == '0')) { - /* complete keyid */ - char buf[9]; - if (hexlength == 17) - s++; - mem2str(buf, s, 9 ); - desc->u.kid[0] = strtoul( buf, NULL, 16 ); - desc->u.kid[1] = strtoul( s+8, NULL, 16 ); - mode = KEYDB_SEARCH_MODE_LONG_KID; - } - else if (hexlength == 32 || (!hexprefix && hexlength == 33 - && *s == '0')) { - /* md5 fingerprint */ - int i; - if (hexlength == 33) - s++; - memset(desc->u.fpr+16, 0, 4); - for (i=0; i < 16; i++, s+=2) { - int c = hextobyte(s); - if (c == -1) - return 0; - desc->u.fpr[i] = c; - } - mode = KEYDB_SEARCH_MODE_FPR16; - } - else if (hexlength == 40 || (!hexprefix && hexlength == 41 - && *s == '0')) { - /* sha1/rmd160 fingerprint */ - int i; - if (hexlength == 41) - s++; - for (i=0; i < 20; i++, s+=2) { - int c = hextobyte(s); - if (c == -1) - return 0; - desc->u.fpr[i] = c; - } - mode = KEYDB_SEARCH_MODE_FPR20; - } - else { - if (hexprefix) /* This was a hex number with a prefix */ - return 0; /* and a wrong length */ - - desc->exact = 0; - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_SUBSTR; /* default mode */ - } - } - - desc->mode = mode; - return mode; -} - - -static int -skip_disabled(void *dummy,u32 *keyid) -{ - int rc,disabled=0; - PKT_public_key *pk=xcalloc (1,sizeof(PKT_public_key)); - - rc = get_pubkey(pk, keyid); - if(rc) - { - log_error("error checking disabled status of %08lX: %s\n", - (ulong)keyid[1],gpg_strerror (rc)); - goto leave; - } - - disabled=pk_is_disabled(pk); - - leave: - free_public_key(pk); - return disabled; -} - -/**************** - * Try to get the pubkey by the userid. This function looks for the - * first pubkey certificate which has the given name in a user_id. - * if pk/sk has the pubkey algo set, the function will only return - * a pubkey with that algo. - * The caller should provide storage for either the pk or the sk. - * If ret_kb is not NULL the function will return the keyblock there. - */ - -static int -key_byname( GETKEY_CTX *retctx, STRLIST namelist, - PKT_public_key *pk, PKT_secret_key *sk, - int secmode, int include_disabled, - KBNODE *ret_kb, KEYDB_HANDLE *ret_kdbhd ) -{ - int rc = 0; - int n; - STRLIST r; - GETKEY_CTX ctx; - KBNODE help_kb = NULL; - - if( retctx ) {/* reset the returned context in case of error */ - assert (!ret_kdbhd); /* not allowed because the handle is - stored in the context */ - *retctx = NULL; - } - if (ret_kdbhd) - *ret_kdbhd = NULL; - - /* build the search context */ - for(n=0, r=namelist; r; r = r->next ) - n++; - ctx = xcalloc (1,sizeof *ctx + (n-1)*sizeof ctx->items ); - ctx->nitems = n; - - for(n=0, r=namelist; r; r = r->next, n++ ) { - classify_user_id (r->d, &ctx->items[n]); - - if (ctx->items[n].exact) - ctx->exact = 1; - if (!ctx->items[n].mode) { - xfree (ctx); - return GPG_ERR_INV_USER_ID; - } - if(!include_disabled - && ctx->items[n].mode!=KEYDB_SEARCH_MODE_SHORT_KID - && ctx->items[n].mode!=KEYDB_SEARCH_MODE_LONG_KID - && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR16 - && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR20 - && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR) - ctx->items[n].skipfnc=skip_disabled; - } - - ctx->kr_handle = keydb_new (secmode); - if ( !ret_kb ) - ret_kb = &help_kb; - - if( secmode ) { - if (sk) { - ctx->req_algo = sk->req_algo; - ctx->req_usage = sk->req_usage; - } - rc = lookup( ctx, ret_kb, 1 ); - if ( !rc && sk ) { - sk_from_block ( ctx, sk, *ret_kb ); - } - } - else { - if (pk) { - ctx->req_algo = pk->req_algo; - ctx->req_usage = pk->req_usage; - } - rc = lookup( ctx, ret_kb, 0 ); - if ( !rc && pk ) { - pk_from_block ( ctx, pk, *ret_kb ); - } - } - - release_kbnode ( help_kb ); - - if (retctx) /* caller wants the context */ - *retctx = ctx; - else { - if (ret_kdbhd) { - *ret_kdbhd = ctx->kr_handle; - ctx->kr_handle = NULL; - } - get_pubkey_end (ctx); - } - - return rc; -} - -/* - * Find a public key from NAME and returh the keyblock or the key. - * If ret_kdb is not NULL, the KEYDB handle used to locate this keyblock is - * returned and the caller is responsible for closing it. - */ -int -get_pubkey_byname (PKT_public_key *pk, - const char *name, KBNODE *ret_keyblock, - KEYDB_HANDLE *ret_kdbhd, int include_disabled ) -{ - int rc; - STRLIST namelist = NULL; - - add_to_strlist( &namelist, name ); - rc = key_byname( NULL, namelist, pk, NULL, 0, - include_disabled, ret_keyblock, ret_kdbhd); - free_strlist( namelist ); - return rc; -} - -int -get_pubkey_bynames( GETKEY_CTX *retctx, PKT_public_key *pk, - STRLIST names, KBNODE *ret_keyblock ) -{ - return key_byname( retctx, names, pk, NULL, 0, 1, ret_keyblock, NULL); -} - -int -get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock ) -{ - int rc; - - rc = lookup( ctx, ret_keyblock, 0 ); - if ( !rc && pk && ret_keyblock ) - pk_from_block ( ctx, pk, *ret_keyblock ); - - return rc; -} - - -void -get_pubkey_end( GETKEY_CTX ctx ) -{ - if( ctx ) { - memset (&ctx->kbpos, 0, sizeof ctx->kbpos); - keydb_release (ctx->kr_handle); - if( !ctx->not_allocated ) - xfree ( ctx ); - } -} - - - - -/**************** - * Search for a key with the given fingerprint. - * FIXME: - * We should replace this with the _byname function. This can be done - * by creating a userID conforming to the unified fingerprint style. - */ -int -get_pubkey_byfprint( PKT_public_key *pk, - const byte *fprint, size_t fprint_len) -{ - int rc; - - if( fprint_len == 20 || fprint_len == 16 ) { - struct getkey_ctx_s ctx; - KBNODE kb = NULL; - - memset( &ctx, 0, sizeof ctx ); - ctx.exact = 1 ; - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (0); - ctx.nitems = 1; - ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16 - : KEYDB_SEARCH_MODE_FPR20; - memcpy( ctx.items[0].u.fpr, fprint, fprint_len ); - rc = lookup( &ctx, &kb, 0 ); - if (!rc && pk ) - pk_from_block ( &ctx, pk, kb ); - release_kbnode ( kb ); - get_pubkey_end( &ctx ); - } - else - rc = GPG_ERR_GENERAL; /* Oops */ - return rc; -} - - -/* Get a public key and store it into the allocated pk. This function - differs from get_pubkey_byfprint() in that it does not do a check - of the key to avoid recursion. It should be used only in very - certain cases. PK may be NULL to check just for the existance of - the key. */ -int -get_pubkey_byfprint_fast (PKT_public_key *pk, - const byte *fprint, size_t fprint_len) -{ - int rc = 0; - KEYDB_HANDLE hd; - KBNODE keyblock; - byte fprbuf[MAX_FINGERPRINT_LEN]; - int i; - - for (i=0; i < MAX_FINGERPRINT_LEN && i < fprint_len; i++) - fprbuf[i] = fprint[i]; - while (i < MAX_FINGERPRINT_LEN) - fprbuf[i++] = 0; - - hd = keydb_new (0); - rc = keydb_search_fpr (hd, fprbuf); - if (rc == -1) - { - keydb_release (hd); - return GPG_ERR_NO_PUBKEY; - } - rc = keydb_get_keyblock (hd, &keyblock); - keydb_release (hd); - if (rc) - { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - return GPG_ERR_NO_PUBKEY; - } - - assert ( keyblock->pkt->pkttype == PKT_PUBLIC_KEY - || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY ); - if (pk) - copy_public_key (pk, keyblock->pkt->pkt.public_key ); - release_kbnode (keyblock); - - /* Not caching key here since it won't have all of the fields - properly set. */ - - return 0; -} - -/**************** - * Search for a key with the given fingerprint and return the - * complete keyblock which may have more than only this key. - */ -int -get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint, - size_t fprint_len ) -{ - int rc; - - if( fprint_len == 20 || fprint_len == 16 ) { - struct getkey_ctx_s ctx; - - memset( &ctx, 0, sizeof ctx ); - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (0); - ctx.nitems = 1; - ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16 - : KEYDB_SEARCH_MODE_FPR20; - memcpy( ctx.items[0].u.fpr, fprint, fprint_len ); - rc = lookup( &ctx, ret_keyblock, 0 ); - get_pubkey_end( &ctx ); - } - else - rc = GPG_ERR_GENERAL; /* Oops */ - - return rc; -} - - -/**************** - * Get a secret key by name and store it into sk - * If NAME is NULL use the default key - */ -static int -get_seckey_byname2( GETKEY_CTX *retctx, - PKT_secret_key *sk, const char *name, int unprotect, - KBNODE *retblock ) -{ - STRLIST namelist = NULL; - int rc; - - if( !name && opt.def_secret_key && *opt.def_secret_key ) { - add_to_strlist( &namelist, opt.def_secret_key ); - rc = key_byname( retctx, namelist, NULL, sk, 1, 1, retblock, NULL ); - } - else if( !name ) { /* use the first one as default key */ - struct getkey_ctx_s ctx; - KBNODE kb = NULL; - - assert (!retctx ); /* do we need this at all */ - assert (!retblock); - memset( &ctx, 0, sizeof ctx ); - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (1); - ctx.nitems = 1; - ctx.items[0].mode = KEYDB_SEARCH_MODE_FIRST; - rc = lookup( &ctx, &kb, 1 ); - if (!rc && sk ) - sk_from_block ( &ctx, sk, kb ); - release_kbnode ( kb ); - get_seckey_end( &ctx ); - } - else { - add_to_strlist( &namelist, name ); - rc = key_byname( retctx, namelist, NULL, sk, 1, 1, retblock, NULL ); - } - - free_strlist( namelist ); - - if( !rc && unprotect ) - rc = check_secret_key( sk, 0 ); - - return rc; -} - -int -get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock ) -{ - return get_seckey_byname2 ( NULL, sk, name, unlock, NULL ); -} - - -int -get_seckey_bynames( GETKEY_CTX *retctx, PKT_secret_key *sk, - STRLIST names, KBNODE *ret_keyblock ) -{ - return key_byname( retctx, names, NULL, sk, 1, 1, ret_keyblock, NULL ); -} - - -int -get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock ) -{ - int rc; - - rc = lookup( ctx, ret_keyblock, 1 ); - if ( !rc && sk && ret_keyblock ) - sk_from_block ( ctx, sk, *ret_keyblock ); - - return rc; -} - - -void -get_seckey_end( GETKEY_CTX ctx ) -{ - get_pubkey_end( ctx ); -} - - -/**************** - * Search for a key with the given fingerprint. - * FIXME: - * We should replace this with the _byname function. Thiscsan be done - * by creating a userID conforming to the unified fingerprint style. - */ -int -get_seckey_byfprint( PKT_secret_key *sk, - const byte *fprint, size_t fprint_len) -{ - int rc; - - if( fprint_len == 20 || fprint_len == 16 ) { - struct getkey_ctx_s ctx; - KBNODE kb = NULL; - - memset( &ctx, 0, sizeof ctx ); - ctx.exact = 1 ; - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (1); - ctx.nitems = 1; - ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16 - : KEYDB_SEARCH_MODE_FPR20; - memcpy( ctx.items[0].u.fpr, fprint, fprint_len ); - rc = lookup( &ctx, &kb, 1 ); - if (!rc && sk ) - sk_from_block ( &ctx, sk, kb ); - release_kbnode ( kb ); - get_pubkey_end( &ctx ); - } - else - rc = GPG_ERR_GENERAL; /* Oops */ - return rc; -} - - -/************************************************ - ************* Merging stuff ******************** - ************************************************/ - -/**************** - * merge all selfsignatures with the keys. - * FIXME: replace this at least for the public key parts - * by merge_selfsigs. - * It is still used in keyedit.c and - * at 2 or 3 other places - check whether it is really needed. - * It might be needed by the key edit and import stuff because - * the keylock is changed. - */ -void -merge_keys_and_selfsig( KBNODE keyblock ) -{ - PKT_public_key *pk = NULL; - PKT_secret_key *sk = NULL; - PKT_signature *sig; - KBNODE k; - u32 kid[2] = { 0, 0 }; - u32 sigdate = 0; - - if (keyblock && keyblock->pkt->pkttype == PKT_PUBLIC_KEY ) { - /* divert to our new function */ - merge_selfsigs (keyblock); - return; - } - /* still need the old one because the new one can't handle secret keys */ - - for(k=keyblock; k; k = k->next ) { - if( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - pk = k->pkt->pkt.public_key; sk = NULL; - if( pk->version < 4 ) - pk = NULL; /* not needed for old keys */ - else if( k->pkt->pkttype == PKT_PUBLIC_KEY ) - keyid_from_pk( pk, kid ); - else if( !pk->expiredate ) { /* and subkey */ - /* insert the expiration date here */ - /*FIXME!!! pk->expiredate = subkeys_expiretime( k, kid );*/ - } - sigdate = 0; - } - else if( k->pkt->pkttype == PKT_SECRET_KEY - || k->pkt->pkttype == PKT_SECRET_SUBKEY ) { - pk = NULL; sk = k->pkt->pkt.secret_key; - if( sk->version < 4 ) - sk = NULL; - else if( k->pkt->pkttype == PKT_SECRET_KEY ) - keyid_from_sk( sk, kid ); - sigdate = 0; - } - else if( (pk || sk ) && k->pkt->pkttype == PKT_SIGNATURE - && (sig=k->pkt->pkt.signature)->sig_class >= 0x10 - && sig->sig_class <= 0x30 && sig->version > 3 - && !(sig->sig_class == 0x18 || sig->sig_class == 0x28) - && sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1] ) { - /* okay this is a self-signature which can be used. - * This is not used for subkey binding signature, becuase this - * is done above. - * FIXME: We should only use this if the signature is valid - * but this is time consuming - we must provide another - * way to handle this - */ - const byte *p; - u32 ed; - - p = parse_sig_subpkt( sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL ); - if( pk ) { - ed = p? pk->timestamp + buffer_to_u32(p):0; - if( sig->timestamp > sigdate ) { - pk->expiredate = ed; - sigdate = sig->timestamp; - } - } - else { - ed = p? sk->timestamp + buffer_to_u32(p):0; - if( sig->timestamp > sigdate ) { - sk->expiredate = ed; - sigdate = sig->timestamp; - } - } - } - - if(pk && (pk->expiredate==0 || - (pk->max_expiredate && pk->expiredate>pk->max_expiredate))) - pk->expiredate=pk->max_expiredate; - - if(sk && (sk->expiredate==0 || - (sk->max_expiredate && sk->expiredate>sk->max_expiredate))) - sk->expiredate=sk->max_expiredate; - } -} - -/* - * Apply information from SIGNODE (which is the valid self-signature - * associated with that UID) to the UIDNODE: - * - wether the UID has been revoked - * - assumed creation date of the UID - * - temporary store the keyflags here - * - temporary store the key expiration time here - * - mark whether the primary user ID flag hat been set. - * - store the preferences - */ -static void -fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated ) -{ - PKT_user_id *uid = uidnode->pkt->pkt.user_id; - PKT_signature *sig = signode->pkt->pkt.signature; - const byte *p, *sym, *hash, *zip; - size_t n, nsym, nhash, nzip; - - uid->created = 0; /* not created == invalid */ - if ( IS_UID_REV ( sig ) ) { - uid->is_revoked = 1; - return; /* has been revoked */ - } - - uid->created = sig->timestamp; /* this one is okay */ - uid->selfsigversion = sig->version; - /* If we got this far, it's not expired :) */ - uid->is_expired = 0; - uid->expiredate = sig->expiredate; - - /* store the key flags in the helper variable for later processing */ - uid->help_key_usage = 0; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n ); - if ( p && n ) { - /* first octet of the keyflags */ - if ( (*p & 0x03) ) - uid->help_key_usage |= PUBKEY_USAGE_SIG; - if ( (*p & 0x0c) ) - uid->help_key_usage |= PUBKEY_USAGE_ENC; - /* Note: we do not set the CERT flag here because it can be assumed - * that thre is no real policy to set it. */ - if ( (*p & 0x20) ) - uid->help_key_usage |= PUBKEY_USAGE_AUTH; - } - - /* ditto or the key expiration */ - uid->help_key_expire = 0; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); - if ( p ) { - uid->help_key_expire = keycreated + buffer_to_u32(p); - } - - /* Set the primary user ID flag - we will later wipe out some - * of them to only have one in our keyblock */ - uid->is_primary = 0; - p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL ); - if ( p && *p ) - uid->is_primary = 2; - /* We could also query this from the unhashed area if it is not in - * the hased area and then later try to decide which is the better - * there should be no security problem with this. - * For now we only look at the hashed one. - */ - - /* Now build the preferences list. These must come from the - hashed section so nobody can modify the ciphers a key is - willing to accept. */ - p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PREF_SYM, &n ); - sym = p; nsym = p?n:0; - p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PREF_HASH, &n ); - hash = p; nhash = p?n:0; - p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PREF_COMPR, &n ); - zip = p; nzip = p?n:0; - if (uid->prefs) - xfree (uid->prefs); - n = nsym + nhash + nzip; - if (!n) - uid->prefs = NULL; - else { - uid->prefs = xmalloc (sizeof (*uid->prefs) * (n+1)); - n = 0; - for (; nsym; nsym--, n++) { - uid->prefs[n].type = PREFTYPE_SYM; - uid->prefs[n].value = *sym++; - } - for (; nhash; nhash--, n++) { - uid->prefs[n].type = PREFTYPE_HASH; - uid->prefs[n].value = *hash++; - } - for (; nzip; nzip--, n++) { - uid->prefs[n].type = PREFTYPE_ZIP; - uid->prefs[n].value = *zip++; - } - uid->prefs[n].type = PREFTYPE_NONE; /* end of list marker */ - uid->prefs[n].value = 0; - } - - /* see whether we have the MDC feature */ - uid->mdc_feature = 0; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n); - if (p && n && (p[0] & 0x01)) - uid->mdc_feature = 1; - - /* and the keyserver modify flag */ - uid->ks_modify = 1; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS, &n); - if (p && n && (p[0] & 0x80)) - uid->ks_modify = 0; -} - -static void -merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) -{ - PKT_public_key *pk = NULL; - KBNODE k; - u32 kid[2]; - u32 sigdate, uiddate, uiddate2; - KBNODE signode, uidnode, uidnode2; - u32 curtime = make_timestamp (); - unsigned int key_usage = 0; - u32 keytimestamp = 0; - u32 key_expire = 0; - int key_expire_seen = 0; - byte sigversion = 0; - - *r_revoked = 0; - if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY ) - BUG (); - pk = keyblock->pkt->pkt.public_key; - keytimestamp = pk->timestamp; - - keyid_from_pk( pk, kid ); - pk->main_keyid[0] = kid[0]; - pk->main_keyid[1] = kid[1]; - - if ( pk->version < 4 ) { - /* before v4 the key packet itself contains the expiration - * date and there was no way to change it, so we start with - * the one from the key packet */ - key_expire = pk->max_expiredate; - key_expire_seen = 1; - } - - /* first pass: find the latest direct key self-signature. - * We assume that the newest one overrides all others - */ - - /* In case this key was already merged */ - xfree (pk->revkey); - pk->revkey=NULL; - pk->numrevkeys=0; - - signode = NULL; - sigdate = 0; /* helper to find the latest signature */ - for(k=keyblock; k && k->pkt->pkttype != PKT_USER_ID; k = k->next ) { - if ( k->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = k->pkt->pkt.signature; - if ( sig->keyid[0] == kid[0] && sig->keyid[1]==kid[1] ) { - if ( check_key_signature( keyblock, k, NULL ) ) - ; /* signature did not verify */ - else if ( IS_KEY_REV (sig) ){ - /* key has been revoked - there is no way to override - * such a revocation, so we theoretically can stop now. - * We should not cope with expiration times for revocations - * here because we have to assume that an attacker can - * generate all kinds of signatures. However due to the - * fact that the key has been revoked it does not harm - * either and by continuing we gather some more info on - * that key. - */ - *r_revoked = 1; - } - else if ( IS_KEY_SIG (sig) ) { - /* Add any revocation keys onto the pk. This is - particularly interesting since we normally only - get data from the most recent 1F signature, but - you need multiple 1F sigs to properly handle - revocation keys (PGP does it this way, and a - revocation key could be sensitive and hence in a - different signature). */ - if(sig->revkey) { - int i; - - pk->revkey= - xrealloc(pk->revkey,sizeof(struct revocation_key)* - (pk->numrevkeys+sig->numrevkeys)); - - for(i=0;i<sig->numrevkeys;i++) - memcpy(&pk->revkey[pk->numrevkeys++], - sig->revkey[i], - sizeof(struct revocation_key)); - } - - if( sig->timestamp >= sigdate ) { - if(sig->flags.expired) - ; /* signature has expired - ignore it */ - else { - sigdate = sig->timestamp; - signode = k; - if( sig->version > sigversion ) - sigversion = sig->version; - - } - } - } - } - } - } - - /* Remove dupes from the revocation keys */ - - if(pk->revkey) - { - int i,j,x,changed=0; - - for(i=0;i<pk->numrevkeys;i++) - { - for(j=i+1;j<pk->numrevkeys;j++) - { - if(memcmp(&pk->revkey[i],&pk->revkey[j], - sizeof(struct revocation_key))==0) - { - /* remove j */ - - for(x=j;x<pk->numrevkeys-1;x++) - pk->revkey[x]=pk->revkey[x+1]; - - pk->numrevkeys--; - j--; - changed=1; - } - } - } - - if(changed) - pk->revkey=xrealloc(pk->revkey, - pk->numrevkeys*sizeof(struct revocation_key)); - } - - if ( signode ) { - /* some information from a direct key signature take precedence - * over the same information given in UID sigs. - */ - PKT_signature *sig = signode->pkt->pkt.signature; - const byte *p; - size_t n; - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n ); - if ( p && n ) { - /* first octet of the keyflags */ - if ( (*p & 0x03) ) - key_usage |= PUBKEY_USAGE_SIG; - if ( (*p & 0x0c) ) - key_usage |= PUBKEY_USAGE_ENC; - if ( (*p & 0x20) ) - key_usage |= PUBKEY_USAGE_AUTH; - } - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); - if ( p ) { - key_expire = keytimestamp + buffer_to_u32(p); - key_expire_seen = 1; - } - - /* mark that key as valid: one direct key signature should - * render a key as valid */ - pk->is_valid = 1; - } - - /* pass 1.5: look for key revocation signatures that were not made - by the key (i.e. did a revocation key issue a revocation for - us?). Only bother to do this if there is a revocation key in - the first place. */ - - if(pk->revkey) - for(k=keyblock; k && k->pkt->pkttype != PKT_USER_ID; k = k->next ) - { - if ( k->pkt->pkttype == PKT_SIGNATURE ) - { - PKT_signature *sig = k->pkt->pkt.signature; - - if(IS_KEY_REV(sig) && - (sig->keyid[0]!=kid[0] || sig->keyid[1]!=kid[1])) - { - /* Failure here means the sig did not verify, is was - not issued by a revocation key, or a revocation - key loop was broken. */ - - if(check_revocation_keys(pk,sig)==0) - *r_revoked=1; - - /* In the future handle subkey and cert revocations? - PGP doesn't, but it's in 2440. */ - } - } - } - - /* second pass: look at the self-signature of all user IDs */ - signode = uidnode = NULL; - sigdate = 0; /* helper to find the latest signature in one user ID */ - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID ) { - if ( uidnode && signode ) - { - fixup_uidnode ( uidnode, signode, keytimestamp ); - pk->is_valid=1; - } - uidnode = k; - signode = NULL; - sigdate = 0; - } - else if ( k->pkt->pkttype == PKT_SIGNATURE && uidnode ) { - PKT_signature *sig = k->pkt->pkt.signature; - if ( sig->keyid[0] == kid[0] && sig->keyid[1]==kid[1] ) { - if ( check_key_signature( keyblock, k, NULL ) ) - ; /* signature did not verify */ - else if ( (IS_UID_SIG (sig) || IS_UID_REV (sig)) - && sig->timestamp >= sigdate ) { - /* Note: we allow to invalidate cert revocations - * by a newer signature. An attacker can't use this - * because a key should be revoced with a key revocation. - * The reason why we have to allow for that is that at - * one time an email address may become invalid but later - * the same email address may become valid again (hired, - * fired, hired again). - */ - if(sig->flags.expired) { - /* Expired uids don't get to be primary unless - they are the only uid there is. */ - uidnode->pkt->pkt.user_id->is_primary=0; - uidnode->pkt->pkt.user_id->is_expired=1; - uidnode->pkt->pkt.user_id->expiredate=sig->expiredate; - } - else { - sigdate = sig->timestamp; - signode = k; - if( sig->version > sigversion ) - sigversion = sig->version; - } - } - } - } - } - if ( uidnode && signode ) { - fixup_uidnode ( uidnode, signode, keytimestamp ); - pk->is_valid = 1; - } - - /* If the key isn't valid yet, and we have - --allow-non-selfsigned-uid set, then force it valid. */ - if(!pk->is_valid && opt.allow_non_selfsigned_uid) - { - if(opt.verbose) - log_info(_("Invalid key %08lX made valid by " - "--allow-non-selfsigned-uid\n"), - (ulong)keyid_from_pk(pk,NULL)); - - pk->is_valid = 1; - } - - /* The key STILL isn't valid, so try and find an ultimately - trusted signature. */ - if(!pk->is_valid) - { - uidnode=NULL; - - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k=k->next) - { - if ( k->pkt->pkttype == PKT_USER_ID ) - uidnode = k; - else if ( k->pkt->pkttype == PKT_SIGNATURE && uidnode ) - { - PKT_signature *sig = k->pkt->pkt.signature; - - if(sig->keyid[0] != kid[0] || sig->keyid[1]!=kid[1]) - { - PKT_public_key *ultimate_pk; - - ultimate_pk=xcalloc (1,sizeof(*ultimate_pk)); - - /* We don't want to use the full get_pubkey to - avoid infinite recursion in certain cases. - There is no reason to check that an ultimately - trusted key is still valid - if it has been - revoked or the user should also renmove the - ultimate trust flag. */ - if(get_pubkey_fast(ultimate_pk,sig->keyid)==0 - && check_key_signature2(keyblock,k,ultimate_pk, - NULL, NULL, NULL, NULL)==0 - && get_ownertrust(ultimate_pk)==TRUST_ULTIMATE) - { - free_public_key(ultimate_pk); - pk->is_valid=1; - break; - } - - free_public_key(ultimate_pk); - } - } - } - } - - /* Record the highest selfsig version so we know if this is a v3 - key through and through, or a v3 key with a v4 selfsig - somewhere. This is useful in a few places to know if the key - must be treated as PGP2-style or OpenPGP-style. Note that a - selfsig revocation with a higher version number will also raise - this value. This is okay since such a revocation must be - issued by the user (i.e. it cannot be issued by someone else to - modify the key behavior.) */ - - pk->selfsigversion=sigversion; - - /* Now that we had a look at all user IDs we can now get some information - * from those user IDs. - */ - - if ( !key_usage ) { - /* find the latest user ID with key flags set */ - uiddate = 0; /* helper to find the latest user ID */ - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; - k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = k->pkt->pkt.user_id; - if ( uid->help_key_usage && uid->created > uiddate ) { - key_usage = uid->help_key_usage; - uiddate = uid->created; - } - } - } - } - if ( !key_usage ) { /* no key flags at all: get it from the algo */ - key_usage = openpgp_pk_algo_usage ( pk->pubkey_algo ); - } - else { /* check that the usage matches the usage as given by the algo */ - int x = openpgp_pk_algo_usage ( pk->pubkey_algo ); - if ( x ) /* mask it down to the actual allowed usage */ - key_usage &= x; - } - pk->pubkey_usage = key_usage; - - if ( !key_expire_seen ) { - /* find the latest valid user ID with a key expiration set - * Note, that this may be a different one from the above because - * some user IDs may have no expiration date set */ - uiddate = 0; - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; - k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = k->pkt->pkt.user_id; - if ( uid->help_key_expire && uid->created > uiddate ) { - key_expire = uid->help_key_expire; - uiddate = uid->created; - } - } - } - } - - /* Currently only v3 keys have a maximum expiration date, but I'll - bet v5 keys get this feature again. */ - if(key_expire==0 || (pk->max_expiredate && key_expire>pk->max_expiredate)) - key_expire=pk->max_expiredate; - - pk->has_expired = key_expire >= curtime? 0 : key_expire; - pk->expiredate = key_expire; - - /* Fixme: we should see how to get rid of the expiretime fields but - * this needs changes at other places too. */ - - /* and now find the real primary user ID and delete all others */ - uiddate = uiddate2 = 0; - uidnode = uidnode2 = NULL; - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID && - !k->pkt->pkt.user_id->attrib_data) { - PKT_user_id *uid = k->pkt->pkt.user_id; - if (uid->is_primary) - { - if(uid->created > uiddate) - { - uiddate = uid->created; - uidnode = k; - } - else if(uid->created==uiddate && uidnode) - { - /* The dates are equal, so we need to do a - different (and arbitrary) comparison. This - should rarely, if ever, happen. It's good to - try and guarantee that two different GnuPG - users with two different keyrings at least pick - the same primary. */ - if(cmp_user_ids(uid,uidnode->pkt->pkt.user_id)>0) - uidnode=k; - } - } - else - { - if(uid->created > uiddate2) - { - uiddate2 = uid->created; - uidnode2 = k; - } - else if(uid->created==uiddate2 && uidnode2) - { - if(cmp_user_ids(uid,uidnode2->pkt->pkt.user_id)>0) - uidnode2=k; - } - } - } - } - if ( uidnode ) { - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; - k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID && - !k->pkt->pkt.user_id->attrib_data) { - PKT_user_id *uid = k->pkt->pkt.user_id; - if ( k != uidnode ) - uid->is_primary = 0; - } - } - } - else if( uidnode2 ) { - /* none is flagged primary - use the latest user ID we have, - and disambiguate with the arbitrary packet comparison. */ - uidnode2->pkt->pkt.user_id->is_primary = 1; - } - else - { - /* None of our uids were self-signed, so pick the one that - sorts first to be the primary. This is the best we can do - here since there are no self sigs to date the uids. */ - - uidnode = NULL; - - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; - k = k->next ) - { - if(k->pkt->pkttype==PKT_USER_ID - && !k->pkt->pkt.user_id->attrib_data) - { - if(!uidnode) - { - uidnode=k; - uidnode->pkt->pkt.user_id->is_primary=1; - continue; - } - else - { - if(cmp_user_ids(k->pkt->pkt.user_id, - uidnode->pkt->pkt.user_id)>0) - { - uidnode->pkt->pkt.user_id->is_primary=0; - uidnode=k; - uidnode->pkt->pkt.user_id->is_primary=1; - } - else - k->pkt->pkt.user_id->is_primary=0; /* just to be - safe */ - } - } - } - } -} - - -static void -merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode ) -{ - PKT_public_key *mainpk = NULL, *subpk = NULL; - PKT_signature *sig; - KBNODE k; - u32 mainkid[2]; - u32 sigdate = 0; - KBNODE signode; - u32 curtime = make_timestamp (); - unsigned int key_usage = 0; - u32 keytimestamp = 0; - u32 key_expire = 0; - const byte *p; - size_t n; - - if ( subnode->pkt->pkttype != PKT_PUBLIC_SUBKEY ) - BUG (); - mainpk = keyblock->pkt->pkt.public_key; - if ( mainpk->version < 4 ) - return; /* (actually this should never happen) */ - keyid_from_pk( mainpk, mainkid ); - subpk = subnode->pkt->pkt.public_key; - keytimestamp = subpk->timestamp; - - subpk->is_valid = 0; - subpk->main_keyid[0] = mainpk->main_keyid[0]; - subpk->main_keyid[1] = mainpk->main_keyid[1]; - - /* find the latest key binding self-signature. */ - signode = NULL; - sigdate = 0; /* helper to find the latest signature */ - for(k=subnode->next; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; - k = k->next ) { - if ( k->pkt->pkttype == PKT_SIGNATURE ) { - sig = k->pkt->pkt.signature; - if ( sig->keyid[0] == mainkid[0] && sig->keyid[1]==mainkid[1] ) { - if ( check_key_signature( keyblock, k, NULL ) ) - ; /* signature did not verify */ - else if ( IS_SUBKEY_REV (sig) ) { - /* Note that this means that the date on a - revocation sig does not matter - even if the - binding sig is dated after the revocation sig, - the subkey is still marked as revoked. This - seems ok, as it is just as easy to make new - subkeys rather than re-sign old ones as the - problem is in the distribution. Plus, PGP (7) - does this the same way. */ - subpk->is_revoked = 1; - /* although we could stop now, we continue to - * figure out other information like the old expiration - * time */ - } - else if ( IS_SUBKEY_SIG (sig) && sig->timestamp >= sigdate ) { - if(sig->flags.expired) - ; /* signature has expired - ignore it */ - else { - sigdate = sig->timestamp; - signode = k; - } - } - } - } - } - - if ( !signode ) { - return; /* no valid key binding */ - } - - subpk->is_valid = 1; - sig = signode->pkt->pkt.signature; - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n ); - if ( p && n ) { - /* first octet of the keyflags */ - if ( (*p & 0x03) ) - key_usage |= PUBKEY_USAGE_SIG; - if ( (*p & 0x0c) ) - key_usage |= PUBKEY_USAGE_ENC; - if ( (*p & 0x20) ) - key_usage |= PUBKEY_USAGE_AUTH; - } - if ( !key_usage ) { /* no key flags at all: get it from the algo */ - key_usage = openpgp_pk_algo_usage ( subpk->pubkey_algo ); - } - else { /* check that the usage matches the usage as given by the algo */ - int x = openpgp_pk_algo_usage ( subpk->pubkey_algo ); - if ( x ) /* mask it down to the actual allowed usage */ - key_usage &= x; - } - subpk->pubkey_usage = key_usage; - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); - if ( p ) - key_expire = keytimestamp + buffer_to_u32(p); - else - key_expire = 0; - subpk->has_expired = key_expire >= curtime? 0 : key_expire; - subpk->expiredate = key_expire; -} - - - -/* - * Merge information from the self-signatures with the key, so that - * we can later use them more easy. - * The function works by first applying the self signatures to the - * primary key and the to each subkey. - * Here are the rules we use to decide which inormation from which - * self-signature is used: - * We check all self signatures or validity and ignore all invalid signatures. - * All signatures are then ordered by their creation date .... - * For the primary key: - * FIXME the docs - */ -static void -merge_selfsigs( KBNODE keyblock ) -{ - KBNODE k; - int revoked; - PKT_public_key *main_pk; - prefitem_t *prefs; - int mdc_feature; - - if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY ) { - if (keyblock->pkt->pkttype == PKT_SECRET_KEY ) { - log_error ("expected public key but found secret key " - "- must stop\n"); - /* we better exit here becuase a public key is expected at - other places too. FIXME: Figure this out earlier and - don't get to here at all */ - g10_exit (1); - } - BUG (); - } - - merge_selfsigs_main ( keyblock, &revoked ); - - /* now merge in the data from each of the subkeys */ - for(k=keyblock; k; k = k->next ) { - if ( k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - merge_selfsigs_subkey ( keyblock, k ); - } - } - - main_pk = keyblock->pkt->pkt.public_key; - if ( revoked || main_pk->has_expired || !main_pk->is_valid ) { - /* if the primary key is revoked, expired, or invalid we - * better set the appropriate flags on that key and all - * subkeys */ - for(k=keyblock; k; k = k->next ) { - if ( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - PKT_public_key *pk = k->pkt->pkt.public_key; - if(!main_pk->is_valid) - pk->is_valid = 0; - if(revoked) - pk->is_revoked = 1; - if(main_pk->has_expired) - pk->has_expired = main_pk->has_expired; - } - } - return; - } - - /* set the preference list of all keys to those of the primary real - * user ID. Note: we use these preferences when we don't know by - * which user ID the key has been selected. - * fixme: we should keep atoms of commonly used preferences or - * use reference counting to optimize the preference lists storage. - * FIXME: it might be better to use the intersection of - * all preferences. - * Do a similar thing for the MDC feature flag. - */ - prefs = NULL; - mdc_feature = 0; - for (k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next) { - if (k->pkt->pkttype == PKT_USER_ID - && !k->pkt->pkt.user_id->attrib_data - && k->pkt->pkt.user_id->is_primary) { - prefs = k->pkt->pkt.user_id->prefs; - mdc_feature = k->pkt->pkt.user_id->mdc_feature; - break; - } - } - for(k=keyblock; k; k = k->next ) { - if ( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - PKT_public_key *pk = k->pkt->pkt.public_key; - if (pk->prefs) - xfree (pk->prefs); - pk->prefs = copy_prefs (prefs); - pk->mdc_feature = mdc_feature; - } - } -} - - -/* - * Merge the secret keys from secblock into the pubblock thereby - * replacing the public (sub)keys with their secret counterparts Hmmm: - * It might be better to get away from the concept of entire secret - * keys at all and have a way to store just the real secret parts - * from the key. - */ -static void -merge_public_with_secret ( KBNODE pubblock, KBNODE secblock ) -{ - KBNODE pub; - - assert ( pubblock->pkt->pkttype == PKT_PUBLIC_KEY ); - assert ( secblock->pkt->pkttype == PKT_SECRET_KEY ); - - for (pub=pubblock; pub; pub = pub->next ) { - if ( pub->pkt->pkttype == PKT_PUBLIC_KEY ) { - PKT_public_key *pk = pub->pkt->pkt.public_key; - PKT_secret_key *sk = secblock->pkt->pkt.secret_key; - assert ( pub == pubblock ); /* only in the first node */ - /* there is nothing to compare in this case, so just replace - * some information */ - copy_public_parts_to_secret_key ( pk, sk ); - free_public_key ( pk ); - pub->pkt->pkttype = PKT_SECRET_KEY; - pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk); - } - else if ( pub->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - KBNODE sec; - PKT_public_key *pk = pub->pkt->pkt.public_key; - - /* this is more complicated: it may happen that the sequence - * of the subkeys dosn't match, so we have to find the - * appropriate secret key */ - for (sec=secblock->next; sec; sec = sec->next ) { - if ( sec->pkt->pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *sk = sec->pkt->pkt.secret_key; - if ( !cmp_public_secret_key ( pk, sk ) ) { - copy_public_parts_to_secret_key ( pk, sk ); - free_public_key ( pk ); - pub->pkt->pkttype = PKT_SECRET_SUBKEY; - pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk); - break; - } - } - } - if ( !sec ) - BUG(); /* already checked in premerge */ - } - } -} - -/* This function checks that for every public subkey a corresponding - * secret subkey is available and deletes the public subkey otherwise. - * We need this function because we can't delete it later when we - * actually merge the secret parts into the pubring. - * The function also plays some games with the node flags. - */ -static void -premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock ) -{ - KBNODE last, pub; - - assert ( pubblock->pkt->pkttype == PKT_PUBLIC_KEY ); - assert ( secblock->pkt->pkttype == PKT_SECRET_KEY ); - - for (pub=pubblock,last=NULL; pub; last = pub, pub = pub->next ) { - pub->flag &= ~3; /* reset bits 0 and 1 */ - if ( pub->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - KBNODE sec; - PKT_public_key *pk = pub->pkt->pkt.public_key; - - for (sec=secblock->next; sec; sec = sec->next ) { - if ( sec->pkt->pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *sk = sec->pkt->pkt.secret_key; - if ( !cmp_public_secret_key ( pk, sk ) ) { - if ( sk->protect.s2k.mode == 1001 ) { - /* The secret parts are not available so - we can't use that key for signing etc. - Fix the pubkey usage */ - pk->pubkey_usage &= ~(PUBKEY_USAGE_SIG - |PUBKEY_USAGE_AUTH); - } - /* transfer flag bits 0 and 1 to the pubblock */ - pub->flag |= (sec->flag &3); - break; - } - } - } - if ( !sec ) { - KBNODE next, ll; - - if (opt.verbose) - log_info ( _("no secret subkey " - "for public subkey %08lX - ignoring\n"), - (ulong)keyid_from_pk (pk,NULL) ); - /* we have to remove the subkey in this case */ - assert ( last ); - /* find the next subkey */ - for (next=pub->next,ll=pub; - next && pub->pkt->pkttype != PKT_PUBLIC_SUBKEY; - ll = next, next = next->next ) - ; - /* make new link */ - last->next = next; - /* release this public subkey with all sigs */ - ll->next = NULL; - release_kbnode( pub ); - /* let the loop continue */ - pub = last; - } - } - } - /* We need to copy the found bits (0 and 1) from the secret key to - the public key. This has already been done for the subkeys but - got lost on the primary key - fix it here *. */ - pubblock->flag |= (secblock->flag & 3); -} - - - - -/* See see whether the key fits - * our requirements and in case we do not - * request the primary key, we should select - * a suitable subkey. - * FIXME: Check against PGP 7 whether we still need a kludge - * to favor type 16 keys over type 20 keys when type 20 - * has not been explitely requested. - * Returns: True when a suitable key has been found. - * - * We have to distinguish four cases: FIXME! - * 1. No usage and no primary key requested - * Examples for this case are that we have a keyID to be used - * for decrytion or verification. - * 2. No usage but primary key requested - * This is the case for all functions which work on an - * entire keyblock, e.g. for editing or listing - * 3. Usage and primary key requested - * FXME - * 4. Usage but no primary key requested - * FIXME - * FIXME: Tell what is going to happen here and something about the rationale - * Note: We don't use this function if no specific usage is requested; - * This way the getkey functions can be used for plain key listings. - * - * CTX ist the keyblock we are investigating, if FOUNDK is not NULL this - * is the key we actually found by looking at the keyid or a fingerprint and - * may eitehr point to the primary or one of the subkeys. - */ - -static int -finish_lookup (GETKEY_CTX ctx) -{ - KBNODE keyblock = ctx->keyblock; - KBNODE k; - KBNODE foundk = NULL; - PKT_user_id *foundu = NULL; -#define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC) - unsigned int req_usage = ( ctx->req_usage & USAGE_MASK ); - /* Request the primary if we're certifying another key, and also - if signing data while --pgp6 or --pgp7 is on since pgp 6 and 7 - do not understand signatures made by a signing subkey. PGP 8 - does. */ - int req_prim = (ctx->req_usage & PUBKEY_USAGE_CERT) || - ((PGP6 || PGP7) && (ctx->req_usage & PUBKEY_USAGE_SIG)); - u32 latest_date; - KBNODE latest_key; - u32 curtime = make_timestamp (); - - assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY ); - - ctx->found_key = NULL; - - if (ctx->exact) { - for (k=keyblock; k; k = k->next) { - if ( (k->flag & 1) ) { - assert ( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ); - foundk = k; - break; - } - } - } - - for (k=keyblock; k; k = k->next) { - if ( (k->flag & 2) ) { - assert (k->pkt->pkttype == PKT_USER_ID); - foundu = k->pkt->pkt.user_id; - break; - } - } - - if ( DBG_CACHE ) - log_debug( "finish_lookup: checking key %08lX (%s)(req_usage=%x)\n", - (ulong)keyid_from_pk( keyblock->pkt->pkt.public_key, NULL), - foundk? "one":"all", req_usage); - - if (!req_usage) { - latest_key = foundk? foundk:keyblock; - goto found; - } - - if (!req_usage) { - PKT_public_key *pk = foundk->pkt->pkt.public_key; - if (pk->user_id) - free_user_id (pk->user_id); - pk->user_id = scopy_user_id (foundu); - ctx->found_key = foundk; - cache_user_id( keyblock ); - return 1; /* found */ - } - - latest_date = 0; - latest_key = NULL; - /* do not look at subkeys if a certification key is requested */ - if ((!foundk || foundk->pkt->pkttype == PKT_PUBLIC_SUBKEY) && !req_prim) { - KBNODE nextk; - /* either start a loop or check just this one subkey */ - for (k=foundk?foundk:keyblock; k; k = nextk ) { - PKT_public_key *pk; - nextk = k->next; - if ( k->pkt->pkttype != PKT_PUBLIC_SUBKEY ) - continue; - if ( foundk ) - nextk = NULL; /* what a hack */ - pk = k->pkt->pkt.public_key; - if (DBG_CACHE) - log_debug( "\tchecking subkey %08lX\n", - (ulong)keyid_from_pk( pk, NULL)); - if ( !pk->is_valid ) { - if (DBG_CACHE) - log_debug( "\tsubkey not valid\n"); - continue; - } - if ( pk->is_revoked ) { - if (DBG_CACHE) - log_debug( "\tsubkey has been revoked\n"); - continue; - } - if ( pk->has_expired ) { - if (DBG_CACHE) - log_debug( "\tsubkey has expired\n"); - continue; - } - if ( pk->timestamp > curtime && !opt.ignore_valid_from ) { - if (DBG_CACHE) - log_debug( "\tsubkey not yet valid\n"); - continue; - } - - if ( !((pk->pubkey_usage&USAGE_MASK) & req_usage) ) { - if (DBG_CACHE) - log_debug( "\tusage does not match: want=%x have=%x\n", - req_usage, pk->pubkey_usage ); - continue; - } - - if (DBG_CACHE) - log_debug( "\tsubkey looks fine\n"); - if ( pk->timestamp > latest_date ) { - latest_date = pk->timestamp; - latest_key = k; - } - } - } - - /* Okay now try the primary key unless we want an exact - * key ID match on a subkey */ - if ((!latest_key && !(ctx->exact && foundk != keyblock)) || req_prim) { - PKT_public_key *pk; - if (DBG_CACHE && !foundk && !req_prim ) - log_debug( "\tno suitable subkeys found - trying primary\n"); - pk = keyblock->pkt->pkt.public_key; - if ( !pk->is_valid ) { - if (DBG_CACHE) - log_debug( "\tprimary key not valid\n"); - } - else if ( pk->is_revoked ) { - if (DBG_CACHE) - log_debug( "\tprimary key has been revoked\n"); - } - else if ( pk->has_expired ) { - if (DBG_CACHE) - log_debug( "\tprimary key has expired\n"); - } - else if ( !((pk->pubkey_usage&USAGE_MASK) & req_usage) ) { - if (DBG_CACHE) - log_debug( "\tprimary key usage does not match: " - "want=%x have=%x\n", - req_usage, pk->pubkey_usage ); - } - else { /* okay */ - if (DBG_CACHE) - log_debug( "\tprimary key may be used\n"); - latest_key = keyblock; - latest_date = pk->timestamp; - } - } - - if ( !latest_key ) { - if (DBG_CACHE) - log_debug("\tno suitable key found - giving up\n"); - return 0; - } - - found: - if (DBG_CACHE) - log_debug( "\tusing key %08lX\n", - (ulong)keyid_from_pk( latest_key->pkt->pkt.public_key, NULL) ); - - if (latest_key) { - PKT_public_key *pk = latest_key->pkt->pkt.public_key; - if (pk->user_id) - free_user_id (pk->user_id); - pk->user_id = scopy_user_id (foundu); - } - - ctx->found_key = latest_key; - - if (latest_key != keyblock && opt.verbose) { - log_info(_("using secondary key %08lX " - "instead of primary key %08lX\n"), - (ulong)keyid_from_pk( latest_key->pkt->pkt.public_key, NULL), - (ulong)keyid_from_pk( keyblock->pkt->pkt.public_key, NULL) ); - } - - cache_user_id( keyblock ); - - return 1; /* found */ -} - - -static int -lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode ) -{ - int rc; - KBNODE secblock = NULL; /* helper */ - int no_suitable_key = 0; - - rc = 0; - while (!(rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems))) { - /* If we are searching for the first key we have to make sure - that the next interation does not no an implicit reset. - This can be triggered by an empty key ring. */ - if (ctx->nitems && ctx->items->mode == KEYDB_SEARCH_MODE_FIRST) - ctx->items->mode = KEYDB_SEARCH_MODE_NEXT; - - rc = keydb_get_keyblock (ctx->kr_handle, &ctx->keyblock); - if (rc) { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - rc = 0; - goto skip; - } - - if ( secmode ) { - /* find the correspondig public key and use this - * this one for the selection process */ - u32 aki[2]; - KBNODE k = ctx->keyblock; - - if (k->pkt->pkttype != PKT_SECRET_KEY) - BUG(); - - keyid_from_sk (k->pkt->pkt.secret_key, aki); - k = get_pubkeyblock (aki); - if( !k ) { - if (!opt.quiet) - log_info(_("key %08lX: secret key without public key " - "- skipped\n"), (ulong)aki[1] ); - goto skip; - } - secblock = ctx->keyblock; - ctx->keyblock = k; - - premerge_public_with_secret ( ctx->keyblock, secblock ); - } - - /* warning: node flag bits 0 and 1 should be preserved by - * merge_selfsigs. For secret keys, premerge did tranfer the - * keys to the keyblock */ - merge_selfsigs ( ctx->keyblock ); - if ( finish_lookup (ctx) ) { - no_suitable_key = 0; - if ( secmode ) { - merge_public_with_secret ( ctx->keyblock, - secblock); - release_kbnode (secblock); - secblock = NULL; - } - goto found; - } - else - no_suitable_key = 1; - - skip: - /* release resources and continue search */ - if ( secmode ) { - release_kbnode( secblock ); - secblock = NULL; - } - release_kbnode( ctx->keyblock ); - ctx->keyblock = NULL; - } - - found: - if( rc && rc != -1 ) - log_error("keydb_search failed: %s\n", gpg_strerror (rc)); - - if( !rc ) { - *ret_keyblock = ctx->keyblock; /* return the keyblock */ - ctx->keyblock = NULL; - } - else if (rc == -1 && no_suitable_key) - rc = secmode ? GPG_ERR_UNUSABLE_SECKEY : GPG_ERR_UNUSABLE_PUBKEY; - else if( rc == -1 ) - rc = secmode ? GPG_ERR_NO_SECKEY : GPG_ERR_NO_PUBKEY; - - if ( secmode ) { - release_kbnode( secblock ); - secblock = NULL; - } - release_kbnode( ctx->keyblock ); - ctx->keyblock = NULL; - - ctx->last_rc = rc; - return rc; -} - - - - -/**************** - * FIXME: Replace by the generic function - * It does not work as it is right now - it is used at - * 2 places: a) to get the key for an anonyous recipient - * b) to get the ultimately trusted keys. - * The a) usage might have some problems. - * - * set with_subkeys true to include subkeys - * set with_spm true to include secret-parts-missing keys - * - * Enumerate all primary secret keys. Caller must use these procedure: - * 1) create a void pointer and initialize it to NULL - * 2) pass this void pointer by reference to this function - * and provide space for the secret key (pass a buffer for sk) - * 3) call this function as long as it does not return -1 - * to indicate EOF. - * 4) Always call this function a last time with SK set to NULL, - * so that can free it's context. - */ -int -enum_secret_keys( void **context, PKT_secret_key *sk, - int with_subkeys, int with_spm ) -{ - int rc=0; - struct { - int eof; - int first; - KEYDB_HANDLE hd; - KBNODE keyblock; - KBNODE node; - } *c = *context; - - - if( !c ) { /* make a new context */ - c = xcalloc (1, sizeof *c ); - *context = c; - c->hd = keydb_new (1); - c->first = 1; - c->keyblock = NULL; - c->node = NULL; - } - - if( !sk ) { /* free the context */ - keydb_release (c->hd); - release_kbnode (c->keyblock); - xfree ( c ); - *context = NULL; - return 0; - } - - if( c->eof ) - return -1; - - do { - /* get the next secret key from the current keyblock */ - for (; c->node; c->node = c->node->next) { - if ((c->node->pkt->pkttype == PKT_SECRET_KEY - || (with_subkeys - && c->node->pkt->pkttype == PKT_SECRET_SUBKEY) ) - && !(c->node->pkt->pkt.secret_key->protect.s2k.mode==1001 - && !with_spm)) { - copy_secret_key (sk, c->node->pkt->pkt.secret_key ); - c->node = c->node->next; - return 0; /* found */ - } - } - release_kbnode (c->keyblock); - c->keyblock = c->node = NULL; - - rc = c->first? keydb_search_first (c->hd) : keydb_search_next (c->hd); - c->first = 0; - if (rc) { - keydb_release (c->hd); c->hd = NULL; - c->eof = 1; - return -1; /* eof */ - } - - rc = keydb_get_keyblock (c->hd, &c->keyblock); - c->node = c->keyblock; - } while (!rc); - - return rc; /* error */ -} - - - -/********************************************* - *********** user ID printing helpers ******* - *********************************************/ - -/**************** - * Return a string with a printable representation of the user_id. - * this string must be freed by m_free. - */ -char* -get_user_id_string( u32 *keyid ) -{ - user_id_db_t r; - char *p; - int pass=0; - /* try it two times; second pass reads from key resources */ - do { - for(r=user_id_db; r; r = r->next ) { - keyid_list_t a; - for (a=r->keyids; a; a= a->next ) { - if( a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1] ) { - p = xmalloc ( r->len + 10 ); - sprintf(p, "%08lX %.*s", - (ulong)keyid[1], r->len, r->name ); - return p; - } - } - } - } while( ++pass < 2 && !get_pubkey( NULL, keyid ) ); - p = xmalloc ( 15 ); - sprintf(p, "%08lX [?]", (ulong)keyid[1] ); - return p; -} - - -char* -get_user_id_string_printable ( u32 *keyid ) -{ - char *p = get_user_id_string( keyid ); - char *p2 = utf8_to_native( p, strlen(p), 0 ); - xfree (p); - p = make_printable_string (p2, strlen (p2), 0); - xfree (p2); - return p; -} - - -char* -get_long_user_id_string( u32 *keyid ) -{ - user_id_db_t r; - char *p; - int pass=0; - /* try it two times; second pass reads from key resources */ - do { - for(r=user_id_db; r; r = r->next ) { - keyid_list_t a; - for (a=r->keyids; a; a= a->next ) { - if( a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1] ) { - p = xmalloc ( r->len + 20 ); - sprintf(p, "%08lX%08lX %.*s", - (ulong)keyid[0], (ulong)keyid[1], - r->len, r->name ); - return p; - } - } - } - } while( ++pass < 2 && !get_pubkey( NULL, keyid ) ); - p = xmalloc ( 25 ); - sprintf(p, "%08lX%08lX [?]", (ulong)keyid[0], (ulong)keyid[1] ); - return p; -} - -char* -get_user_id( u32 *keyid, size_t *rn ) -{ - user_id_db_t r; - char *p; - int pass=0; - - /* try it two times; second pass reads from key resources */ - do { - for(r=user_id_db; r; r = r->next ) { - keyid_list_t a; - for (a=r->keyids; a; a= a->next ) { - if( a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1] ) { - p = xmalloc ( r->len ); - memcpy(p, r->name, r->len ); - *rn = r->len; - return p; - } - } - } - } while( ++pass < 2 && !get_pubkey( NULL, keyid ) ); - p = xstrdup ( _("[User id not found]") ); - *rn = strlen(p); - return p; -} - -char* -get_user_id_printable( u32 *keyid ) -{ - size_t rn; - char *p = get_user_id( keyid, &rn ); - char *p2 = utf8_to_native( p, rn, 0 ); - xfree (p); - p = make_printable_string (p2, strlen (p2), 0); - xfree (p2); - return p; -} - -KEYDB_HANDLE -get_ctx_handle(GETKEY_CTX ctx) -{ - return ctx->kr_handle; -} diff --git a/g10/global.h b/g10/global.h deleted file mode 100644 index d1c554dce..000000000 --- a/g10/global.h +++ /dev/null @@ -1,31 +0,0 @@ -/* global.h - Local typedefs and constants - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GPG_GLOBAL_H -#define GPG_GLOBAL_H - -#define MAX_FINGERPRINT_LEN 20 - -typedef struct kbnode_struct *KBNODE; -typedef struct keydb_search_desc KEYDB_SEARCH_DESC; - -#include "gpg.h" - -#endif /*GPG_GLOBAL_H*/ diff --git a/g10/gpg.h b/g10/gpg.h deleted file mode 100644 index bf61411f7..000000000 --- a/g10/gpg.h +++ /dev/null @@ -1,38 +0,0 @@ -/* gpg.h - top level include file for gpg etc. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef GNUPG_G10_GPG_H -#define GNUPG_G10_GPG_H - -/* Note, that this file should be the first one after the system - header files. This is required to set the error source to the - correct value and may be of advantage if we ever have to do - special things. */ - -#ifdef GPG_ERR_SOURCE_DEFAULT -#error GPG_ERR_SOURCE_DEFAULT already defined -#endif -#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GPG -#include <gpg-error.h> - - -/* FIXME: merge this with global.h */ - - -#endif /*GNUPG_G10_GPG_H*/ diff --git a/g10/gpgv.c b/g10/gpgv.c deleted file mode 100644 index 9bd954c6f..000000000 --- a/g10/gpgv.c +++ /dev/null @@ -1,389 +0,0 @@ -/* gpgv.c - The GnuPG signature verify utility - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#ifdef HAVE_DOSISH_SYSTEM -#include <fcntl.h> /* for setmode() */ -#endif - -#define INCLUDED_BY_MAIN_MODULE 1 -#include "gpg.h" -#include "packet.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "options.h" -#include "keydb.h" -#include "trustdb.h" -#include "mpi.h" -#include "cipher.h" -#include "filter.h" -#include "ttyio.h" -#include "i18n.h" -#include "status.h" - - -enum cmd_and_opt_values { aNull = 0, - oQuiet = 'q', - oVerbose = 'v', - oBatch = 500, - oKeyring, - oIgnoreTimeConflict, - oStatusFD, - oLoggerFD, - oHomedir, -aTest }; - - -static ARGPARSE_OPTS opts[] = { - - { 301, NULL, 0, N_("@\nOptions:\n ") }, - - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oKeyring, "keyring" ,2, N_("take the keys from this keyring")}, - { oIgnoreTimeConflict, "ignore-time-conflict", 0, - N_("make timestamp conflicts only a warning") }, - { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") }, - { oLoggerFD, "logger-fd",1, "@" }, - { oHomedir, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */ - -{0} }; - - - -int g10_errors_seen = 0; - -#ifdef __riscos__ -RISCOS_GLOBAL_STATICS("GnuPG (gpgv) Heap") -#endif /* __riscos__ */ - -static const char * -my_strusage( int level ) -{ - const char *p; - switch( level ) { - case 11: p = "gpgv (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = - _("Please report bugs to <gnupg-bugs@gnu.org>.\n"); - break; - case 1: - case 40: p = - _("Usage: gpgv [options] [files] (-h for help)"); - break; - case 41: p = - _("Syntax: gpg [options] [files]\n" - "Check signatures against known trusted keys\n"); - break; - - default: p = NULL; - } - return p; -} - - - - -static void -i18n_init(void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE_GT ); -#else -#ifdef ENABLE_NLS -#ifdef HAVE_LC_MESSAGES - setlocale( LC_TIME, "" ); - setlocale( LC_MESSAGES, "" ); -#else - setlocale( LC_ALL, "" ); -#endif - bindtextdomain( PACKAGE_GT, LOCALEDIR ); - textdomain( PACKAGE_GT ); -#endif -#endif -} - - -int -main( int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - int rc=0; - STRLIST sl; - STRLIST nrings=NULL; - unsigned configlineno; - -#ifdef __riscos__ - riscos_global_defaults(); -#endif /* __riscos__ */ - - set_strusage (my_strusage); - log_set_prefix ("gpgv", 1); - gnupg_init_signals(0, NULL); - i18n_init(); - opt.command_fd = -1; /* no command fd */ - opt.pgp2_workarounds = 1; - opt.keyserver_options.auto_key_retrieve = 1; - opt.trust_model = TM_ALWAYS; - opt.batch = 1; - -#if defined (_WIN32) - opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG", - "HomeDir" ); -#else - opt.homedir = getenv("GNUPGHOME"); -#endif - if( !opt.homedir || !*opt.homedir ) { - opt.homedir = GNUPG_DEFAULT_HOMEDIR; - } - tty_no_terminal(1); - tty_batchmode(1); - disable_dotlock(); - - set_native_charset (NULL); /* Try to auto set the character set */ - - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - while( optfile_parse( NULL, NULL, &configlineno, &pargs, opts) ) { - switch( pargs.r_opt ) { - case oQuiet: opt.quiet = 1; break; - case oVerbose: g10_opt_verbose++; - opt.verbose++; opt.list_sigs=1; break; - case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; - case oStatusFD: set_status_fd( pargs.r.ret_int ); break; - case oLoggerFD: - log_set_fd (iobuf_translate_file_handle (pargs.r.ret_int, 1)); - break; - case oHomedir: opt.homedir = pargs.r.ret_str; break; - case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break; - default : pargs.err = 2; break; - } - } - - if( log_get_errorcount(0) ) - g10_exit(2); - - g10_opt_homedir = opt.homedir; - - if( opt.verbose > 1 ) - set_packet_list_mode(1); - - if( !nrings ) /* no keyring given: use default one */ - keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", 0, 0); - for(sl = nrings; sl; sl = sl->next ) - keydb_add_resource (sl->d, 0, 0 ); - - FREE_STRLIST(nrings); - - if( (rc = verify_signatures( argc, argv ) )) - log_error("verify signatures failed: %s\n", gpg_strerror (rc) ); - - /* cleanup */ - g10_exit(0); - return 8; /*NEVER REACHED*/ -} - - -void -g10_exit( int rc ) -{ - rc = rc? rc : log_get_errorcount(0)? 2 : - g10_errors_seen? 1 : 0; - exit(rc ); -} - - - -void -read_trust_options (byte *trust_model,ulong *created,ulong *nextcheck, - byte *marginals,byte *completes,byte *cert_depth) -{ -} - - -/* Stub: - * We have to override the trustcheck from pkclist.c becuase - * this utility assumes that all keys in the keyring are trustworthy - */ -int -check_signatures_trust( PKT_signature *sig ) -{ - return 0; -} - - -/* Stub: - * We don't have the trustdb , so we have to provide some stub functions - * instead - */ - -int -cache_disabled_value(PKT_public_key *pk) -{ - return 0; -} - -int -get_validity_info (PKT_public_key *pk, PKT_user_id *uid) -{ - return '?'; -} - -unsigned int -get_validity (PKT_public_key *pk, PKT_user_id *uid) -{ - return 0; -} - -const char * -trust_value_to_string (unsigned int value) -{ - return "err"; -} - -/* Stub: */ -int -get_ownertrust_info (PKT_public_key *pk) -{ - return '?'; -} - -unsigned int -get_ownertrust (PKT_public_key *pk) -{ - return TRUST_UNKNOWN; -} - - -/* Stub: - * Because we only work with trusted keys, it does not make sense to - * get them from a keyserver - */ -int -keyserver_import_keyid( u32 *keyid, void *dummy ) -{ - return -1; -} - -/* Stub: - * No encryption here but mainproc links to these functions. - */ -int -get_session_key( PKT_pubkey_enc *k, DEK *dek ) -{ - return GPG_ERR_GENERAL; -} -/* Stub: */ -int -get_override_session_key( DEK *dek, const char *string ) -{ - return GPG_ERR_GENERAL; -} -/* Stub: */ -int -decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) -{ - return GPG_ERR_GENERAL; -} - - -/* Stub: - * No interactive commnds, so we don't need the helptexts - */ -void -display_online_help( const char *keyword ) -{ -} - -/* Stub: - * We don't use secret keys, but getkey.c links to this - */ -int -check_secret_key( PKT_secret_key *sk, int n ) -{ - return GPG_ERR_GENERAL; -} - -/* Stub: - * No secret key, so no passphrase needed - */ -DEK * -passphrase_to_dek( u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, - const char *tmp, int *canceled) -{ - if (canceled) - *canceled = 0; - return NULL; -} - -/* Stubs to avoid linking to photoid.c */ -void show_photos(const struct user_attribute *attrs,int count,PKT_public_key *pk) {} -int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len) {return 0;} -char *image_type_to_string(byte type,int string) {return NULL;} - -/* Stubs to void linking to ../cipher/cipher.c */ -int string_to_cipher_algo( const char *string ) { return 0; } -const char *cipher_algo_to_string( int algo ) { return "?";} -void disable_cipher_algo( int algo ) {} -int check_cipher_algo( int algo ) { return -1;} -unsigned int cipher_get_keylen( int algo ) { return 0; } -unsigned int cipher_get_blocksize( int algo ) {return 0;} -CIPHER_HANDLE cipher_open( int algo, int mode, int secure ) { return NULL;} -void cipher_close( CIPHER_HANDLE c ) {} -int cipher_setkey( CIPHER_HANDLE c, byte *key, unsigned keylen ) { return -1;} -void cipher_setiv( CIPHER_HANDLE c, const byte *iv, unsigned ivlen ){} -void cipher_encrypt( CIPHER_HANDLE c, byte *outbuf, - byte *inbuf, unsigned nbytes ) {} -void cipher_decrypt( CIPHER_HANDLE c, byte *outbuf, - byte *inbuf, unsigned nbytes ) {} -void cipher_sync( CIPHER_HANDLE c ) {} - - -/* Stubs to avoid linking to ../util/ttyio.c */ -int tty_batchmode( int onoff ) { return 0; } -void tty_printf( const char *fmt, ... ) { } -void tty_print_string( const byte *p, size_t n ) { } -void tty_print_utf8_string( const byte *p, size_t n ) {} -void tty_print_utf8_string2( const byte *p, size_t n, size_t max_n ) {} -char *tty_get( const char *prompt ) { return NULL;} -char *tty_get_hidden( const char *prompt ) {return NULL; } -void tty_kill_prompt(void) {} -int tty_get_answer_is_yes( const char *prompt ) {return 0;} -int tty_no_terminal(int onoff) {return 0;} - -/* We do not do any locking, so use these stubs here */ -void disable_dotlock(void) {} -DOTLOCK create_dotlock( const char *file_to_lock ) { return NULL; } -int make_dotlock( DOTLOCK h, long timeout ) { return 0;} -int release_dotlock( DOTLOCK h ) {return 0;} -void dotlock_remove_lockfiles(void) {} diff --git a/g10/helptext.c b/g10/helptext.c deleted file mode 100644 index 4a65314eb..000000000 --- a/g10/helptext.c +++ /dev/null @@ -1,316 +0,0 @@ -/* helptext.c - English help texts - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "gpg.h" -#include "util.h" -#include "ttyio.h" -#include "main.h" -#include "i18n.h" - - -/**************** - * These helptexts are used for the "online" help feature. We use - * a key consisting of words and dots. Because the lookup is only - * done in an interactive mode on a user request (when she enters a "?" - * as response to a prompt) we can use a simple search through the list. - * - * Mini glossary: - * - * "user ID", "trustdb", "NOTE" and "WARNING". - */ - -static struct helptexts { const char *key; const char *help; } helptexts[] = { - -/* begin of list */ - -{ "edit_ownertrust.value", N_( -"It's up to you to assign a value here; this value will never be exported\n" -"to any 3rd party. We need it to implement the web-of-trust; it has nothing\n" -"to do with the (implicitly created) web-of-certificates." -)}, - -{ "edit_ownertrust.set_ultimate.okay", N_( - "To build the Web-of-Trust, GnuPG needs to know which keys are\n" - "ultimately trusted - those are usually the keys for which you have\n" - "access to the secret key. Answer \"yes\" to set this key to\n" - "ultimately trusted\n" -)}, - -{ "revoked_key.override", N_( -"If you want to use this revoked key anyway, answer \"yes\"." -)}, - -{ "untrusted_key.override", N_( -"If you want to use this untrusted key anyway, answer \"yes\"." -)}, - -{ "pklist.user_id.enter", N_( -"Enter the user ID of the addressee to whom you want to send the message." -)}, - -{ "keygen.algo", N_( -"Select the algorithm to use.\n" -"\n" -"DSA (aka DSS) is the digital signature algorithm which can only be used\n" -"for signatures. This is the suggested algorithm because verification of\n" -"DSA signatures are much faster than those of ElGamal.\n" -"\n" -"ElGamal is an algorithm which can be used for signatures and encryption.\n" -"OpenPGP distinguishs between two flavors of this algorithms: an encrypt only\n" -"and a sign+encrypt; actually it is the same, but some parameters must be\n" -"selected in a special way to create a safe key for signatures: this program\n" -"does this but other OpenPGP implementations are not required to understand\n" -"the signature+encryption flavor.\n" -"\n" -"The first (primary) key must always be a key which is capable of signing;\n" -"this is the reason why the encryption only ElGamal key is not available in\n" -"this menu." -)}, - - -{ "keygen.algo.elg_se", N_( -"Although these keys are defined in RFC2440 they are not suggested\n" -"because they are not supported by all programs and signatures created\n" -"with them are quite large and very slow to verify." -)}, - -{ "keygen.algo.rsa_se", N_( -"In general it is not a good idea to use the same key for signing and\n" -"encryption. This algorithm should only be used in certain domains.\n" -"Please consult your security expert first." -)}, - - -{ "keygen.size", N_( - "Enter the size of the key" -)}, - -{ "keygen.size.huge.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - - -{ "keygen.size.large.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - - -{ "keygen.valid", N_( - "Enter the required value as shown in the prompt.\n" - "It is possible to enter a ISO date (YYYY-MM-DD) but you won't\n" - "get a good error response - instead the system tries to interpret\n" - "the given value as an interval." -)}, - -{ "keygen.valid.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - - -{ "keygen.name", N_( - "Enter the name of the key holder" -)}, - - -{ "keygen.email", N_( - "please enter an optional but highly suggested email address" -)}, - -{ "keygen.comment", N_( - "Please enter an optional comment" -)}, - - -{ "keygen.userid.cmd", N_( - "" -"N to change the name.\n" -"C to change the comment.\n" -"E to change the email address.\n" -"O to continue with key generation.\n" -"Q to to quit the key generation." -)}, - -{ "keygen.sub.okay", N_( - "Answer \"yes\" (or just \"y\") if it is okay to generate the sub key." -)}, - -{ "sign_uid.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - -{ "sign_uid.class", N_( -"When you sign a user ID on a key, you should first verify that the key\n" -"belongs to the person named in the user ID. It is useful for others to\n" -"know how carefully you verified this.\n\n" -"\"0\" means you make no particular claim as to how carefully you verified the\n" -" key.\n\n" -"\"1\" means you believe the key is owned by the person who claims to own it\n" -" but you could not, or did not verify the key at all. This is useful for\n" -" a \"persona\" verification, where you sign the key of a pseudonymous user.\n\n" -"\"2\" means you did casual verification of the key. For example, this could\n" -" mean that you verified the key fingerprint and checked the user ID on the\n" -" key against a photo ID.\n\n" -"\"3\" means you did extensive verification of the key. For example, this could\n" -" mean that you verified the key fingerprint with the owner of the key in\n" -" person, and that you checked, by means of a hard to forge document with a\n" -" photo ID (such as a passport) that the name of the key owner matches the\n" -" name in the user ID on the key, and finally that you verified (by exchange\n" -" of email) that the email address on the key belongs to the key owner.\n\n" -"Note that the examples given above for levels 2 and 3 are *only* examples.\n" -"In the end, it is up to you to decide just what \"casual\" and \"extensive\"\n" -"mean to you when you sign other keys.\n\n" -"If you don't know what the right answer is, answer \"0\"." -)}, - -{ "change_passwd.empty.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - - -{ "keyedit.save.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - - -{ "keyedit.cancel.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - -{ "keyedit.sign_all.okay", N_( - "Answer \"yes\" is you want to sign ALL the user IDs" -)}, - -{ "keyedit.remove.uid.okay", N_( - "Answer \"yes\" if you really want to delete this user ID.\n" - "All certificates are then also lost!" -)}, - -{ "keyedit.remove.subkey.okay", N_( - "Answer \"yes\" if it is okay to delete the subkey" -)}, - - -{ "keyedit.delsig.valid", N_( - "This is a valid signature on the key; you normally don't want\n" - "to delete this signature because it may be important to establish a\n" - "trust connection to the key or another key certified by this key." -)}, -{ "keyedit.delsig.unknown", N_( - "This signature can't be checked because you don't have the\n" - "corresponding key. You should postpone its deletion until you\n" - "know which key was used because this signing key might establish\n" - "a trust connection through another already certified key." -)}, -{ "keyedit.delsig.invalid", N_( - "The signature is not valid. It does make sense to remove it from\n" - "your keyring." -)}, -{ "keyedit.delsig.selfsig", N_( - "This is a signature which binds the user ID to the key. It is\n" - "usually not a good idea to remove such a signature. Actually\n" - "GnuPG might not be able to use this key anymore. So do this\n" - "only if this self-signature is for some reason not valid and\n" - "a second one is available." -)}, - -{ "keyedit.updpref.okay", N_( - "Change the preferences of all user IDs (or just of the selected ones)\n" - "to the current list of preferences. The timestamp of all affected\n" - "self-signatures will be advanced by one second.\n" -)}, - - -{ "passphrase.enter", N_( - "" -"Please enter the passhrase; this is a secret sentence \n" -)}, - - -{ "passphrase.repeat", N_( - "Please repeat the last passphrase, so you are sure what you typed in." -)}, - -{ "detached_signature.filename", N_( - "Give the name of the file to which the signature applies" -)}, - -/* openfile.c (overwrite_filep) */ -{ "openfile.overwrite.okay", N_( - "Answer \"yes\" if it is okay to overwrite the file" -)}, - -/* openfile.c (ask_outfile_name) */ -{ "openfile.askoutname", N_( - "Please enter a new filename. If you just hit RETURN the default\n" - "file (which is shown in brackets) will be used." -)}, - -/* revoke.c (ask_revocation_reason) */ -{ "ask_revocation_reason.code", N_( - "You should specify a reason for the certification. Depending on the\n" - "context you have the ability to choose from this list:\n" - " \"Key has been compromised\"\n" - " Use this if you have a reason to believe that unauthorized persons\n" - " got access to your secret key.\n" - " \"Key is superseded\"\n" - " Use this if you have replaced this key with a newer one.\n" - " \"Key is no longer used\"\n" - " Use this if you have retired this key.\n" - " \"User ID is no longer valid\"\n" - " Use this to state that the user ID should not longer be used;\n" - " this is normally used to mark an email address invalid.\n" -)}, - -/* revoke.c (ask_revocation_reason) */ -{ "ask_revocation_reason.text", N_( - "If you like, you can enter a text describing why you issue this\n" - "revocation certificate. Please keep this text concise.\n" - "An empty line ends the text.\n" -)}, - -/* end of list */ -{ NULL, NULL } }; - - -void -display_online_help( const char *keyword ) -{ - - tty_kill_prompt(); - if( !keyword ) - tty_printf(_("No help available") ); - else { - const char *p; - int i; - - for(i=0; (p=helptexts[i].key) && strcmp( p, keyword ); i++ ) - ; - if( !p || !*helptexts[i].help ) - tty_printf(_("No help available for `%s'"), keyword ); - else - tty_printf("%s", _(helptexts[i].help) ); - } - tty_printf("\n"); -} diff --git a/g10/import.c b/g10/import.c deleted file mode 100644 index 9c323243a..000000000 --- a/g10/import.c +++ /dev/null @@ -1,1906 +0,0 @@ -/* import.c - Import OpenPGP key material - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "trustdb.h" -#include "main.h" -#include "i18n.h" -#include "ttyio.h" -#include "status.h" -#include "keyserver-internal.h" - -struct stats_s { - ulong count; - ulong no_user_id; - ulong imported; - ulong imported_rsa; - ulong n_uids; - ulong n_sigs; - ulong n_subk; - ulong unchanged; - ulong n_revoc; - ulong secret_read; - ulong secret_imported; - ulong secret_dups; - ulong skipped_new_keys; - ulong not_imported; -}; - - -static int import( iobuf_t inp, const char* fname, - struct stats_s *stats, unsigned int options ); -static int read_block( iobuf_t a, PACKET **pending_pkt, KBNODE *ret_root ); -static void revocation_present(KBNODE keyblock); -static int import_one( const char *fname, KBNODE keyblock, - struct stats_s *stats, unsigned int options); -static int import_secret_one( const char *fname, KBNODE keyblock, - struct stats_s *stats, unsigned int options); -static int import_revoke_cert( const char *fname, KBNODE node, - struct stats_s *stats); -static int chk_self_sigs( const char *fname, KBNODE keyblock, - PKT_public_key *pk, u32 *keyid, int *non_self ); -static int delete_inv_parts( const char *fname, KBNODE keyblock, - u32 *keyid, unsigned int options ); -static int merge_blocks( const char *fname, KBNODE keyblock_orig, - KBNODE keyblock, u32 *keyid, - int *n_uids, int *n_sigs, int *n_subk ); -static int append_uid( KBNODE keyblock, KBNODE node, int *n_sigs, - const char *fname, u32 *keyid ); -static int append_key( KBNODE keyblock, KBNODE node, int *n_sigs, - const char *fname, u32 *keyid ); -static int merge_sigs( KBNODE dst, KBNODE src, int *n_sigs, - const char *fname, u32 *keyid ); -static int merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs, - const char *fname, u32 *keyid ); - -int -parse_import_options(char *str,unsigned int *options) -{ - struct parse_options import_opts[]= - { - {"allow-local-sigs",IMPORT_ALLOW_LOCAL_SIGS}, - {"repair-hkp-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG}, - {"repair-pks-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG}, - {"fast-import",IMPORT_FAST_IMPORT}, - {"convert-sk-to-pk",IMPORT_SK2PK}, - {NULL,0} - }; - - return parse_options(str,options,import_opts); -} - -void * -import_new_stats_handle (void) -{ - return xcalloc (1, sizeof (struct stats_s) ); -} - -void -import_release_stats_handle (void *p) -{ - xfree (p); -} - -/**************** - * Import the public keys from the given filename. Input may be armored. - * This function rejects all keys which are not validly self signed on at - * least one userid. Only user ids which are self signed will be imported. - * Other signatures are not checked. - * - * Actually this function does a merge. It works like this: - * - * - get the keyblock - * - check self-signatures and remove all userids and their signatures - * without/invalid self-signatures. - * - reject the keyblock, if we have no valid userid. - * - See whether we have this key already in one of our pubrings. - * If not, simply add it to the default keyring. - * - Compare the key and the self-signatures of the new and the one in - * our keyring. If they are different something weird is going on; - * ask what to do. - * - See whether we have only non-self-signature on one user id; if not - * ask the user what to do. - * - compare the signatures: If we already have this signature, check - * that they compare okay; if not, issue a warning and ask the user. - * (consider looking at the timestamp and use the newest?) - * - Simply add the signature. Can't verify here because we may not have - * the signature's public key yet; verification is done when putting it - * into the trustdb, which is done automagically as soon as this pubkey - * is used. - * - Proceed with next signature. - * - * Key revocation certificates have special handling. - * - */ -static int -import_keys_internal( iobuf_t inp, char **fnames, int nnames, - void *stats_handle, unsigned int options ) -{ - int i, rc = 0; - struct stats_s *stats = stats_handle; - - if (!stats) - stats = import_new_stats_handle (); - - if (inp) { - rc = import( inp, "[stream]", stats, options); - } - else { - if( !fnames && !nnames ) - nnames = 1; /* Ohh what a ugly hack to jump into the loop */ - - for(i=0; i < nnames; i++ ) { - const char *fname = fnames? fnames[i] : NULL; - iobuf_t inp2 = iobuf_open(fname); - if( !fname ) - fname = "[stdin]"; - if( !inp2 ) - log_error(_("can't open `%s': %s\n"), fname, strerror(errno) ); - else { - rc = import( inp2, fname, stats, options ); - iobuf_close(inp2); - /* Must invalidate that ugly cache to actually close it. */ - iobuf_ioctl (NULL, 2, 0, (char*)fname); - if( rc ) - log_error("import from `%s' failed: %s\n", fname, - gpg_strerror (rc) ); - } - if( !fname ) - break; - } - } - if (!stats_handle) { - import_print_stats (stats); - import_release_stats_handle (stats); - } - /* If no fast import and the trustdb is dirty (i.e. we added a key - or userID that had something other than a selfsig, a signature - that was other than a selfsig, or any revocation), then - update/check the trustdb if the user specified by setting - interactive or by not setting no-auto-check-trustdb */ - if (!(options&IMPORT_FAST_IMPORT) && trustdb_pending_check()) - { - if (opt.interactive) - update_trustdb(); - else if (!opt.no_auto_check_trustdb) - check_trustdb(); - } - - return rc; -} - -void -import_keys( char **fnames, int nnames, - void *stats_handle, unsigned int options ) -{ - import_keys_internal( NULL, fnames, nnames, stats_handle, options); -} - -int -import_keys_stream( iobuf_t inp, void *stats_handle, unsigned int options ) -{ - return import_keys_internal( inp, NULL, 0, stats_handle, options); -} - -static int -import( iobuf_t inp, const char* fname, - struct stats_s *stats, unsigned int options ) -{ - PACKET *pending_pkt = NULL; - KBNODE keyblock; - int rc = 0; - - getkey_disable_caches(); - - if( !opt.no_armor ) { /* armored reading is not disabled */ - armor_filter_context_t *afx = xcalloc (1, sizeof *afx ); - afx->only_keyblocks = 1; - iobuf_push_filter2( inp, armor_filter, afx, 1 ); - } - - while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) { - if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY ) - rc = import_one( fname, keyblock, stats, options ); - else if( keyblock->pkt->pkttype == PKT_SECRET_KEY ) - rc = import_secret_one( fname, keyblock, stats, options ); - else if( keyblock->pkt->pkttype == PKT_SIGNATURE - && keyblock->pkt->pkt.signature->sig_class == 0x20 ) - rc = import_revoke_cert( fname, keyblock, stats ); - else { - log_info( _("skipping block of type %d\n"), - keyblock->pkt->pkttype ); - } - release_kbnode(keyblock); - /* fixme: we should increment the not imported counter but this - does only make sense if we keep on going despite of errors. */ - if( rc ) - break; - if( !(++stats->count % 100) && !opt.quiet ) - log_info(_("%lu keys processed so far\n"), stats->count ); - } - if( rc == -1 ) - rc = 0; - else if( rc && rc != GPG_ERR_INV_KEYRING ) - log_error( _("error reading `%s': %s\n"), fname, gpg_strerror (rc)); - - return rc; -} - - -void -import_print_stats (void *hd) -{ - struct stats_s *stats = hd; - - if( !opt.quiet ) { - log_info(_("Total number processed: %lu\n"), stats->count ); - if( stats->skipped_new_keys ) - log_info(_(" skipped new keys: %lu\n"), - stats->skipped_new_keys ); - if( stats->no_user_id ) - log_info(_(" w/o user IDs: %lu\n"), stats->no_user_id ); - if( stats->imported || stats->imported_rsa ) { - log_info(_(" imported: %lu"), stats->imported ); - if( stats->imported_rsa ) - fprintf(stderr, " (RSA: %lu)", stats->imported_rsa ); - putc('\n', stderr); - } - if( stats->unchanged ) - log_info(_(" unchanged: %lu\n"), stats->unchanged ); - if( stats->n_uids ) - log_info(_(" new user IDs: %lu\n"), stats->n_uids ); - if( stats->n_subk ) - log_info(_(" new subkeys: %lu\n"), stats->n_subk ); - if( stats->n_sigs ) - log_info(_(" new signatures: %lu\n"), stats->n_sigs ); - if( stats->n_revoc ) - log_info(_(" new key revocations: %lu\n"), stats->n_revoc ); - if( stats->secret_read ) - log_info(_(" secret keys read: %lu\n"), stats->secret_read ); - if( stats->secret_imported ) - log_info(_(" secret keys imported: %lu\n"), stats->secret_imported ); - if( stats->secret_dups ) - log_info(_(" secret keys unchanged: %lu\n"), stats->secret_dups ); - if( stats->not_imported ) - log_info(_(" not imported: %lu\n"), stats->not_imported ); - } - - if( is_status_enabled() ) { - char buf[14*20]; - sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", - stats->count, - stats->no_user_id, - stats->imported, - stats->imported_rsa, - stats->unchanged, - stats->n_uids, - stats->n_subk, - stats->n_sigs, - stats->n_revoc, - stats->secret_read, - stats->secret_imported, - stats->secret_dups, - stats->skipped_new_keys, - stats->not_imported ); - write_status_text( STATUS_IMPORT_RES, buf ); - } -} - - -/**************** - * Read the next keyblock from stream A. - * PENDING_PKT should be initialzed to NULL - * and not chnaged form the caller. - * Retunr: 0 = okay, -1 no more blocks or another errorcode. - */ -static int -read_block( iobuf_t a, PACKET **pending_pkt, KBNODE *ret_root ) -{ - int rc; - PACKET *pkt; - KBNODE root = NULL; - int in_cert; - - if( *pending_pkt ) { - root = new_kbnode( *pending_pkt ); - *pending_pkt = NULL; - in_cert = 1; - } - else - in_cert = 0; - pkt = xmalloc ( sizeof *pkt ); - init_packet(pkt); - while( (rc=parse_packet(a, pkt)) != -1 ) { - if( rc ) { /* ignore errors */ - if( rc != GPG_ERR_UNKNOWN_PACKET ) { - log_error("read_block: read error: %s\n", gpg_strerror (rc) ); - rc = GPG_ERR_INV_KEYRING; - goto ready; - } - free_packet( pkt ); - init_packet(pkt); - continue; - } - - if( !root && pkt->pkttype == PKT_SIGNATURE - && pkt->pkt.signature->sig_class == 0x20 ) { - /* this is a revocation certificate which is handled - * in a special way */ - root = new_kbnode( pkt ); - pkt = NULL; - goto ready; - } - - /* make a linked list of all packets */ - switch( pkt->pkttype ) { - case PKT_COMPRESSED: - if( pkt->pkt.compressed->algorithm < 1 - || pkt->pkt.compressed->algorithm > 2 ) { - rc = GPG_ERR_COMPR_ALGO; - goto ready; - } - { - compress_filter_context_t *cfx = xcalloc (1, sizeof *cfx ); - cfx->algo = pkt->pkt.compressed->algorithm; - pkt->pkt.compressed->buf = NULL; - iobuf_push_filter2( a, compress_filter, cfx, 1 ); - } - free_packet( pkt ); - init_packet(pkt); - break; - - case PKT_RING_TRUST: - /* skip those packets */ - free_packet( pkt ); - init_packet(pkt); - break; - - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - if( in_cert ) { /* store this packet */ - *pending_pkt = pkt; - pkt = NULL; - goto ready; - } - in_cert = 1; - default: - if( in_cert ) { - if( !root ) - root = new_kbnode( pkt ); - else - add_kbnode( root, new_kbnode( pkt ) ); - pkt = xmalloc ( sizeof *pkt ); - } - init_packet(pkt); - break; - } - } - ready: - if( rc == -1 && root ) - rc = 0; - - if( rc ) - release_kbnode( root ); - else - *ret_root = root; - free_packet( pkt ); - xfree ( pkt ); - return rc; -} - -/* Walk through the subkeys on a pk to find if we have the PKS - disease: multiple subkeys with their binding sigs stripped, and the - sig for the first subkey placed after the last subkey. That is, - instead of "pk uid sig sub1 bind1 sub2 bind2 sub3 bind3" we have - "pk uid sig sub1 sub2 sub3 bind1". We can't do anything about sub2 - and sub3, as they are already lost, but we can try and rescue sub1 - by reordering the keyblock so that it reads "pk uid sig sub1 bind1 - sub2 sub3". Returns TRUE if the keyblock was modified. */ - -static int -fix_pks_corruption(KBNODE keyblock) -{ - int changed=0,keycount=0; - KBNODE node,last=NULL,sknode=NULL; - - /* First determine if we have the problem at all. Look for 2 or - more subkeys in a row, followed by a single binding sig. */ - for(node=keyblock;node;last=node,node=node->next) - { - if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY) - { - keycount++; - if(!sknode) - sknode=node; - } - else if(node->pkt->pkttype==PKT_SIGNATURE && - node->pkt->pkt.signature->sig_class==0x18 && - keycount>=2 && node->next==NULL) - { - /* We might have the problem, as this key has two subkeys in - a row without any intervening packets. */ - - /* Sanity check */ - if(last==NULL) - break; - - /* Temporarily attach node to sknode. */ - node->next=sknode->next; - sknode->next=node; - last->next=NULL; - - /* Note we aren't checking whether this binding sig is a - selfsig. This is not necessary here as the subkey and - binding sig will be rejected later if that is the - case. */ - if(check_key_signature(keyblock,node,NULL)) - { - /* Not a match, so undo the changes. */ - sknode->next=node->next; - last->next=node; - node->next=NULL; - break; - } - else - { - sknode->flag |= 1; /* Mark it good so we don't need to - check it again */ - changed=1; - break; - } - } - else - keycount=0; - } - - return changed; -} - - -static void -print_import_ok (PKT_public_key *pk, PKT_secret_key *sk, unsigned int reason) -{ - byte array[MAX_FINGERPRINT_LEN], *s; - char buf[MAX_FINGERPRINT_LEN*2+30], *p; - size_t i, n; - - sprintf (buf, "%u ", reason); - p = buf + strlen (buf); - - if (pk) - fingerprint_from_pk (pk, array, &n); - else - fingerprint_from_sk (sk, array, &n); - s = array; - for (i=0; i < n ; i++, s++, p += 2) - sprintf (p, "%02X", *s); - - write_status_text (STATUS_IMPORT_OK, buf); -} - -void -print_import_check (PKT_public_key * pk, PKT_user_id * id) -{ - char * buf; - byte fpr[24]; - u32 keyid[2]; - size_t i, pos = 0, n; - - buf = xmalloc (17+41+id->len+32); - keyid_from_pk (pk, keyid); - sprintf (buf, "%08X%08X ", keyid[0], keyid[1]); - pos = 17; - fingerprint_from_pk (pk, fpr, &n); - for (i = 0; i < n; i++, pos += 2) - sprintf (buf+pos, "%02X", fpr[i]); - strcat (buf, " "); - pos += 1; - strcat (buf, id->name); - write_status_text (STATUS_IMPORT_CHECK, buf); - xfree (buf); -} - -/**************** - * Try to import one keyblock. Return an error only in serious cases, but - * never for an invalid keyblock. It uses log_error to increase the - * internal errorcount, so that invalid input can be detected by programs - * which called g10. - */ -static int -import_one( const char *fname, KBNODE keyblock, - struct stats_s *stats, unsigned int options ) -{ - PKT_public_key *pk; - PKT_public_key *pk_orig; - KBNODE node, uidnode; - KBNODE keyblock_orig = NULL; - u32 keyid[2]; - int rc = 0; - int new_key = 0; - int mod_key = 0; - int non_self = 0; - - /* get the key and print some info about it */ - node = find_kbnode( keyblock, PKT_PUBLIC_KEY ); - if( !node ) - BUG(); - - pk = node->pkt->pkt.public_key; - keyid_from_pk( pk, keyid ); - uidnode = find_next_kbnode( keyblock, PKT_USER_ID ); - - if(pk->pubkey_algo==PUBKEY_ALGO_ELGAMAL) - log_info(_("NOTE: Elgamal primary key detected - " - "this may take some time to import\n")); - - if( opt.verbose && !opt.interactive ) { - log_info( "pub %4u%c/%08lX %s ", - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo ), - (ulong)keyid[1], datestr_from_pk(pk) ); - if( uidnode ) - print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name, - uidnode->pkt->pkt.user_id->len ); - putc('\n', stderr); - } - if( !uidnode ) { - log_error( _("key %08lX: no user ID\n"), (ulong)keyid[1]); - return 0; - } - - if (opt.interactive) { - if(is_status_enabled()) - print_import_check (pk, uidnode->pkt->pkt.user_id); - merge_keys_and_selfsig (keyblock); - tty_printf ("\n"); - show_basic_key_info (keyblock); - tty_printf ("\n"); - if (!cpr_get_answer_is_yes ("import.okay", - "Do you want to import this key? (y/N) ")) - return 0; - } - - clear_kbnode_flags( keyblock ); - - if((options&IMPORT_REPAIR_PKS_SUBKEY_BUG) && fix_pks_corruption(keyblock) - && opt.verbose) - log_info(_("key %08lX: PKS subkey corruption repaired\n"), - (ulong)keyid[1]); - - rc = chk_self_sigs( fname, keyblock , pk, keyid, &non_self ); - if( rc ) - return rc== -1? 0:rc; - - /* If we allow such a thing, mark unsigned uids as valid */ - if( opt.allow_non_selfsigned_uid ) - for( node=keyblock; node; node = node->next ) - if( node->pkt->pkttype == PKT_USER_ID && !(node->flag & 1) ) - { - char *user=utf8_to_native(node->pkt->pkt.user_id->name, - node->pkt->pkt.user_id->len,0); - node->flag |= 1; - log_info( _("key %08lX: accepted non self-signed user ID '%s'\n"), - (ulong)keyid[1],user); - xfree (user); - } - - if( !delete_inv_parts( fname, keyblock, keyid, options ) ) { - log_error ( _("key %08lX: no valid user IDs\n"), (ulong)keyid[1]); - if( !opt.quiet ) - log_info(_("this may be caused by a missing self-signature\n")); - stats->no_user_id++; - return 0; - } - - /* do we have this key already in one of our pubrings ? */ - pk_orig = xcalloc (1, sizeof *pk_orig ); - rc = get_pubkey_fast ( pk_orig, keyid ); - if( rc && gpg_err_code (rc) != GPG_ERR_NO_PUBKEY - && gpg_err_code (rc) != GPG_ERR_UNUSABLE_PUBKEY ) { - log_error( _("key %08lX: public key not found: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - } - else if ( rc && opt.merge_only ) { - if( opt.verbose ) - log_info( _("key %08lX: new key - skipped\n"), (ulong)keyid[1] ); - rc = 0; - stats->skipped_new_keys++; - } - else if( rc ) { /* insert this key */ - KEYDB_HANDLE hd = keydb_new (0); - - rc = keydb_locate_writable (hd, NULL); - if (rc) { - log_error (_("no writable keyring found: %s\n"), gpg_strerror (rc)); - keydb_release (hd); - return GPG_ERR_GENERAL; - } - if( opt.verbose > 1 ) - log_info (_("writing to `%s'\n"), keydb_get_resource_name (hd) ); - rc = keydb_insert_keyblock (hd, keyblock ); - if (rc) - log_error (_("error writing keyring `%s': %s\n"), - keydb_get_resource_name (hd), gpg_strerror (rc)); - else - { - /* This should not be possible since we delete the - ownertrust when a key is deleted, but it can happen if - the keyring and trustdb are out of sync. It can also - be made to happen with the trusted-key command. */ - - clear_ownertrusts (pk); - if(non_self) - revalidation_mark (); - } - keydb_release (hd); - - /* we are ready */ - if( !opt.quiet ) { - char *p=get_user_id_printable (keyid); - log_info( _("key %08lX: public key \"%s\" imported\n"), - (ulong)keyid[1],p); - xfree (p); - } - if( is_status_enabled() ) { - char *us = get_long_user_id_string( keyid ); - write_status_text( STATUS_IMPORTED, us ); - xfree (us); - print_import_ok (pk,NULL, 1); - } - stats->imported++; - if( is_RSA( pk->pubkey_algo ) ) - stats->imported_rsa++; - new_key = 1; - } - else { /* merge */ - KEYDB_HANDLE hd; - int n_uids, n_sigs, n_subk; - - /* Compare the original against the new key; just to be sure nothing - * weird is going on */ - if( cmp_public_keys( pk_orig, pk ) ) { - log_error( _("key %08lX: doesn't match our copy\n"), - (ulong)keyid[1]); - goto leave; - } - - /* now read the original keyblock */ - hd = keydb_new (0); - { - byte afp[MAX_FINGERPRINT_LEN]; - size_t an; - - fingerprint_from_pk (pk_orig, afp, &an); - while (an < MAX_FINGERPRINT_LEN) - afp[an++] = 0; - rc = keydb_search_fpr (hd, afp); - } - if( rc ) { - log_error (_("key %08lX: can't locate original keyblock: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - keydb_release (hd); - goto leave; - } - rc = keydb_get_keyblock (hd, &keyblock_orig ); - if (rc) { - log_error (_("key %08lX: can't read original keyblock: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - keydb_release (hd); - goto leave; - } - - collapse_uids( &keyblock ); - /* and try to merge the block */ - clear_kbnode_flags( keyblock_orig ); - clear_kbnode_flags( keyblock ); - n_uids = n_sigs = n_subk = 0; - rc = merge_blocks( fname, keyblock_orig, keyblock, - keyid, &n_uids, &n_sigs, &n_subk ); - if( rc ) { - keydb_release (hd); - goto leave; - } - if( n_uids || n_sigs || n_subk ) { - mod_key = 1; - /* keyblock_orig has been updated; write */ - rc = keydb_update_keyblock (hd, keyblock_orig); - if (rc) - log_error (_("error writing keyring `%s': %s\n"), - keydb_get_resource_name (hd), gpg_strerror (rc) ); - else if(non_self) - revalidation_mark (); - - /* we are ready */ - if( !opt.quiet ) { - char *p=get_user_id_printable(keyid); - if( n_uids == 1 ) - log_info( _("key %08lX: \"%s\" 1 new user ID\n"), - (ulong)keyid[1], p); - else if( n_uids ) - log_info( _("key %08lX: \"%s\" %d new user IDs\n"), - (ulong)keyid[1], p, n_uids ); - if( n_sigs == 1 ) - log_info( _("key %08lX: \"%s\" 1 new signature\n"), - (ulong)keyid[1], p); - else if( n_sigs ) - log_info( _("key %08lX: \"%s\" %d new signatures\n"), - (ulong)keyid[1], p, n_sigs ); - if( n_subk == 1 ) - log_info( _("key %08lX: \"%s\" 1 new subkey\n"), - (ulong)keyid[1], p); - else if( n_subk ) - log_info( _("key %08lX: \"%s\" %d new subkeys\n"), - (ulong)keyid[1], p, n_subk ); - xfree (p); - } - - stats->n_uids +=n_uids; - stats->n_sigs +=n_sigs; - stats->n_subk +=n_subk; - - if (is_status_enabled ()) - print_import_ok (pk, NULL, - ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0))); - } - else { - if (is_status_enabled ()) - print_import_ok (pk, NULL, 0); - - if( !opt.quiet ) { - char *p=get_user_id_printable(keyid); - log_info( _("key %08lX: \"%s\" not changed\n"), - (ulong)keyid[1],p); - xfree (p); - } - stats->unchanged++; - } - keydb_release (hd); hd = NULL; - } - - leave: - release_kbnode( keyblock_orig ); - free_public_key( pk_orig ); - - revocation_present(keyblock); - - return rc; -} - -/* Walk a secret keyblock and produce a public keyblock out of it. */ -static KBNODE -sec_to_pub_keyblock(KBNODE sec_keyblock) -{ - KBNODE secnode,pub_keyblock=NULL,ctx=NULL; - - while((secnode=walk_kbnode(sec_keyblock,&ctx,0))) - { - KBNODE pubnode; - - if(secnode->pkt->pkttype==PKT_SECRET_KEY || - secnode->pkt->pkttype==PKT_SECRET_SUBKEY) - { - /* Make a public key. We only need to convert enough to - write the keyblock out. */ - - PKT_secret_key *sk=secnode->pkt->pkt.secret_key; - PACKET *pkt=xcalloc (1,sizeof(PACKET)); - PKT_public_key *pk=xcalloc (1,sizeof(PKT_public_key)); - int n; - - if(secnode->pkt->pkttype==PKT_SECRET_KEY) - pkt->pkttype=PKT_PUBLIC_KEY; - else - pkt->pkttype=PKT_PUBLIC_SUBKEY; - - pkt->pkt.public_key=pk; - - pk->version=sk->version; - pk->timestamp=sk->timestamp; - pk->expiredate=sk->expiredate; - pk->pubkey_algo=sk->pubkey_algo; - - n=pubkey_get_npkey(pk->pubkey_algo); - if(n==0) - pk->pkey[0]=mpi_copy(sk->skey[0]); - else - { - int i; - - for(i=0;i<n;i++) - pk->pkey[i]=mpi_copy(sk->skey[i]); - } - - pubnode=new_kbnode(pkt); - } - else - { - pubnode=clone_kbnode(secnode); - } - - if(pub_keyblock==NULL) - pub_keyblock=pubnode; - else - add_kbnode(pub_keyblock,pubnode); - } - - return pub_keyblock; -} - -/**************** - * Ditto for secret keys. Handling is simpler than for public keys. - * We allow secret key importing only when allow is true, this is so - * that a secret key can not be imported accidently and thereby tampering - * with the trust calculation. - */ -static int -import_secret_one( const char *fname, KBNODE keyblock, - struct stats_s *stats, unsigned int options) -{ - PKT_secret_key *sk; - KBNODE node, uidnode; - u32 keyid[2]; - int rc = 0; - - /* get the key and print some info about it */ - node = find_kbnode( keyblock, PKT_SECRET_KEY ); - if( !node ) - BUG(); - - sk = node->pkt->pkt.secret_key; - keyid_from_sk( sk, keyid ); - uidnode = find_next_kbnode( keyblock, PKT_USER_ID ); - - if( opt.verbose ) { - log_info( "sec %4u%c/%08lX %s ", - nbits_from_sk( sk ), - pubkey_letter( sk->pubkey_algo ), - (ulong)keyid[1], datestr_from_sk(sk) ); - if( uidnode ) - print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name, - uidnode->pkt->pkt.user_id->len ); - putc('\n', stderr); - } - stats->secret_read++; - - if( !uidnode ) { - log_error( _("key %08lX: no user ID\n"), (ulong)keyid[1]); - return 0; - } - - if(sk->protect.algo>110) - { - log_error(_("key %08lX: secret key with invalid cipher %d " - "- skipped\n"),(ulong)keyid[1],sk->protect.algo); - return 0; - } - - clear_kbnode_flags( keyblock ); - - /* do we have this key already in one of our secrings ? */ - rc = seckey_available( keyid ); - if( gpg_err_code (rc) == GPG_ERR_NO_SECKEY && !opt.merge_only ) { - /* simply insert this key */ - KEYDB_HANDLE hd = keydb_new (1); - - /* get default resource */ - rc = keydb_locate_writable (hd, NULL); - if (rc) { - log_error (_("no default secret keyring: %s\n"), gpg_strerror (rc)); - keydb_release (hd); - return GPG_ERR_GENERAL; - } - rc = keydb_insert_keyblock (hd, keyblock ); - if (rc) - log_error (_("error writing keyring `%s': %s\n"), - keydb_get_resource_name (hd), gpg_strerror (rc) ); - keydb_release (hd); - /* we are ready */ - if( !opt.quiet ) - log_info( _("key %08lX: secret key imported\n"), (ulong)keyid[1]); - stats->secret_imported++; - if (is_status_enabled ()) - print_import_ok (NULL, sk, 1|16); - - if(options&IMPORT_SK2PK) - { - /* Try and make a public key out of this. */ - - KBNODE pub_keyblock=sec_to_pub_keyblock(keyblock); - import_one(fname,pub_keyblock,stats,opt.import_options); - release_kbnode(pub_keyblock); - } - - } - else if( !rc ) { /* we can't merge secret keys */ - log_error( _("key %08lX: already in secret keyring\n"), - (ulong)keyid[1]); - stats->secret_dups++; - if (is_status_enabled ()) - print_import_ok (NULL, sk, 16); - - /* TODO: if we ever do merge secret keys, make sure to handle - the sec_to_pub_keyblock feature as well. */ - } - else - log_error( _("key %08lX: secret key not found: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - - return rc; -} - - -/**************** - * Import a revocation certificate; this is a single signature packet. - */ -static int -import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats ) -{ - PKT_public_key *pk=NULL; - KBNODE onode, keyblock = NULL; - KEYDB_HANDLE hd = NULL; - u32 keyid[2]; - int rc = 0; - - assert( !node->next ); - assert( node->pkt->pkttype == PKT_SIGNATURE ); - assert( node->pkt->pkt.signature->sig_class == 0x20 ); - - keyid[0] = node->pkt->pkt.signature->keyid[0]; - keyid[1] = node->pkt->pkt.signature->keyid[1]; - - pk = xcalloc (1, sizeof *pk ); - rc = get_pubkey( pk, keyid ); - if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY ) { - log_error ( _("key %08lX: no public key - " - "can't apply revocation certificate\n"), (ulong)keyid[1]); - rc = 0; - goto leave; - } - else if( rc ) { - log_error( _("key %08lX: public key not found: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - goto leave; - } - - /* read the original keyblock */ - hd = keydb_new (0); - { - byte afp[MAX_FINGERPRINT_LEN]; - size_t an; - - fingerprint_from_pk (pk, afp, &an); - while (an < MAX_FINGERPRINT_LEN) - afp[an++] = 0; - rc = keydb_search_fpr (hd, afp); - } - if (rc) { - log_error (_("key %08lX: can't locate original keyblock: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - goto leave; - } - rc = keydb_get_keyblock (hd, &keyblock ); - if (rc) { - log_error (_("key %08lX: can't read original keyblock: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - goto leave; - } - - - /* it is okay, that node is not in keyblock because - * check_key_signature works fine for sig_class 0x20 in this - * special case. */ - rc = check_key_signature( keyblock, node, NULL); - if( rc ) { - log_error( _("key %08lX: invalid revocation certificate" - ": %s - rejected\n"), (ulong)keyid[1], gpg_strerror (rc)); - goto leave; - } - - - /* check whether we already have this */ - for(onode=keyblock->next; onode; onode=onode->next ) { - if( onode->pkt->pkttype == PKT_USER_ID ) - break; - else if( onode->pkt->pkttype == PKT_SIGNATURE - && !cmp_signatures(node->pkt->pkt.signature, - onode->pkt->pkt.signature)) - { - rc = 0; - goto leave; /* yes, we already know about it */ - } - } - - - /* insert it */ - insert_kbnode( keyblock, clone_kbnode(node), 0 ); - - /* and write the keyblock back */ - rc = keydb_update_keyblock (hd, keyblock ); - if (rc) - log_error (_("error writing keyring `%s': %s\n"), - keydb_get_resource_name (hd), gpg_strerror (rc) ); - keydb_release (hd); hd = NULL; - /* we are ready */ - if( !opt.quiet ) { - char *p=get_user_id_printable (keyid); - log_info( _("key %08lX: \"%s\" revocation certificate imported\n"), - (ulong)keyid[1],p); - xfree (p); - } - stats->n_revoc++; - - /* If the key we just revoked was ultimately trusted, remove its - ultimate trust. This doesn't stop the user from putting the - ultimate trust back, but is a reasonable solution for now. */ - if(get_ownertrust(pk)==TRUST_ULTIMATE) - clear_ownertrusts(pk); - - revalidation_mark (); - - leave: - keydb_release (hd); - release_kbnode( keyblock ); - free_public_key( pk ); - return rc; -} - - -/**************** - * loop over the keyblock and check all self signatures. - * Mark all user-ids with a self-signature by setting flag bit 0. - * Mark all user-ids with an invalid self-signature by setting bit 1. - * This works also for subkeys, here the subkey is marked. Invalid or - * extra subkey sigs (binding or revocation) are marked for deletion. - * non_self is set to true if there are any sigs other than self-sigs - * in this keyblock. - */ -static int -chk_self_sigs( const char *fname, KBNODE keyblock, - PKT_public_key *pk, u32 *keyid, int *non_self ) -{ - KBNODE n,knode=NULL; - PKT_signature *sig; - int rc; - u32 bsdate=0,rsdate=0; - KBNODE bsnode=NULL,rsnode=NULL; - - for( n=keyblock; (n = find_next_kbnode(n, 0)); ) { - if(n->pkt->pkttype==PKT_PUBLIC_SUBKEY) - { - knode=n; - bsdate=0; - rsdate=0; - bsnode=NULL; - rsnode=NULL; - continue; - } - else if( n->pkt->pkttype != PKT_SIGNATURE ) - continue; - sig = n->pkt->pkt.signature; - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { - - /* This just caches the sigs for later use. That way we - import a fully-cached key which speeds things up. */ - if(!opt.no_sig_cache) - check_key_signature(keyblock,n,NULL); - - if( (sig->sig_class&~3) == 0x10 ) { - KBNODE unode = find_prev_kbnode( keyblock, n, PKT_USER_ID ); - if( !unode ) { - log_error( _("key %08lX: no user ID for signature\n"), - (ulong)keyid[1]); - return -1; /* the complete keyblock is invalid */ - } - - /* If it hasn't been marked valid yet, keep trying */ - if(!(unode->flag&1)) { - rc = check_key_signature( keyblock, n, NULL); - if( rc ) - { - if (opt.verbose) - { - char *p=utf8_to_native(unode->pkt->pkt.user_id->name, - strlen(unode->pkt->pkt.user_id->name),0); - log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? - _("key %08lX: unsupported public key " - "algorithm on user id \"%s\"\n"): - _("key %08lX: invalid self-signature " - "on user id \"%s\"\n"), - (ulong)keyid[1],p); - xfree (p); - } - } - else - unode->flag |= 1; /* mark that signature checked */ - } - } - else if( sig->sig_class == 0x18 ) { - /* Note that this works based solely on the timestamps - like the rest of gpg. If the standard gets - revocation targets, this may need to be revised. */ - - if( !knode ) - { - if (opt.verbose) - log_info( _("key %08lX: no subkey for subkey " - "binding signature\n"),(ulong)keyid[1]); - n->flag |= 4; /* delete this */ - } - else - { - rc = check_key_signature( keyblock, n, NULL); - if( rc ) - { - if (opt.verbose) - log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? - _("key %08lX: unsupported public key algorithm\n"): - _("key %08lX: invalid subkey binding\n"), - (ulong)keyid[1]); - n->flag|=4; - } - else - { - /* It's valid, so is it newer? */ - if(sig->timestamp>=bsdate) - { - knode->flag |= 1; /* the subkey is valid */ - if(bsnode) - { - bsnode->flag|=4; /* Delete the last binding - sig since this one is - newer */ - if (opt.verbose) - log_info(_("key %08lX: removed multiple " - "subkey binding\n"), - (ulong)keyid[1]); - } - - bsnode=n; - bsdate=sig->timestamp; - } - else - n->flag|=4; /* older */ - } - } - } - else if( sig->sig_class == 0x28 ) { - /* We don't actually mark the subkey as revoked right - now, so just check that the revocation sig is the - most recent valid one. Note that we don't care if - the binding sig is newer than the revocation sig. - See the comment in getkey.c:merge_selfsigs_subkey for - more */ - if( !knode ) { - if (opt.verbose) - log_info( _("key %08lX: no subkey for subkey " - "revocation signature\n"),(ulong)keyid[1]); - n->flag |= 4; /* delete this */ - } - else { - rc = check_key_signature( keyblock, n, NULL); - if( rc ) { - if (opt.verbose) - log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? - _("key %08lX: unsupported public key algorithm\n"): - _("key %08lX: invalid subkey revocation\n"), - (ulong)keyid[1]); - n->flag|=4; - } - else { - /* It's valid, so is it newer? */ - if(sig->timestamp>=rsdate) { - if(rsnode) { - rsnode->flag|=4; /* Delete the last revocation - sig since this one is - newer */ - if (opt.verbose) - log_info(_("key %08lX: removed multiple subkey " - "revocation signatures\n"), - (ulong)keyid[1]); - } - - rsnode=n; - rsdate=sig->timestamp; - } - else - n->flag|=4; /* older */ - } - } - } - } - else - *non_self=1; - } - - return 0; -} - -/**************** - * delete all parts which are invalid and those signatures whose - * public key algorithm is not available in this implemenation; - * but consider RSA as valid, because parse/build_packets knows - * about it. - * returns: true if at least one valid user-id is left over. - */ -static int -delete_inv_parts( const char *fname, KBNODE keyblock, - u32 *keyid, unsigned int options) -{ - KBNODE node; - int nvalid=0, uid_seen=0, subkey_seen=0; - - for(node=keyblock->next; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - uid_seen = 1; - if( (node->flag & 2) || !(node->flag & 1) ) { - if( opt.verbose ) { - log_info( _("key %08lX: skipped user ID '"), - (ulong)keyid[1]); - print_utf8_string( stderr, node->pkt->pkt.user_id->name, - node->pkt->pkt.user_id->len ); - fputs("'\n", stderr ); - } - delete_kbnode( node ); /* the user-id */ - /* and all following packets up to the next user-id */ - while( node->next - && node->next->pkt->pkttype != PKT_USER_ID - && node->next->pkt->pkttype != PKT_PUBLIC_SUBKEY - && node->next->pkt->pkttype != PKT_SECRET_SUBKEY ){ - delete_kbnode( node->next ); - node = node->next; - } - } - else - nvalid++; - } - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - if( (node->flag & 2) || !(node->flag & 1) ) { - if( opt.verbose ) { - log_info( _("key %08lX: skipped subkey\n"), - (ulong)keyid[1]); - } - delete_kbnode( node ); /* the subkey */ - /* and all following signature packets */ - while( node->next - && node->next->pkt->pkttype == PKT_SIGNATURE ) { - delete_kbnode( node->next ); - node = node->next; - } - } - else - subkey_seen = 1; - } - else if( node->pkt->pkttype == PKT_SIGNATURE - && openpgp_pk_test_algo( node->pkt->pkt.signature - ->pubkey_algo, 0) - && node->pkt->pkt.signature->pubkey_algo != PUBKEY_ALGO_RSA ) - delete_kbnode( node ); /* build_packet() can't handle this */ - else if( node->pkt->pkttype == PKT_SIGNATURE && - !node->pkt->pkt.signature->flags.exportable && - !(options&IMPORT_ALLOW_LOCAL_SIGS) && - seckey_available( node->pkt->pkt.signature->keyid ) ) { - /* Here we violate the rfc a bit by still allowing - * to import non-exportable signature when we have the - * the secret key used to create this signature - it - * seems that this makes sense. */ - if (opt.verbose) - log_info( _("key %08lX: non exportable signature " - "(class %02x) - skipped\n"), - (ulong)keyid[1], - node->pkt->pkt.signature->sig_class ); - delete_kbnode( node ); - } - else if( node->pkt->pkttype == PKT_SIGNATURE - && node->pkt->pkt.signature->sig_class == 0x20 ) { - if( uid_seen ) { - if (opt.verbose) - log_error( _("key %08lX: revocation certificate " - "at wrong place - skipped\n"), - (ulong)keyid[1]); - delete_kbnode( node ); - } - else { - /* If the revocation cert is from a different key than - the one we're working on don't check it - it's - probably from a revocation key and won't be - verifiable with this key anyway. */ - - if(node->pkt->pkt.signature->keyid[0]==keyid[0] && - node->pkt->pkt.signature->keyid[1]==keyid[1]) - { - int rc = check_key_signature( keyblock, node, NULL); - if( rc ) - { - if (opt.verbose) - log_info ( _("key %08lX: invalid revocation " - "certificate: %s - skipped\n"), - (ulong)keyid[1], gpg_strerror (rc)); - delete_kbnode( node ); - } - } - } - } - else if( node->pkt->pkttype == PKT_SIGNATURE && - (node->pkt->pkt.signature->sig_class == 0x18 || - node->pkt->pkt.signature->sig_class == 0x28) && - !subkey_seen ) { - if (opt.verbose) - log_info ( _("key %08lX: subkey signature " - "in wrong place - skipped\n"), - (ulong)keyid[1]); - delete_kbnode( node ); - } - else if( node->pkt->pkttype == PKT_SIGNATURE - && !IS_CERT(node->pkt->pkt.signature)) - { - if (opt.verbose) - log_info (_("key %08lX: unexpected signature class (0x%02X) -" - " skipped\n"),(ulong)keyid[1], - node->pkt->pkt.signature->sig_class); - delete_kbnode(node); - } - else if( (node->flag & 4) ) /* marked for deletion */ - delete_kbnode( node ); - } - - /* note: because keyblock is the public key, it is never marked - * for deletion and so keyblock cannot change */ - commit_kbnode( &keyblock ); - return nvalid; -} - - -/**************** - * It may happen that the imported keyblock has duplicated user IDs. - * We check this here and collapse those user IDs together with their - * sigs into one. - * Returns: True if the keyblock hash changed. - */ -int -collapse_uids( KBNODE *keyblock ) -{ - KBNODE n, n2; - int in_uid; - int any=0; - u32 kid1; - - restart: - for( n = *keyblock; n; n = n->next ) { - if( n->pkt->pkttype != PKT_USER_ID ) - continue; - for( n2 = n->next; n2; n2 = n2->next ) { - if( n2->pkt->pkttype == PKT_USER_ID - && !cmp_user_ids( n->pkt->pkt.user_id, - n2->pkt->pkt.user_id ) ) { - /* found a duplicate */ - any = 1; - if( !n2->next - || n2->next->pkt->pkttype == PKT_USER_ID - || n2->next->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n2->next->pkt->pkttype == PKT_SECRET_SUBKEY ) { - /* no more signatures: delete the user ID - * and start over */ - remove_kbnode( keyblock, n2 ); - } - else { - /* The simple approach: Move one signature and - * then start over to delete the next one :-( */ - move_kbnode( keyblock, n2->next, n->next ); - } - goto restart; - } - } - } - if( !any ) - return 0; - - restart_sig: - /* now we may have duplicate signatures on one user ID: fix this */ - for( in_uid = 0, n = *keyblock; n; n = n->next ) { - if( n->pkt->pkttype == PKT_USER_ID ) - in_uid = 1; - else if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n->pkt->pkttype == PKT_SECRET_SUBKEY ) - in_uid = 0; - else if( in_uid ) { - n2 = n; - do { - KBNODE ncmp = NULL; - for( ; n2; n2 = n2->next ) { - if( n2->pkt->pkttype == PKT_USER_ID - || n2->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n2->pkt->pkttype == PKT_SECRET_SUBKEY ) - break; - if( n2->pkt->pkttype != PKT_SIGNATURE ) - ; - else if( !ncmp ) - ncmp = n2; - else if( !cmp_signatures( ncmp->pkt->pkt.signature, - n2->pkt->pkt.signature )) { - remove_kbnode( keyblock, n2 ); - goto restart_sig; - } - } - n2 = ncmp? ncmp->next : NULL; - } while( n2 ); - } - } - - if( (n = find_kbnode( *keyblock, PKT_PUBLIC_KEY )) ) - kid1 = keyid_from_pk( n->pkt->pkt.public_key, NULL ); - else if( (n = find_kbnode( *keyblock, PKT_SECRET_KEY )) ) - kid1 = keyid_from_sk( n->pkt->pkt.secret_key, NULL ); - else - kid1 = 0; - if (!opt.quiet) - log_info (_("key %08lX: duplicated user ID detected - merged\n"), - (ulong)kid1); - - return 1; -} - -/* Check for a 0x20 revocation from a revocation key that is not - present. This gets called without the benefit of merge_xxxx so you - can't rely on pk->revkey and friends. */ -static void -revocation_present(KBNODE keyblock) -{ - KBNODE onode,inode; - PKT_public_key *pk=keyblock->pkt->pkt.public_key; - - for(onode=keyblock->next;onode;onode=onode->next) - { - /* If we reach user IDs, we're done. */ - if(onode->pkt->pkttype==PKT_USER_ID) - break; - - if(onode->pkt->pkttype==PKT_SIGNATURE && - onode->pkt->pkt.signature->sig_class==0x1F && - onode->pkt->pkt.signature->revkey) - { - int idx; - PKT_signature *sig=onode->pkt->pkt.signature; - - for(idx=0;idx<sig->numrevkeys;idx++) - { - u32 keyid[2]; - - keyid_from_fingerprint(sig->revkey[idx]->fpr, - MAX_FINGERPRINT_LEN,keyid); - - for(inode=keyblock->next;inode;inode=inode->next) - { - /* If we reach user IDs, we're done. */ - if(inode->pkt->pkttype==PKT_USER_ID) - break; - - if(inode->pkt->pkttype==PKT_SIGNATURE && - inode->pkt->pkt.signature->sig_class==0x20 && - inode->pkt->pkt.signature->keyid[0]==keyid[0] && - inode->pkt->pkt.signature->keyid[1]==keyid[1]) - { - /* Okay, we have a revocation key, and a - revocation issued by it. Do we have the key - itself? */ - int rc; - - rc=get_pubkey_byfprint_fast (NULL,sig->revkey[idx]->fpr, - MAX_FINGERPRINT_LEN); - if ( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY - || gpg_err_code (rc) == GPG_ERR_UNUSABLE_PUBKEY) - { - /* No, so try and get it */ - if(opt.keyserver_scheme && - opt.keyserver_options.auto_key_retrieve) - { - log_info(_("WARNING: key %08lX may be revoked: " - "fetching revocation key %08lX\n"), - (ulong)keyid_from_pk(pk,NULL), - (ulong)keyid[1]); - keyserver_import_fprint(sig->revkey[idx]->fpr, - MAX_FINGERPRINT_LEN); - - /* Do we have it now? */ - rc=get_pubkey_byfprint_fast (NULL, - sig->revkey[idx]->fpr, - MAX_FINGERPRINT_LEN); - } - - if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY - || gpg_err_code (rc) == GPG_ERR_UNUSABLE_PUBKEY) - log_info(_("WARNING: key %08lX may be revoked: " - "revocation key %08lX not present.\n"), - (ulong)keyid_from_pk(pk,NULL), - (ulong)keyid[1]); - } - } - } - } - } - } -} - -/**************** - * compare and merge the blocks - * - * o compare the signatures: If we already have this signature, check - * that they compare okay; if not, issue a warning and ask the user. - * o Simply add the signature. Can't verify here because we may not have - * the signature's public key yet; verification is done when putting it - * into the trustdb, which is done automagically as soon as this pubkey - * is used. - * Note: We indicate newly inserted packets with flag bit 0 - */ -static int -merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock, - u32 *keyid, int *n_uids, int *n_sigs, int *n_subk ) -{ - KBNODE onode, node; - int rc, found; - - /* 1st: handle revocation certificates */ - for(node=keyblock->next; node; node=node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) - break; - else if( node->pkt->pkttype == PKT_SIGNATURE - && node->pkt->pkt.signature->sig_class == 0x20 ) { - /* check whether we already have this */ - found = 0; - for(onode=keyblock_orig->next; onode; onode=onode->next ) { - if( onode->pkt->pkttype == PKT_USER_ID ) - break; - else if( onode->pkt->pkttype == PKT_SIGNATURE - && onode->pkt->pkt.signature->sig_class == 0x20 - && !cmp_signatures(onode->pkt->pkt.signature, - node->pkt->pkt.signature)) - { - found = 1; - break; - } - } - if( !found ) { - KBNODE n2 = clone_kbnode(node); - insert_kbnode( keyblock_orig, n2, 0 ); - n2->flag |= 1; - ++*n_sigs; - - if (!opt.quiet) - { - char *p=get_user_id_printable (keyid); - log_info(_("key %08lX: \"%s\" " - "revocation certificate added\n"), - (ulong)keyid[1],p); - xfree (p); - } - } - } - } - - /* 2nd: merge in any direct key (0x1F) sigs */ - for(node=keyblock->next; node; node=node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) - break; - else if( node->pkt->pkttype == PKT_SIGNATURE - && node->pkt->pkt.signature->sig_class == 0x1F ) { - /* check whether we already have this */ - found = 0; - for(onode=keyblock_orig->next; onode; onode=onode->next ) { - if( onode->pkt->pkttype == PKT_USER_ID ) - break; - else if( onode->pkt->pkttype == PKT_SIGNATURE - && onode->pkt->pkt.signature->sig_class == 0x1F - && !cmp_signatures(onode->pkt->pkt.signature, - node->pkt->pkt.signature)) { - found = 1; - break; - } - } - if( !found ) { - KBNODE n2 = clone_kbnode(node); - insert_kbnode( keyblock_orig, n2, 0 ); - n2->flag |= 1; - ++*n_sigs; - if (!opt.quiet) - log_info( _("key %08lX: direct key signature added\n"), - (ulong)keyid[1]); - } - } - } - - /* 3rd: try to merge new certificates in */ - for(onode=keyblock_orig->next; onode; onode=onode->next ) { - if( !(onode->flag & 1) && onode->pkt->pkttype == PKT_USER_ID) { - /* find the user id in the imported keyblock */ - for(node=keyblock->next; node; node=node->next ) - if( node->pkt->pkttype == PKT_USER_ID - && !cmp_user_ids( onode->pkt->pkt.user_id, - node->pkt->pkt.user_id ) ) - break; - if( node ) { /* found: merge */ - rc = merge_sigs( onode, node, n_sigs, fname, keyid ); - if( rc ) - return rc; - } - } - } - - /* 4th: add new user-ids */ - for(node=keyblock->next; node; node=node->next ) { - if( node->pkt->pkttype == PKT_USER_ID) { - /* do we have this in the original keyblock */ - for(onode=keyblock_orig->next; onode; onode=onode->next ) - if( onode->pkt->pkttype == PKT_USER_ID - && !cmp_user_ids( onode->pkt->pkt.user_id, - node->pkt->pkt.user_id ) ) - break; - if( !onode ) { /* this is a new user id: append */ - rc = append_uid( keyblock_orig, node, n_sigs, fname, keyid); - if( rc ) - return rc; - ++*n_uids; - } - } - } - - /* 5th: add new subkeys */ - for(node=keyblock->next; node; node=node->next ) { - onode = NULL; - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - /* do we have this in the original keyblock? */ - for(onode=keyblock_orig->next; onode; onode=onode->next ) - if( onode->pkt->pkttype == PKT_PUBLIC_SUBKEY - && !cmp_public_keys( onode->pkt->pkt.public_key, - node->pkt->pkt.public_key ) ) - break; - if( !onode ) { /* this is a new subkey: append */ - rc = append_key( keyblock_orig, node, n_sigs, fname, keyid); - if( rc ) - return rc; - ++*n_subk; - } - } - else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - /* do we have this in the original keyblock? */ - for(onode=keyblock_orig->next; onode; onode=onode->next ) - if( onode->pkt->pkttype == PKT_SECRET_SUBKEY - && !cmp_secret_keys( onode->pkt->pkt.secret_key, - node->pkt->pkt.secret_key ) ) - break; - if( !onode ) { /* this is a new subkey: append */ - rc = append_key( keyblock_orig, node, n_sigs, fname, keyid); - if( rc ) - return rc; - ++*n_subk; - } - } - } - - /* 6th: merge subkey certificates */ - for(onode=keyblock_orig->next; onode; onode=onode->next ) { - if( !(onode->flag & 1) - && ( onode->pkt->pkttype == PKT_PUBLIC_SUBKEY - || onode->pkt->pkttype == PKT_SECRET_SUBKEY) ) { - /* find the subkey in the imported keyblock */ - for(node=keyblock->next; node; node=node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - && !cmp_public_keys( onode->pkt->pkt.public_key, - node->pkt->pkt.public_key ) ) - break; - else if( node->pkt->pkttype == PKT_SECRET_SUBKEY - && !cmp_secret_keys( onode->pkt->pkt.secret_key, - node->pkt->pkt.secret_key ) ) - break; - } - if( node ) { /* found: merge */ - rc = merge_keysigs( onode, node, n_sigs, fname, keyid ); - if( rc ) - return rc; - } - } - } - - - return 0; -} - - -/**************** - * append the userid starting with NODE and all signatures to KEYBLOCK. - */ -static int -append_uid( KBNODE keyblock, KBNODE node, int *n_sigs, - const char *fname, u32 *keyid ) -{ - KBNODE n, n_where=NULL; - - assert(node->pkt->pkttype == PKT_USER_ID ); - - /* find the position */ - for( n = keyblock; n; n_where = n, n = n->next ) { - if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n->pkt->pkttype == PKT_SECRET_SUBKEY ) - break; - } - if( !n ) - n_where = NULL; - - /* and append/insert */ - while( node ) { - /* we add a clone to the original keyblock, because this - * one is released first */ - n = clone_kbnode(node); - if( n_where ) { - insert_kbnode( n_where, n, 0 ); - n_where = n; - } - else - add_kbnode( keyblock, n ); - n->flag |= 1; - node->flag |= 1; - if( n->pkt->pkttype == PKT_SIGNATURE ) - ++*n_sigs; - - node = node->next; - if( node && node->pkt->pkttype != PKT_SIGNATURE ) - break; - } - - return 0; -} - - -/**************** - * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_USER_ID. - * (how should we handle comment packets here?) - */ -static int -merge_sigs( KBNODE dst, KBNODE src, int *n_sigs, - const char *fname, u32 *keyid ) -{ - KBNODE n, n2; - int found=0; - - assert(dst->pkt->pkttype == PKT_USER_ID ); - assert(src->pkt->pkttype == PKT_USER_ID ); - - for(n=src->next; n && n->pkt->pkttype != PKT_USER_ID; n = n->next ) { - if( n->pkt->pkttype != PKT_SIGNATURE ) - continue; - if( n->pkt->pkt.signature->sig_class == 0x18 - || n->pkt->pkt.signature->sig_class == 0x28 ) - continue; /* skip signatures which are only valid on subkeys */ - found = 0; - for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next) - if(!cmp_signatures(n->pkt->pkt.signature,n2->pkt->pkt.signature)) - { - found++; - break; - } - if( !found ) { - /* This signature is new or newer, append N to DST. - * We add a clone to the original keyblock, because this - * one is released first */ - n2 = clone_kbnode(n); - insert_kbnode( dst, n2, PKT_SIGNATURE ); - n2->flag |= 1; - n->flag |= 1; - ++*n_sigs; - } - } - - return 0; -} - -/**************** - * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_xxx_SUBKEY. - */ -static int -merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs, - const char *fname, u32 *keyid ) -{ - KBNODE n, n2; - int found=0; - - assert( dst->pkt->pkttype == PKT_PUBLIC_SUBKEY - || dst->pkt->pkttype == PKT_SECRET_SUBKEY ); - - for(n=src->next; n ; n = n->next ) { - if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n->pkt->pkttype == PKT_PUBLIC_KEY ) - break; - if( n->pkt->pkttype != PKT_SIGNATURE ) - continue; - found = 0; - for(n2=dst->next; n2; n2 = n2->next){ - if( n2->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n2->pkt->pkttype == PKT_PUBLIC_KEY ) - break; - if( n2->pkt->pkttype == PKT_SIGNATURE - && n->pkt->pkt.signature->keyid[0] - == n2->pkt->pkt.signature->keyid[0] - && n->pkt->pkt.signature->keyid[1] - == n2->pkt->pkt.signature->keyid[1] - && n->pkt->pkt.signature->timestamp - <= n2->pkt->pkt.signature->timestamp - && n->pkt->pkt.signature->sig_class - == n2->pkt->pkt.signature->sig_class ) { - found++; - break; - } - } - if( !found ) { - /* This signature is new or newer, append N to DST. - * We add a clone to the original keyblock, because this - * one is released first */ - n2 = clone_kbnode(n); - insert_kbnode( dst, n2, PKT_SIGNATURE ); - n2->flag |= 1; - n->flag |= 1; - ++*n_sigs; - } - } - - return 0; -} - -/**************** - * append the subkey starting with NODE and all signatures to KEYBLOCK. - * Mark all new and copied packets by setting flag bit 0. - */ -static int -append_key( KBNODE keyblock, KBNODE node, int *n_sigs, - const char *fname, u32 *keyid ) -{ - KBNODE n; - - assert( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ); - - while( node ) { - /* we add a clone to the original keyblock, because this - * one is released first */ - n = clone_kbnode(node); - add_kbnode( keyblock, n ); - n->flag |= 1; - node->flag |= 1; - if( n->pkt->pkttype == PKT_SIGNATURE ) - ++*n_sigs; - - node = node->next; - if( node && node->pkt->pkttype != PKT_SIGNATURE ) - break; - } - - return 0; -} diff --git a/g10/kbnode.c b/g10/kbnode.c deleted file mode 100644 index 58daad871..000000000 --- a/g10/kbnode.c +++ /dev/null @@ -1,401 +0,0 @@ -/* kbnode.c - keyblock node utility functions - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "packet.h" -#include "keydb.h" - -#define USE_UNUSED_NODES 1 - -static KBNODE unused_nodes; - -static KBNODE -alloc_node(void) -{ - KBNODE n; - - n = unused_nodes; - if( n ) - unused_nodes = n->next; - else - n = xmalloc ( sizeof *n ); - n->next = NULL; - n->pkt = NULL; - n->flag = 0; - n->private_flag=0; - n->recno = 0; - return n; -} - -static void -free_node( KBNODE n ) -{ - if( n ) { -#if USE_UNUSED_NODES - n->next = unused_nodes; - unused_nodes = n; -#else - xfree ( n ); -#endif - } -} - - - -KBNODE -new_kbnode( PACKET *pkt ) -{ - KBNODE n = alloc_node(); - n->pkt = pkt; - return n; -} - - -KBNODE -clone_kbnode( KBNODE node ) -{ - KBNODE n = alloc_node(); - - n->pkt = node->pkt; - n->private_flag = node->private_flag | 2; /* mark cloned */ - return n; -} - - -void -release_kbnode( KBNODE n ) -{ - KBNODE n2; - - while( n ) { - n2 = n->next; - if( !is_cloned_kbnode(n) ) { - free_packet( n->pkt ); - xfree ( n->pkt ); - } - free_node( n ); - n = n2; - } -} - - -/**************** - * Delete NODE. - * Note: This only works with walk_kbnode!! - */ -void -delete_kbnode( KBNODE node ) -{ - node->private_flag |= 1; -} - - - -/**************** - * Append NODE to ROOT. ROOT must exist! - */ -void -add_kbnode( KBNODE root, KBNODE node ) -{ - KBNODE n1; - - for(n1=root; n1->next; n1 = n1->next) - ; - n1->next = node; -} - -/**************** - * Insert NODE into the list after root but before a packet which is not of - * type PKTTYPE - * (only if PKTTYPE != 0) - */ -void -insert_kbnode( KBNODE root, KBNODE node, int pkttype ) -{ - if( !pkttype ) { - node->next = root->next; - root->next = node; - } - else { - KBNODE n1; - - for(n1=root; n1->next; n1 = n1->next) - if( pkttype != n1->next->pkt->pkttype ) { - node->next = n1->next; - n1->next = node; - return; - } - /* no such packet, append */ - node->next = NULL; - n1->next = node; - } -} - - -/**************** - * Find the previous node (if PKTTYPE = 0) or the previous node - * with pkttype PKTTYPE in the list starting with ROOT of NODE. - */ -KBNODE -find_prev_kbnode( KBNODE root, KBNODE node, int pkttype ) -{ - KBNODE n1; - - for (n1=NULL; root && root != node; root = root->next ) { - if (!pkttype ||root->pkt->pkttype == pkttype) - n1 = root; - } - return n1; -} - -/**************** - * Ditto, but find the next packet. The behaviour is trivial if - * PKTTYPE is 0 but if it is specified, the next node with a packet - * of this type is returned. The function has some knowledge about - * the valid ordering of packets: e.g. if the next signature packet - * is requested, the function will not return one if it encounters - * a user-id. - */ -KBNODE -find_next_kbnode( KBNODE node, int pkttype ) -{ - for( node=node->next ; node; node = node->next ) { - if( !pkttype ) - return node; - else if( pkttype == PKT_USER_ID - && ( node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_SECRET_KEY ) ) - return NULL; - else if( pkttype == PKT_SIGNATURE - && ( node->pkt->pkttype == PKT_USER_ID - || node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_SECRET_KEY ) ) - return NULL; - else if( node->pkt->pkttype == pkttype ) - return node; - } - return NULL; -} - - -KBNODE -find_kbnode( KBNODE node, int pkttype ) -{ - for( ; node; node = node->next ) { - if( node->pkt->pkttype == pkttype ) - return node; - } - return NULL; -} - - - -/**************** - * Walk through a list of kbnodes. This function returns - * the next kbnode for each call; before using the function the first - * time, the caller must set CONTEXT to NULL (This has simply the effect - * to start with ROOT). - */ -KBNODE -walk_kbnode( KBNODE root, KBNODE *context, int all ) -{ - KBNODE n; - - do { - if( !*context ) { - *context = root; - n = root; - } - else { - n = (*context)->next; - *context = n; - } - } while( !all && n && is_deleted_kbnode(n) ); - - return n; -} - -void -clear_kbnode_flags( KBNODE n ) -{ - for( ; n; n = n->next ) { - n->flag = 0; - } -} - - -/**************** - * Commit changes made to the kblist at ROOT. Note that ROOT my change, - * and it is therefore passed by reference. - * The function has the effect of removing all nodes marked as deleted. - * returns true if any node has been changed - */ -int -commit_kbnode( KBNODE *root ) -{ - KBNODE n, nl; - int changed = 0; - - for( n = *root, nl=NULL; n; n = nl->next ) { - if( is_deleted_kbnode(n) ) { - if( n == *root ) - *root = nl = n->next; - else - nl->next = n->next; - if( !is_cloned_kbnode(n) ) { - free_packet( n->pkt ); - xfree ( n->pkt ); - } - free_node( n ); - changed = 1; - } - else - nl = n; - } - return changed; -} - -void -remove_kbnode( KBNODE *root, KBNODE node ) -{ - KBNODE n, nl; - - for( n = *root, nl=NULL; n; n = nl->next ) { - if( n == node ) { - if( n == *root ) - *root = nl = n->next; - else - nl->next = n->next; - if( !is_cloned_kbnode(n) ) { - free_packet( n->pkt ); - xfree ( n->pkt ); - } - free_node( n ); - } - else - nl = n; - } -} - - -/**************** - * Move NODE behind right after WHERE or to the beginning if WHERE is NULL. - */ -void -move_kbnode( KBNODE *root, KBNODE node, KBNODE where ) -{ - KBNODE tmp, prev; - - if( !root || !*root || !node ) - return; /* sanity check */ - for( prev = *root; prev && prev->next != node; prev = prev->next ) - ; - if( !prev ) - return; /* node is not in the list */ - - if( !where ) { /* move node before root */ - if( node == *root ) /* move to itself */ - return; - prev->next = node->next; - node->next = *root; - *root = node; - return; - } - /* move it after where */ - if( node == where ) - return; - tmp = node->next; - node->next = where->next; - where->next = node; - prev->next = tmp; -} - - - - -void -dump_kbnode( KBNODE node ) -{ - for(; node; node = node->next ) { - const char *s; - switch( node->pkt->pkttype ) { - case 0: s="empty"; break; - case PKT_PUBLIC_KEY: s="public-key"; break; - case PKT_SECRET_KEY: s="secret-key"; break; - case PKT_SECRET_SUBKEY: s= "secret-subkey"; break; - case PKT_PUBKEY_ENC: s="public-enc"; break; - case PKT_SIGNATURE: s="signature"; break; - case PKT_ONEPASS_SIG: s="onepass-sig"; break; - case PKT_USER_ID: s="user-id"; break; - case PKT_PUBLIC_SUBKEY: s="public-subkey"; break; - case PKT_COMMENT: s="comment"; break; - case PKT_RING_TRUST: s="trust"; break; - case PKT_PLAINTEXT: s="plaintext"; break; - case PKT_COMPRESSED: s="compressed"; break; - case PKT_ENCRYPTED: s="encrypted"; break; - case PKT_GPG_CONTROL: s="gpg-control"; break; - default: s="unknown"; break; - } - fprintf(stderr, "node %p %02x/%02x type=%s", - node, node->flag, node->private_flag, s); - if( node->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = node->pkt->pkt.user_id; - fputs(" \"", stderr); - print_string( stderr, uid->name, uid->len, 0 ); - fprintf (stderr, "\" %c%c%c%c\n", - uid->is_expired? 'e':'.', - uid->is_revoked? 'r':'.', - uid->created? 'v':'.', - uid->is_primary? 'p':'.' ); - } - else if( node->pkt->pkttype == PKT_SIGNATURE ) { - fprintf(stderr, " class=%02x keyid=%08lX ts=%lu\n", - node->pkt->pkt.signature->sig_class, - (ulong)node->pkt->pkt.signature->keyid[1], - (ulong)node->pkt->pkt.signature->timestamp); - } - else if( node->pkt->pkttype == PKT_GPG_CONTROL ) { - fprintf(stderr, " ctrl=%d len=%u\n", - node->pkt->pkt.gpg_control->control, - (unsigned int)node->pkt->pkt.gpg_control->datalen); - } - else if( node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - PKT_public_key *pk = node->pkt->pkt.public_key; - fprintf(stderr, " keyid=%08lX a=%d u=%d %c%c%c%c\n", - (ulong)keyid_from_pk( pk, NULL ), - pk->pubkey_algo, pk->pubkey_usage, - pk->has_expired? 'e':'.', - pk->is_revoked? 'r':'.', - pk->is_valid? 'v':'.', - pk->mdc_feature? 'm':'.'); - } - else - fputs("\n", stderr); - } -} diff --git a/g10/keydb.c b/g10/keydb.c deleted file mode 100644 index b64f38cbc..000000000 --- a/g10/keydb.c +++ /dev/null @@ -1,725 +0,0 @@ -/* keydb.c - key database dispatcher - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "gpg.h" -#include "util.h" -#include "options.h" -#include "main.h" /*try_make_homedir ()*/ -#include "packet.h" -#include "keyring.h" -#include "keydb.h" -#include "i18n.h" - -static int active_handles; - -typedef enum { - KEYDB_RESOURCE_TYPE_NONE = 0, - KEYDB_RESOURCE_TYPE_KEYRING -} KeydbResourceType; -#define MAX_KEYDB_RESOURCES 40 - -struct resource_item { - KeydbResourceType type; - union { - KEYRING_HANDLE kr; - } u; - void *token; - int secret; -}; - -static struct resource_item all_resources[MAX_KEYDB_RESOURCES]; -static int used_resources; -static void *primary_keyring=NULL; - -struct keydb_handle { - int locked; - int found; - int current; - int used; /* items in active */ - struct resource_item active[MAX_KEYDB_RESOURCES]; -}; - - -static int lock_all (KEYDB_HANDLE hd); -static void unlock_all (KEYDB_HANDLE hd); - - -/* - * Register a resource (which currently may only be a keyring file). - * The first keyring which is added by this function is - * created if it does not exist. - * Note: this function may be called before secure memory is - * available. - * Flag 1 == force - * Flag 2 == default - */ -int -keydb_add_resource (const char *url, int flags, int secret) -{ - static int any_secret, any_public; - const char *resname = url; - iobuf_t iobuf = NULL; - char *filename = NULL; - int force=(flags&1); - int rc = 0; - KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; - void *token; - - /* Do we have an URL? - * gnupg-ring:filename := this is a plain keyring - * filename := See what is is, but create as plain keyring. - */ - if (strlen (resname) > 11) { - if (!strncmp( resname, "gnupg-ring:", 11) ) { - rt = KEYDB_RESOURCE_TYPE_KEYRING; - resname += 11; - } -#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__) - else if (strchr (resname, ':')) { - log_error ("invalid key resource URL `%s'\n", url ); - rc = GPG_ERR_GENERAL; - goto leave; - } -#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ - } - - if (*resname != DIRSEP_C ) { /* do tilde expansion etc */ - if (strchr(resname, DIRSEP_C) ) - filename = make_filename (resname, NULL); - else - filename = make_filename (opt.homedir, resname, NULL); - } - else - filename = xstrdup (resname); - - if (!force) - force = secret? !any_secret : !any_public; - - /* see whether we can determine the filetype */ - if (rt == KEYDB_RESOURCE_TYPE_NONE) { - FILE *fp = fopen( filename, "rb" ); - - if (fp) { - u32 magic; - - if (fread( &magic, 4, 1, fp) == 1 ) { - if (magic == 0x13579ace || magic == 0xce9a5713) - ; /* GDBM magic - no more support */ - else - rt = KEYDB_RESOURCE_TYPE_KEYRING; - } - else /* maybe empty: assume ring */ - rt = KEYDB_RESOURCE_TYPE_KEYRING; - fclose( fp ); - } - else /* no file yet: create ring */ - rt = KEYDB_RESOURCE_TYPE_KEYRING; - } - - switch (rt) { - case KEYDB_RESOURCE_TYPE_NONE: - log_error ("unknown type of key resource `%s'\n", url ); - rc = GPG_ERR_GENERAL; - goto leave; - - case KEYDB_RESOURCE_TYPE_KEYRING: - if (access(filename, F_OK)) - { /* file does not exist */ - mode_t oldmask; - char *last_slash_in_filename; - - if (!force) - { - rc = gpg_error_from_errno (errno); - goto leave; - } - - last_slash_in_filename = strrchr (filename, DIRSEP_C); - *last_slash_in_filename = 0; - if (access(filename, F_OK)) - { /* On the first time we try to create the default - homedir and check again. */ - static int tried; - - if (!tried) - { - tried = 1; - try_make_homedir (filename); - } - if (access (filename, F_OK)) - { - rc = gpg_error_from_errno (errno); - *last_slash_in_filename = DIRSEP_C; - goto leave; - } - } - *last_slash_in_filename = DIRSEP_C; - - oldmask=umask(077); - iobuf = iobuf_create (filename); - umask(oldmask); - if (!iobuf) - { - log_error ( _("error creating keyring `%s': %s\n"), - filename, strerror(errno)); - rc = gpg_error_from_errno (errno); - goto leave; - } - - if (!opt.quiet) - log_info (_("keyring `%s' created\n"), filename); - iobuf_close (iobuf); - iobuf = NULL; - /* must invalidate that ugly cache */ - iobuf_ioctl (NULL, 2, 0, (char*)filename); - } /* end file creation */ - - if(keyring_register_filename (filename, secret, &token)) - { - if (used_resources >= MAX_KEYDB_RESOURCES) - rc = GPG_ERR_RESOURCE_LIMIT; - else - { - if(flags&2) - primary_keyring=token; - all_resources[used_resources].type = rt; - all_resources[used_resources].u.kr = NULL; /* Not used here */ - all_resources[used_resources].token = token; - all_resources[used_resources].secret = secret; - used_resources++; - } - } - else - { - /* This keyring was already registered, so ignore it. - However, we can still mark it as primary even if it was - already registered. */ - if(flags&2) - primary_keyring=token; - } - break; - - default: - log_error ("resource type of `%s' not supported\n", url); - rc = GPG_ERR_GENERAL; - goto leave; - } - - /* fixme: check directory permissions and print a warning */ - - leave: - if (rc) - log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror (rc)); - else if (secret) - any_secret = 1; - else - any_public = 1; - xfree (filename); - return rc; -} - - - - -KEYDB_HANDLE -keydb_new (int secret) -{ - KEYDB_HANDLE hd; - int i, j; - - hd = xcalloc (1,sizeof *hd); - hd->found = -1; - - assert (used_resources <= MAX_KEYDB_RESOURCES); - for (i=j=0; i < used_resources; i++) - { - if (!all_resources[i].secret != !secret) - continue; - switch (all_resources[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - hd->active[j].type = all_resources[i].type; - hd->active[j].token = all_resources[i].token; - hd->active[j].secret = all_resources[i].secret; - hd->active[j].u.kr = keyring_new (all_resources[i].token, secret); - if (!hd->active[j].u.kr) { - xfree (hd); - return NULL; /* fixme: release all previously allocated handles*/ - } - j++; - break; - } - } - hd->used = j; - - active_handles++; - return hd; -} - -void -keydb_release (KEYDB_HANDLE hd) -{ - int i; - - if (!hd) - return; - assert (active_handles > 0); - active_handles--; - - unlock_all (hd); - for (i=0; i < hd->used; i++) { - switch (hd->active[i].type) { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - keyring_release (hd->active[i].u.kr); - break; - } - } - - xfree (hd); -} - - -/* - * Return the name of the current resource. This is function first - * looks for the last found found, then for the current search - * position, and last returns the first available resource. The - * returned string is only valid as long as the handle exists. This - * function does only return NULL if no handle is specified, in all - * other error cases an empty string is returned. - */ -const char * -keydb_get_resource_name (KEYDB_HANDLE hd) -{ - int idx; - const char *s = NULL; - - if (!hd) - return NULL; - - if ( hd->found >= 0 && hd->found < hd->used) - idx = hd->found; - else if ( hd->current >= 0 && hd->current < hd->used) - idx = hd->current; - else - idx = 0; - - switch (hd->active[idx].type) { - case KEYDB_RESOURCE_TYPE_NONE: - s = NULL; - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - s = keyring_get_resource_name (hd->active[idx].u.kr); - break; - } - - return s? s: ""; -} - - - -static int -lock_all (KEYDB_HANDLE hd) -{ - int i, rc = 0; - - for (i=0; !rc && i < hd->used; i++) { - switch (hd->active[i].type) { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_lock (hd->active[i].u.kr, 1); - break; - } - } - - if (rc) { - /* revert the already set locks */ - for (i--; i >= 0; i--) { - switch (hd->active[i].type) { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - keyring_lock (hd->active[i].u.kr, 0); - break; - } - } - } - else - hd->locked = 1; - - return rc; -} - -static void -unlock_all (KEYDB_HANDLE hd) -{ - int i; - - if (!hd->locked) - return; - - for (i=hd->used-1; i >= 0; i--) { - switch (hd->active[i].type) { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - keyring_lock (hd->active[i].u.kr, 0); - break; - } - } - hd->locked = 0; -} - - -/* - * Return the last found keyring. Caller must free it. - * The returned keyblock has the kbode flag bit 0 set for the node with - * the public key used to locate the keyblock or flag bit 1 set for - * the user ID node. - */ -int -keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) -{ - int rc = 0; - - if (!hd) - return GPG_ERR_INV_ARG; - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - switch (hd->active[hd->found].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = GPG_ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb); - break; - } - - return rc; -} - -/* - * update the current keyblock with KB - */ -int -keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb) -{ - int rc = 0; - - if (!hd) - return GPG_ERR_INV_ARG; - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - if( opt.dry_run ) - return 0; - - rc = lock_all (hd); - if (rc) - return rc; - - switch (hd->active[hd->found].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = GPG_ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb); - break; - } - - unlock_all (hd); - return rc; -} - - -/* - * Insert a new KB into one of the resources. - */ -int -keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb) -{ - int rc = -1; - int idx; - - if (!hd) - return GPG_ERR_INV_ARG; - - if( opt.dry_run ) - return 0; - - if ( hd->found >= 0 && hd->found < hd->used) - idx = hd->found; - else if ( hd->current >= 0 && hd->current < hd->used) - idx = hd->current; - else - return GPG_ERR_GENERAL; - - rc = lock_all (hd); - if (rc) - return rc; - - switch (hd->active[idx].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = GPG_ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb); - break; - } - - unlock_all (hd); - return rc; -} - - -/* - * The current keyblock will be deleted. - */ -int -keydb_delete_keyblock (KEYDB_HANDLE hd) -{ - int rc = -1; - - if (!hd) - return GPG_ERR_INV_ARG; - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - if( opt.dry_run ) - return 0; - - rc = lock_all (hd); - if (rc) - return rc; - - switch (hd->active[hd->found].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = GPG_ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_delete_keyblock (hd->active[hd->found].u.kr); - break; - } - - unlock_all (hd); - return rc; -} - - -/* - * Locate the default writable key resource, so that the next - * operation (which is only relevant for inserts) will be done on this - * resource. - */ -int -keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) -{ - int rc; - - if (!hd) - return GPG_ERR_INV_ARG; - - rc = keydb_search_reset (hd); /* this does reset hd->current */ - if (rc) - return rc; - - /* If we have a primary set, try that one first */ - if(primary_keyring) - { - for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) - { - if(hd->active[hd->current].token==primary_keyring) - { - if(keyring_is_writable (hd->active[hd->current].token)) - return 0; - else - break; - } - } - - rc = keydb_search_reset (hd); /* this does reset hd->current */ - if (rc) - return rc; - } - - for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) - { - switch (hd->active[hd->current].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - BUG(); - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - if (keyring_is_writable (hd->active[hd->current].token)) - return 0; /* found (hd->current is set to it) */ - break; - } - } - - return -1; -} - -/* - * Rebuild the caches of all key resources. - */ -void -keydb_rebuild_caches (void) -{ - int i, rc; - - for (i=0; i < used_resources; i++) - { - if (all_resources[i].secret) - continue; - switch (all_resources[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_rebuild_cache (all_resources[i].token); - if (rc) - log_error (_("failed to rebuild keyring cache: %s\n"), - gpg_strerror (rc)); - break; - } - } -} - - - -/* - * Start the next search on this handle right at the beginning - */ -int -keydb_search_reset (KEYDB_HANDLE hd) -{ - int i, rc = 0; - - if (!hd) - return GPG_ERR_INV_ARG; - - hd->current = 0; - hd->found = -1; - /* and reset all resources */ - for (i=0; !rc && i < hd->used; i++) { - switch (hd->active[i].type) { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_search_reset (hd->active[i].u.kr); - break; - } - } - return rc; -} - - -/* - * Search through all keydb resources, starting at the current position, - * for a keyblock which contains one of the keys described in the DESC array. - */ -int -keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, - size_t ndesc, size_t *descindex) -{ - int rc = -1; - - if (!hd) - return GPG_ERR_INV_ARG; - - while (rc == -1 && hd->current >= 0 && hd->current < hd->used) { - switch (hd->active[hd->current].type) { - case KEYDB_RESOURCE_TYPE_NONE: - BUG(); /* we should never see it here */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_search (hd->active[hd->current].u.kr, desc, - ndesc, descindex); - break; - } - if (rc == -1) /* EOF -> switch to next resource */ - hd->current++; - else if (!rc) - hd->found = hd->current; - } - - return rc; -} - -int -keydb_search_first (KEYDB_HANDLE hd) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FIRST; - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_next (KEYDB_HANDLE hd) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_NEXT; - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_kid (KEYDB_HANDLE hd, u32 *kid) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_LONG_KID; - desc.u.kid[0] = kid[0]; - desc.u.kid[1] = kid[1]; - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FPR; - memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN); - return keydb_search (hd, &desc, 1); -} diff --git a/g10/keydb.h b/g10/keydb.h deleted file mode 100644 index 4920e88a1..000000000 --- a/g10/keydb.h +++ /dev/null @@ -1,283 +0,0 @@ -/* keydb.h - Key database - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_KEYDB_H -#define G10_KEYDB_H - -#include "types.h" -#include "global.h" -#include "packet.h" -#include "cipher.h" - -/* What qualifies as a certification (rather than a signature?) */ -#define IS_CERT(s) (IS_KEY_SIG(s) || IS_UID_SIG(s) || IS_SUBKEY_SIG(s) \ - || IS_KEY_REV(s) || IS_UID_REV(s) || IS_SUBKEY_REV(s)) -#define IS_SIG(s) (!IS_CERT(s)) -#define IS_KEY_SIG(s) ((s)->sig_class == 0x1f) -#define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10) -#define IS_SUBKEY_SIG(s) ((s)->sig_class == 0x18) -#define IS_KEY_REV(s) ((s)->sig_class == 0x20) -#define IS_UID_REV(s) ((s)->sig_class == 0x30) -#define IS_SUBKEY_REV(s) ((s)->sig_class == 0x28) - -struct getkey_ctx_s; -typedef struct getkey_ctx_s *GETKEY_CTX; - -/**************** - * A Keyblock is all packets which form an entire certificate; - * i.e. the public key, certificate, trust packets, user ids, - * signatures, and subkey. - * - * This structure is also used to bind arbitrary packets together. - */ - -struct kbnode_struct { - KBNODE next; - PACKET *pkt; - int flag; - int private_flag; - ulong recno; /* used while updating the trustdb */ -}; - -#define is_deleted_kbnode(a) ((a)->private_flag & 1) -#define is_cloned_kbnode(a) ((a)->private_flag & 2) - - -enum resource_type { - rt_UNKNOWN = 0, - rt_RING = 1 -}; - - -/**************** - * A data structre to hold information about the external position - * of a keyblock. - */ -struct keyblock_pos_struct { - int resno; /* resource number */ - enum resource_type rt; - off_t offset; /* position information */ - unsigned count; /* length of the keyblock in packets */ - iobuf_t fp; /* used by enum_keyblocks */ - int secret; /* working on a secret keyring */ - PACKET *pkt; /* ditto */ - int valid; -}; -typedef struct keyblock_pos_struct KBPOS; - -/* structure to hold a couple of public key certificates */ -typedef struct pk_list *PK_LIST; -struct pk_list { - PK_LIST next; - PKT_public_key *pk; - int flags; /* flag bit 1==throw_keyid */ -}; - -/* structure to hold a couple of secret key certificates */ -typedef struct sk_list *SK_LIST; -struct sk_list { - SK_LIST next; - PKT_secret_key *sk; - int mark; /* not used */ -}; - -/* structure to collect all information which can be used to - * identify a public key */ -typedef struct pubkey_find_info *PUBKEY_FIND_INFO; -struct pubkey_find_info { - u32 keyid[2]; - unsigned nbits; - byte pubkey_algo; - byte fingerprint[MAX_FINGERPRINT_LEN]; - char userid[1]; -}; - - -typedef struct keydb_handle *KEYDB_HANDLE; - -typedef enum { - KEYDB_SEARCH_MODE_NONE, - KEYDB_SEARCH_MODE_EXACT, - KEYDB_SEARCH_MODE_SUBSTR, - KEYDB_SEARCH_MODE_MAIL, - KEYDB_SEARCH_MODE_MAILSUB, - KEYDB_SEARCH_MODE_MAILEND, - KEYDB_SEARCH_MODE_WORDS, - KEYDB_SEARCH_MODE_SHORT_KID, - KEYDB_SEARCH_MODE_LONG_KID, - KEYDB_SEARCH_MODE_FPR16, - KEYDB_SEARCH_MODE_FPR20, - KEYDB_SEARCH_MODE_FPR, - KEYDB_SEARCH_MODE_FIRST, - KEYDB_SEARCH_MODE_NEXT -} KeydbSearchMode; - -struct keydb_search_desc { - KeydbSearchMode mode; - int (*skipfnc)(void *,u32*); - void *skipfncvalue; - union { - const char *name; - char fpr[MAX_FINGERPRINT_LEN]; - u32 kid[2]; - } u; - int exact; -}; - -/*-- keydb.c --*/ - -/* - Flag 1 == force - Flag 2 == default -*/ -int keydb_add_resource (const char *url, int flags, int secret); -KEYDB_HANDLE keydb_new (int secret); -void keydb_release (KEYDB_HANDLE hd); -const char *keydb_get_resource_name (KEYDB_HANDLE hd); -int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb); -int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb); -int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb); -int keydb_delete_keyblock (KEYDB_HANDLE hd); -int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved); -void keydb_rebuild_caches (void); -int keydb_search_reset (KEYDB_HANDLE hd); -#define keydb_search(a,b,c) keydb_search2((a),(b),(c),NULL) -int keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, - size_t ndesc, size_t *descindex); -int keydb_search_first (KEYDB_HANDLE hd); -int keydb_search_next (KEYDB_HANDLE hd); -int keydb_search_kid (KEYDB_HANDLE hd, u32 *kid); -int keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr); - - -/*-- pkclist.c --*/ -void show_revocation_reason( PKT_public_key *pk, int mode ); -int check_signatures_trust( PKT_signature *sig ); -void release_pk_list( PK_LIST pk_list ); -int build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ); -int algo_available( preftype_t preftype, int algo, void *hint ); -int select_algo_from_prefs( PK_LIST pk_list, int preftype, - int request, void *hint ); -int select_mdc_from_pklist (PK_LIST pk_list); - -/*-- skclist.c --*/ -void release_sk_list( SK_LIST sk_list ); -int build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, - int unlock, unsigned use ); - -/*-- passphrase.h --*/ -int have_static_passphrase(void); -void read_passphrase_from_fd( int fd ); -void passphrase_clear_cache ( u32 *keyid, int algo ); -DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, - const char *tryagain_text, int *canceled); -void set_next_passphrase( const char *s ); -char *get_last_passphrase(void); - -/*-- getkey.c --*/ -int classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc); -void cache_public_key( PKT_public_key *pk ); -void getkey_disable_caches(void); -int get_pubkey( PKT_public_key *pk, u32 *keyid ); -int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid ); -KBNODE get_pubkeyblock( u32 *keyid ); -int get_pubkey_byname( PKT_public_key *pk, const char *name, - KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd, - int include_disabled ); -int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk, - STRLIST names, KBNODE *ret_keyblock ); -int get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock ); -void get_pubkey_end( GETKEY_CTX ctx ); -int get_seckey( PKT_secret_key *sk, u32 *keyid ); -int get_primary_seckey( PKT_secret_key *sk, u32 *keyid ); -int get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint, - size_t fprint_len ); -int get_pubkey_byfprint_fast (PKT_public_key *pk, - const byte *fprint, size_t fprint_len); -int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint, - size_t fprint_len ); -int get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid ); -int seckey_available( u32 *keyid ); -int get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock ); -int get_seckey_bynames( GETKEY_CTX *rx, PKT_secret_key *sk, - STRLIST names, KBNODE *ret_keyblock ); -int get_seckey_byfprint( PKT_secret_key *sk, - const byte *fprint, size_t fprint_len); -int get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock ); -void get_seckey_end( GETKEY_CTX ctx ); -int enum_secret_keys( void **context, PKT_secret_key *sk, - int with_subkeys, int with_spm ); -void merge_keys_and_selfsig( KBNODE keyblock ); -char*get_user_id_string( u32 *keyid ); -char*get_user_id_string_printable( u32 *keyid ); -char*get_long_user_id_string( u32 *keyid ); -char*get_user_id( u32 *keyid, size_t *rn ); -char*get_user_id_printable( u32 *keyid ); -KEYDB_HANDLE get_ctx_handle(GETKEY_CTX ctx); - -/*-- keyid.c --*/ -int pubkey_letter( int algo ); -u32 v3_keyid (gcry_mpi_t a, u32 *ki); -u32 keyid_from_sk( PKT_secret_key *sk, u32 *keyid ); -u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid ); -u32 keyid_from_sig( PKT_signature *sig, u32 *keyid ); -u32 keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid ); -byte *namehash_from_uid(PKT_user_id *uid); -unsigned nbits_from_pk( PKT_public_key *pk ); -unsigned nbits_from_sk( PKT_secret_key *sk ); -const char *datestr_from_pk( PKT_public_key *pk ); -const char *datestr_from_sk( PKT_secret_key *sk ); -const char *datestr_from_sig( PKT_signature *sig ); -const char *expirestr_from_pk( PKT_public_key *pk ); -const char *expirestr_from_sk( PKT_secret_key *sk ); -const char *expirestr_from_sig( PKT_signature *sig ); - -const char *colon_strtime (u32 t); -const char *colon_datestr_from_pk (PKT_public_key *pk); -const char *colon_datestr_from_sk (PKT_secret_key *sk); -const char *colon_datestr_from_sig (PKT_signature *sig); -const char *colon_expirestr_from_sig (PKT_signature *sig); - -byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf, size_t *ret_len ); -byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len ); - -char *serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen, - PKT_secret_key *sk); - - -/*-- kbnode.c --*/ -KBNODE new_kbnode( PACKET *pkt ); -KBNODE clone_kbnode( KBNODE node ); -void release_kbnode( KBNODE n ); -void delete_kbnode( KBNODE node ); -void add_kbnode( KBNODE root, KBNODE node ); -void insert_kbnode( KBNODE root, KBNODE node, int pkttype ); -void move_kbnode( KBNODE *root, KBNODE node, KBNODE where ); -void remove_kbnode( KBNODE *root, KBNODE node ); -KBNODE find_prev_kbnode( KBNODE root, KBNODE node, int pkttype ); -KBNODE find_next_kbnode( KBNODE node, int pkttype ); -KBNODE find_kbnode( KBNODE node, int pkttype ); -KBNODE walk_kbnode( KBNODE root, KBNODE *context, int all ); -void clear_kbnode_flags( KBNODE n ); -int commit_kbnode( KBNODE *root ); -void dump_kbnode( KBNODE node ); - -#endif /*G10_KEYDB_H*/ diff --git a/g10/keyedit.c b/g10/keyedit.c deleted file mode 100644 index 4da174e3c..000000000 --- a/g10/keyedit.c +++ /dev/null @@ -1,3856 +0,0 @@ -/* keyedit.c - keyedit stuff - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <ctype.h> - -#include "gpg.h" -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "photoid.h" -#include "util.h" -#include "main.h" -#include "trustdb.h" -#include "filter.h" -#include "ttyio.h" -#include "status.h" -#include "i18n.h" - -static void show_prefs( PKT_user_id *uid, int verbose ); -static void show_key_with_all_names( KBNODE keyblock, int only_marked, - int with_revoker, int with_fpr, int with_subkeys, int with_prefs ); -static void show_key_and_fingerprint( KBNODE keyblock ); -static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock, int photo ); -static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int menu_delsig( KBNODE pub_keyblock ); -static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int menu_addrevoker( KBNODE pub_keyblock, - KBNODE sec_keyblock, int sensitive ); -static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int menu_select_uid( KBNODE keyblock, int idx ); -static int menu_select_key( KBNODE keyblock, int idx ); -static int count_uids( KBNODE keyblock ); -static int count_uids_with_flag( KBNODE keyblock, unsigned flag ); -static int count_keys_with_flag( KBNODE keyblock, unsigned flag ); -static int count_selected_uids( KBNODE keyblock ); -static int real_uids_left( KBNODE keyblock ); -static int count_selected_keys( KBNODE keyblock ); -static int menu_revsig( KBNODE keyblock ); -static int menu_revuid( KBNODE keyblock, KBNODE sec_keyblock ); -static int menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int enable_disable_key( KBNODE keyblock, int disable ); -static void menu_showphoto( KBNODE keyblock ); - -static int update_trust=0; - -#define CONTROL_D ('D' - 'A' + 1) - -#define NODFLG_BADSIG (1<<0) /* bad signature */ -#define NODFLG_NOKEY (1<<1) /* no public key */ -#define NODFLG_SIGERR (1<<2) /* other sig error */ - -#define NODFLG_MARK_A (1<<4) /* temporary mark */ -#define NODFLG_DELSIG (1<<5) /* to be deleted */ - -#define NODFLG_SELUID (1<<8) /* indicate the selected userid */ -#define NODFLG_SELKEY (1<<9) /* indicate the selected key */ -#define NODFLG_SELSIG (1<<10) /* indicate a selected signature */ - -struct sign_attrib { - int non_exportable,non_revocable; - struct revocation_reason_info *reason; - byte trust_depth,trust_value; - char *trust_regexp; -}; - -/**************** - * Print information about a signature, check it and return true - * if the signature is okay. NODE must be a signature packet. - */ -static int -print_and_check_one_sig( KBNODE keyblock, KBNODE node, - int *inv_sigs, int *no_key, int *oth_err, - int *is_selfsig, int print_without_key ) -{ - PKT_signature *sig = node->pkt->pkt.signature; - int rc, sigrc; - int is_rev = sig->sig_class == 0x30; - - /* TODO: Make sure a cached sig record here still has the pk that - issued it. See also keylist.c:list_keyblock_print */ - - rc = check_key_signature (keyblock, node, is_selfsig); - switch ( gpg_err_code (rc) ) { - case 0: - node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR); - sigrc = '!'; - break; - case GPG_ERR_BAD_SIGNATURE: - node->flag = NODFLG_BADSIG; - sigrc = '-'; - if( inv_sigs ) - ++*inv_sigs; - break; - case GPG_ERR_NO_PUBKEY: - case GPG_ERR_UNUSABLE_PUBKEY: - node->flag = NODFLG_NOKEY; - sigrc = '?'; - if( no_key ) - ++*no_key; - break; - default: - node->flag = NODFLG_SIGERR; - sigrc = '%'; - if( oth_err ) - ++*oth_err; - break; - } - if( sigrc != '?' || print_without_key ) { - tty_printf("%s%c%c %c%c%c%c%c%c ", - is_rev? "rev":"sig",sigrc, - (sig->sig_class-0x10>0 && - sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ', - sig->flags.exportable?' ':'L', - sig->flags.revocable?' ':'R', - sig->flags.policy_url?'P':' ', - sig->flags.notation?'N':' ', - sig->flags.expired?'X':' ', - (sig->trust_depth>9)?'T': - (sig->trust_depth>0)?'0'+sig->trust_depth:' '); - if(opt.list_options&LIST_SHOW_LONG_KEYID) - tty_printf("%08lX%08lX",(ulong)sig->keyid[0],(ulong)sig->keyid[1]); - else - tty_printf("%08lX",(ulong)sig->keyid[1]); - tty_printf(" %s", datestr_from_sig(sig)); - if(opt.list_options&LIST_SHOW_SIG_EXPIRE) - tty_printf(" %s",expirestr_from_sig(sig)); - tty_printf(" "); - if( sigrc == '%' ) - tty_printf("[%s] ", gpg_strerror (rc) ); - else if( sigrc == '?' ) - ; - else if( *is_selfsig ) { - tty_printf( is_rev? _("[revocation]") - : _("[self-signature]") ); - } - else { - size_t n; - char *p = get_user_id( sig->keyid, &n ); - tty_print_utf8_string2( p, n, 40 ); - xfree (p); - } - tty_printf("\n"); - - if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY)) - show_policy_url(sig,3,0); - - if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION)) - show_notation(sig,3,0); - - if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER)) - show_keyserver_url(sig,3,0); - } - - return (sigrc == '!'); -} - - - -/**************** - * Check the keysigs and set the flags to indicate errors. - * Returns true if error found. - */ -static int -check_all_keysigs( KBNODE keyblock, int only_selected ) -{ - KBNODE kbctx; - KBNODE node; - int inv_sigs = 0; - int no_key = 0; - int oth_err = 0; - int has_selfsig = 0; - int mis_selfsig = 0; - int selected = !only_selected; - int anyuid = 0; - - for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = node->pkt->pkt.user_id; - - if( only_selected ) - selected = (node->flag & NODFLG_SELUID); - if( selected ) { - tty_printf("uid "); - tty_print_utf8_string( uid->name, uid->len ); - tty_printf("\n"); - if( anyuid && !has_selfsig ) - mis_selfsig++; - has_selfsig = 0; - anyuid = 1; - } - } - else if( selected && node->pkt->pkttype == PKT_SIGNATURE - && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10 - || node->pkt->pkt.signature->sig_class == 0x30 ) ) { - int selfsig; - - if( print_and_check_one_sig( keyblock, node, &inv_sigs, - &no_key, &oth_err, &selfsig, 0 ) ) { - if( selfsig ) - has_selfsig = 1; - } - /* Hmmm: should we update the trustdb here? */ - } - } - if( !has_selfsig ) - mis_selfsig++; - if( inv_sigs == 1 ) - tty_printf(_("1 bad signature\n") ); - else if( inv_sigs ) - tty_printf(_("%d bad signatures\n"), inv_sigs ); - if( no_key == 1 ) - tty_printf(_("1 signature not checked due to a missing key\n") ); - else if( no_key ) - tty_printf(_("%d signatures not checked due to missing keys\n"), no_key ); - if( oth_err == 1 ) - tty_printf(_("1 signature not checked due to an error\n") ); - else if( oth_err ) - tty_printf(_("%d signatures not checked due to errors\n"), oth_err ); - if( mis_selfsig == 1 ) - tty_printf(_("1 user ID without valid self-signature detected\n")); - else if( mis_selfsig ) - tty_printf(_("%d user IDs without valid self-signatures detected\n"), - mis_selfsig); - - return inv_sigs || no_key || oth_err || mis_selfsig; -} - - - - -static int -sign_mk_attrib( PKT_signature *sig, void *opaque ) -{ - struct sign_attrib *attrib = opaque; - byte buf[8]; - - if( attrib->non_exportable ) { - buf[0] = 0; /* not exportable */ - build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 ); - } - - if( attrib->non_revocable ) { - buf[0] = 0; /* not revocable */ - build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 ); - } - - if( attrib->reason ) - revocation_reason_build_cb( sig, attrib->reason ); - - if(attrib->trust_depth) - { - /* Not critical. If someone doesn't understand trust sigs, - this can still be a valid regular signature. */ - buf[0] = attrib->trust_depth; - buf[1] = attrib->trust_value; - build_sig_subpkt(sig,SIGSUBPKT_TRUST,buf,2); - - /* Critical. If someone doesn't understands regexps, this - whole sig should be invalid. Note the +1 for the length - - regexps are null terminated. */ - if(attrib->trust_regexp) - build_sig_subpkt(sig,SIGSUBPKT_FLAG_CRITICAL|SIGSUBPKT_REGEXP, - attrib->trust_regexp, - strlen(attrib->trust_regexp)+1); - } - - return 0; -} - -static void -trustsig_prompt(byte *trust_value, byte *trust_depth, char **regexp) -{ - char *p; - - *trust_value=0; - *trust_depth=0; - *regexp=NULL; - - tty_printf("\n"); - /* Same string as pkclist.c:do_edit_ownertrust */ - 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")); - tty_printf (_(" (%d) I trust marginally\n"), 1); - tty_printf (_(" (%d) I trust fully\n"), 2); - tty_printf("\n"); - - while(*trust_value==0) - { - p = cpr_get("trustsig_prompt.trust_value",_("Your selection? ")); - trim_spaces(p); - cpr_kill_prompt(); - /* 60 and 120 are as per RFC2440 */ - if(p[0]=='1' && !p[1]) - *trust_value=60; - else if(p[0]=='2' && !p[1]) - *trust_value=120; - xfree (p); - } - - tty_printf("\n"); - - tty_printf(_( - "Please enter the depth of this trust signature.\n" - "A depth greater than 1 allows the key you are signing to make\n" - "trust signatures on your behalf.\n")); - tty_printf("\n"); - - while(*trust_depth==0) - { - p = cpr_get("trustsig_prompt.trust_depth",_("Your selection? ")); - trim_spaces(p); - cpr_kill_prompt(); - *trust_depth=atoi(p); - xfree (p); - if(*trust_depth < 1 ) - *trust_depth=0; - } - - tty_printf("\n"); - - tty_printf(_("Please enter a domain to restrict this signature, " - "or enter for none.\n")); - - tty_printf("\n"); - - p=cpr_get("trustsig_prompt.trust_regexp",_("Your selection? ")); - trim_spaces(p); - cpr_kill_prompt(); - - if(strlen(p)>0) - { - char *q=p; - int regexplen=100,ind; - - *regexp=xmalloc (regexplen); - - /* Now mangle the domain the user entered into a regexp. To do - this, \-escape everything that isn't alphanumeric, and attach - "<[^>]+[@.]" to the front, and ">$" to the end. */ - - strcpy(*regexp,"<[^>]+[@.]"); - ind=strlen(*regexp); - - while(*q) - { - if(!((*q>='A' && *q<='Z') - || (*q>='a' && *q<='z') || (*q>='0' && *q<='9'))) - (*regexp)[ind++]='\\'; - - (*regexp)[ind++]=*q; - - if((regexplen-ind)<3) - { - regexplen+=100; - *regexp=xrealloc(*regexp,regexplen); - } - - q++; - } - - (*regexp)[ind]='\0'; - strcat(*regexp,">$"); - } - - xfree (p); - tty_printf("\n"); -} - -/**************** - * Loop over all locusr and and sign the uids after asking. - * If no user id is marked, all user ids will be signed; - * if some user_ids are marked those will be signed. - */ -static int -sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, - int local, int nonrevocable, int trust ) -{ - int rc = 0; - SK_LIST sk_list = NULL; - SK_LIST sk_rover = NULL; - PKT_secret_key *sk = NULL; - KBNODE node, uidnode; - PKT_public_key *primary_pk=NULL; - int select_all = !count_selected_uids(keyblock); - int all_v3=1; - - /* Are there any non-v3 sigs on this key already? */ - if(PGP2) - for(node=keyblock;node;node=node->next) - if(node->pkt->pkttype==PKT_SIGNATURE && - node->pkt->pkt.signature->version>3) - { - all_v3=0; - break; - } - - /* build a list of all signators. - * - * We use the CERT flag to request the primary which must always - * be one which is capable of signing keys. I can't see a reason - * why to sign keys using a subkey. Implementation of USAGE_CERT - * is just a hack in getkey.c and does not mean that a subkey - * marked as certification capable will be used */ - rc=build_sk_list( locusr, &sk_list, 0, PUBKEY_USAGE_SIG|PUBKEY_USAGE_CERT); - if( rc ) - goto leave; - - /* loop over all signators */ - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - u32 sk_keyid[2],pk_keyid[2]; - size_t n; - char *p,*trust_regexp=NULL; - int force_v4=0,class=0,selfsig=0; - u32 duration=0,timestamp=0; - byte trust_depth=0,trust_value=0; - - if(local || nonrevocable || trust || - opt.cert_policy_url || opt.cert_notation_data) - force_v4=1; - - /* we have to use a copy of the sk, because make_keysig_packet - * may remove the protection from sk and if we did other - * changes to the secret key, we would save the unprotected - * version */ - if( sk ) - free_secret_key(sk); - sk = copy_secret_key( NULL, sk_rover->sk ); - keyid_from_sk( sk, sk_keyid ); - /* set mark A for all selected user ids */ - for( node=keyblock; node; node = node->next ) { - if( select_all || (node->flag & NODFLG_SELUID) ) - node->flag |= NODFLG_MARK_A; - else - node->flag &= ~NODFLG_MARK_A; - } - /* reset mark for uids which are already signed */ - uidnode = NULL; - for( node=keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - primary_pk=node->pkt->pkt.public_key; - keyid_from_pk( primary_pk, pk_keyid ); - - /* Is this a self-sig? */ - if(pk_keyid[0]==sk_keyid[0] && pk_keyid[1]==sk_keyid[1]) - { - selfsig=1; - /* Do not force a v4 sig here, otherwise it would - be difficult to remake a v3 selfsig. If this - is a v3->v4 promotion case, then we set - force_v4 later anyway. */ - force_v4=0; - } - } - else if( node->pkt->pkttype == PKT_USER_ID ) { - uidnode = (node->flag & NODFLG_MARK_A)? node : NULL; - if(uidnode) - { - char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name, - uidnode->pkt->pkt.user_id->len, - 0); - - if(uidnode->pkt->pkt.user_id->is_revoked) - { - tty_printf(_("User ID \"%s\" is revoked."),user); - - if(opt.expert) - { - tty_printf("\n"); - /* No, so remove the mark and continue */ - if(!cpr_get_answer_is_yes("sign_uid.revoke_okay", - _("Are you sure you " - "still want to sign " - "it? (y/N) "))) - uidnode->flag &= ~NODFLG_MARK_A; - } - else - { - uidnode->flag &= ~NODFLG_MARK_A; - tty_printf(_(" Unable to sign.\n")); - } - } - else if(uidnode->pkt->pkt.user_id->is_expired) - { - tty_printf(_("User ID \"%s\" is expired."),user); - - if(opt.expert) - { - tty_printf("\n"); - /* No, so remove the mark and continue */ - if(!cpr_get_answer_is_yes("sign_uid.expire_okay", - _("Are you sure you " - "still want to sign " - "it? (y/N) "))) - uidnode->flag &= ~NODFLG_MARK_A; - } - else - { - uidnode->flag &= ~NODFLG_MARK_A; - tty_printf(_(" Unable to sign.\n")); - } - } - else if(!uidnode->pkt->pkt.user_id->created && !selfsig) - { - tty_printf(_("User ID \"%s\" is not self-signed."), - user); - - if(opt.expert) - { - tty_printf("\n"); - /* No, so remove the mark and continue */ - if(!cpr_get_answer_is_yes("sign_uid.nosig_okay", - _("Are you sure you " - "still want to sign " - "it? (y/N) "))) - uidnode->flag &= ~NODFLG_MARK_A; - } - else - { - uidnode->flag &= ~NODFLG_MARK_A; - tty_printf(_(" Unable to sign.\n")); - } - } - xfree (user); - } - } - else if( uidnode && node->pkt->pkttype == PKT_SIGNATURE - && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) { - if( sk_keyid[0] == node->pkt->pkt.signature->keyid[0] - && sk_keyid[1] == node->pkt->pkt.signature->keyid[1] ) { - char buf[50]; - char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name, - uidnode->pkt->pkt.user_id->len, - 0); - - /* It's a v3 self-sig. Make it into a v4 self-sig? */ - if(node->pkt->pkt.signature->version<4 && selfsig) - { - tty_printf(_("The self-signature on \"%s\"\n" - "is a PGP 2.x-style signature.\n"),user); - - /* Note that the regular PGP2 warning below - still applies if there are no v4 sigs on - this key at all. */ - - if(opt.expert) - if(cpr_get_answer_is_yes("sign_uid.v4_promote_okay", - _("Do you want to promote " - "it to an OpenPGP self-" - "signature? (y/N) "))) - { - force_v4=1; - node->flag|=NODFLG_DELSIG; - xfree (user); - continue; - } - } - - /* Is the current signature expired? */ - if(node->pkt->pkt.signature->flags.expired) - { - tty_printf(_("Your current signature on \"%s\"\n" - "has expired.\n"),user); - - if(cpr_get_answer_is_yes("sign_uid.replace_expired_okay", - _("Do you want to issue a " - "new signature to replace " - "the expired one? (y/N) "))) - { - /* Mark these for later deletion. We - don't want to delete them here, just in - case the replacement signature doesn't - happen for some reason. We only delete - these after the replacement is already - in place. */ - - node->flag|=NODFLG_DELSIG; - xfree (user); - continue; - } - } - - if(!node->pkt->pkt.signature->flags.exportable && !local) - { - /* It's a local sig, and we want to make a - exportable sig. */ - tty_printf(_("Your current signature on \"%s\"\n" - "is a local signature.\n"),user); - - if(cpr_get_answer_is_yes("sign_uid.local_promote_okay", - _("Do you want to promote " - "it to a full exportable " - "signature? (y/N) "))) - { - /* Mark these for later deletion. We - don't want to delete them here, just in - case the replacement signature doesn't - happen for some reason. We only delete - these after the replacement is already - in place. */ - - node->flag|=NODFLG_DELSIG; - xfree (user); - continue; - } - } - - /* Fixme: see whether there is a revocation in which - * case we should allow to sign it again. */ - if (!node->pkt->pkt.signature->flags.exportable && local) - tty_printf(_( - "\"%s\" was already locally signed by key %08lX\n"), - user,(ulong)sk_keyid[1] ); - else - tty_printf(_( - "\"%s\" was already signed by key %08lX\n"), - user,(ulong)sk_keyid[1] ); - - if(opt.expert - && cpr_get_answer_is_yes("sign_uid.dupe_okay", - _("Do you want to sign it " - "again anyway? (y/N) "))) - { - /* Don't delete the old sig here since this is - an --expert thing. */ - xfree (user); - continue; - } - - sprintf (buf, "%08lX%08lX", - (ulong)sk->keyid[0], (ulong)sk->keyid[1] ); - write_status_text (STATUS_ALREADY_SIGNED, buf); - uidnode->flag &= ~NODFLG_MARK_A; /* remove mark */ - - xfree (user); - } - } - } - /* check whether any uids are left for signing */ - if( !count_uids_with_flag(keyblock, NODFLG_MARK_A) ) { - tty_printf(_("Nothing to sign with key %08lX\n"), - (ulong)sk_keyid[1] ); - continue; - } - /* Ask whether we really should sign these user id(s) */ - tty_printf("\n"); - show_key_with_all_names( keyblock, 1, 0, 1, 0, 0 ); - tty_printf("\n"); - - if(primary_pk->expiredate && !selfsig) - { - u32 now=make_timestamp(); - - if(primary_pk->expiredate<=now) - { - tty_printf(_("This key has expired!")); - - if(opt.expert) - { - tty_printf(" "); - if(!cpr_get_answer_is_yes("sign_uid.expired_okay", - _("Are you sure you still " - "want to sign it? (y/N) "))) - continue; - } - else - { - tty_printf(_(" Unable to sign.\n")); - continue; - } - } - else - { - char *answer; - - tty_printf(_("This key is due to expire on %s.\n"), - expirestr_from_pk(primary_pk)); - - answer=cpr_get("sign_uid.expire", - _("Do you want your signature to " - "expire at the same time? (Y/n) ")); - if(answer_is_yes_no_default(answer,1)) - { - /* This fixes the signature timestamp we're going - to make as now. This is so the expiration date - is exactly correct, and not a few seconds off - (due to the time it takes to answer the - questions, enter the passphrase, etc). */ - timestamp=now; - duration=primary_pk->expiredate-now; - force_v4=1; - } - - cpr_kill_prompt(); - xfree (answer); - } - } - - /* Only ask for duration if we haven't already set it to match - the expiration of the pk */ - if(opt.ask_cert_expire && !duration && !selfsig) - duration=ask_expire_interval(1); - - if(duration) - force_v4=1; - - /* Is --pgp2 on, it's a v3 key, all the sigs on the key are - currently v3 and we're about to sign it with a v4 sig? If - so, danger! */ - if(PGP2 && all_v3 && - (sk->version>3 || force_v4) && primary_pk->version<=3) - { - tty_printf(_("You may not make an OpenPGP signature on a " - "PGP 2.x key while in --pgp2 mode.\n")); - tty_printf(_("This would make the key unusable in PGP 2.x.\n")); - - if(opt.expert) - { - if(!cpr_get_answer_is_yes("sign_uid.v4_on_v3_okay", - _("Are you sure you still " - "want to sign it? (y/N) "))) - continue; - - all_v3=0; - } - else - continue; - } - - if(selfsig) - ; - else - { - if(opt.batch) - class=0x10+opt.def_cert_check_level; - else - { - char *answer; - - tty_printf(_("How carefully have you verified the key you are " - "about to sign actually belongs\nto the person " - "named above? If you don't know what to " - "answer, enter \"0\".\n")); - tty_printf("\n"); - tty_printf(_(" (0) I will not answer.%s\n"), - opt.def_cert_check_level==0?" (default)":""); - tty_printf(_(" (1) I have not checked at all.%s\n"), - opt.def_cert_check_level==1?" (default)":""); - tty_printf(_(" (2) I have done casual checking.%s\n"), - opt.def_cert_check_level==2?" (default)":""); - tty_printf(_(" (3) I have done very careful checking.%s\n"), - opt.def_cert_check_level==3?" (default)":""); - tty_printf("\n"); - - while(class==0) - { - answer = cpr_get("sign_uid.class",_("Your selection? " - "(enter '?' for more information): ")); - - if(answer[0]=='\0') - class=0x10+opt.def_cert_check_level; /* Default */ - else if(ascii_strcasecmp(answer,"0")==0) - class=0x10; /* Generic */ - else if(ascii_strcasecmp(answer,"1")==0) - class=0x11; /* Persona */ - else if(ascii_strcasecmp(answer,"2")==0) - class=0x12; /* Casual */ - else if(ascii_strcasecmp(answer,"3")==0) - class=0x13; /* Positive */ - else - tty_printf(_("Invalid selection.\n")); - - xfree (answer); - } - } - - if(trust) - trustsig_prompt(&trust_value,&trust_depth,&trust_regexp); - } - - tty_printf(_("Are you really sure that you want to sign this key\n" - "with your key: \"")); - p = get_user_id( sk_keyid, &n ); - tty_print_utf8_string( p, n ); - xfree (p); p = NULL; - tty_printf("\" (%08lX)\n",(ulong)sk_keyid[1]); - - if(selfsig) - { - tty_printf(_("\nThis will be a self-signature.\n")); - - if( local ) - tty_printf( - _("\nWARNING: the signature will not be marked " - "as non-exportable.\n")); - - if( nonrevocable ) - tty_printf( - _("\nWARNING: the signature will not be marked " - "as non-revocable.\n")); - } - else - { - if( local ) - tty_printf( - _("\nThe signature will be marked as non-exportable.\n")); - - if( nonrevocable ) - tty_printf( - _("\nThe signature will be marked as non-revocable.\n")); - - switch(class) - { - case 0x11: - tty_printf(_("\nI have not checked this key at all.\n")); - break; - - case 0x12: - tty_printf(_("\nI have checked this key casually.\n")); - break; - - case 0x13: - tty_printf(_("\nI have checked this key very carefully.\n")); - break; - } - } - - tty_printf("\n"); - - if( opt.batch && opt.answer_yes ) - ; - else if( !cpr_get_answer_is_yes("sign_uid.okay", _("Really sign? ")) ) - continue; - - /* now we can sign the user ids */ - reloop: /* (must use this, because we are modifing the list) */ - primary_pk = NULL; - for( node=keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) - primary_pk = node->pkt->pkt.public_key; - else if( node->pkt->pkttype == PKT_USER_ID - && (node->flag & NODFLG_MARK_A) ) { - PACKET *pkt; - PKT_signature *sig; - struct sign_attrib attrib; - - assert( primary_pk ); - memset( &attrib, 0, sizeof attrib ); - attrib.non_exportable = local; - attrib.non_revocable = nonrevocable; - attrib.trust_depth = trust_depth; - attrib.trust_value = trust_value; - attrib.trust_regexp = trust_regexp; - node->flag &= ~NODFLG_MARK_A; - - /* we force creation of a v4 signature for local - * signatures, otherwise we would not generate the - * subpacket with v3 keys and the signature becomes - * exportable */ - - if(selfsig) - rc = make_keysig_packet( &sig, primary_pk, - node->pkt->pkt.user_id, - NULL, - sk, - 0x13, 0, force_v4?4:0, 0, 0, - keygen_add_std_prefs, primary_pk); - else - rc = make_keysig_packet( &sig, primary_pk, - node->pkt->pkt.user_id, - NULL, - sk, - class, 0, force_v4?4:0, - timestamp, duration, - sign_mk_attrib, &attrib ); - if( rc ) { - log_error(_("signing failed: %s\n"), gpg_strerror (rc)); - goto leave; - } - - *ret_modified = 1; /* we changed the keyblock */ - update_trust = 1; - - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - insert_kbnode( node, new_kbnode(pkt), PKT_SIGNATURE ); - goto reloop; - } - } - - /* Delete any sigs that got promoted */ - for( node=keyblock; node; node = node->next ) - if( node->flag & NODFLG_DELSIG) - delete_kbnode(node); - } /* end loop over signators */ - - leave: - release_sk_list( sk_list ); - if( sk ) - free_secret_key(sk); - return rc; -} - - - -/**************** - * Change the passphrase of the primary and all secondary keys. - * We use only one passphrase for all keys. - */ -static int -change_passphrase( KBNODE keyblock ) -{ - int rc = 0; - int changed=0; - KBNODE node; - PKT_secret_key *sk; - char *passphrase = NULL; - int no_primary_secrets = 0; - - node = find_kbnode( keyblock, PKT_SECRET_KEY ); - if( !node ) { - log_error("Oops; secret key not found anymore!\n"); - goto leave; - } - sk = node->pkt->pkt.secret_key; - - switch( is_secret_key_protected( sk ) ) { - case -1: - rc = GPG_ERR_PUBKEY_ALGO; - break; - case 0: - tty_printf(_("This key is not protected.\n")); - break; - default: - if( sk->protect.s2k.mode == 1001 ) { - tty_printf(_("Secret parts of primary key are not available.\n")); - no_primary_secrets = 1; - } - else if( sk->protect.s2k.mode == 1002 ) { - tty_printf(_("Secret key is actually stored on a card.\n")); - goto leave; - } - else { - tty_printf(_("Key is protected.\n")); - rc = check_secret_key( sk, 0 ); - if( !rc ) - passphrase = get_last_passphrase(); - } - break; - } - - /* unprotect all subkeys (use the supplied passphrase or ask)*/ - for(node=keyblock; !rc && node; node = node->next ) { - if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *subsk = node->pkt->pkt.secret_key; - set_next_passphrase( passphrase ); - rc = check_secret_key( subsk, 0 ); - if( !rc && !passphrase ) - passphrase = get_last_passphrase(); - } - } - - if( rc ) - tty_printf(_("Can't edit this key: %s\n"), gpg_strerror (rc)); - else { - DEK *dek = NULL; - STRING2KEY *s2k = xmalloc_secure ( sizeof *s2k ); - const char *errtext = NULL; - - tty_printf(_("Enter the new passphrase for this secret key.\n\n") ); - - set_next_passphrase( NULL ); - for(;;) { - s2k->mode = opt.s2k_mode; - s2k->hash_algo = opt.s2k_digest_algo; - dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, - s2k, 2, errtext, NULL); - if( !dek ) { - errtext = N_("passphrase not correctly repeated; try again"); - tty_printf ("%s.\n", _(errtext)); - } - else if( !dek->keylen ) { - rc = 0; - tty_printf(_( "You don't want a passphrase -" - " this is probably a *bad* idea!\n\n")); - if( cpr_get_answer_is_yes("change_passwd.empty.okay", - _("Do you really want to do this? "))) - { - changed++; - break; - } - } - else { /* okay */ - rc = 0; - if( !no_primary_secrets ) { - sk->protect.algo = dek->algo; - sk->protect.s2k = *s2k; - rc = protect_secret_key( sk, dek ); - } - for(node=keyblock; !rc && node; node = node->next ) { - if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *subsk = node->pkt->pkt.secret_key; - subsk->protect.algo = dek->algo; - subsk->protect.s2k = *s2k; - rc = protect_secret_key( subsk, dek ); - } - } - if( rc ) - log_error("protect_secret_key failed: %s\n", gpg_strerror (rc) ); - else - changed++; - break; - } - } - xfree (s2k); - xfree (dek); - } - - leave: - xfree ( passphrase ); - set_next_passphrase( NULL ); - return changed && !rc; -} - - -/**************** - * There are some keys out (due to a bug in gnupg), where the sequence - * of the packets is wrong. This function fixes that. - * Returns: true if the keyblock has been fixed. - * - * Note: This function does not work if there is more than one user ID. - */ -static int -fix_keyblock( KBNODE keyblock ) -{ - KBNODE node, last, subkey; - int fixed=0; - - /* locate key signatures of class 0x10..0x13 behind sub key packets */ - for( subkey=last=NULL, node = keyblock; node; - last=node, node = node->next ) { - switch( node->pkt->pkttype ) { - case PKT_PUBLIC_SUBKEY: - case PKT_SECRET_SUBKEY: - if( !subkey ) - subkey = last; /* actually it is the one before the subkey */ - break; - case PKT_SIGNATURE: - if( subkey ) { - PKT_signature *sig = node->pkt->pkt.signature; - if( sig->sig_class >= 0x10 && sig->sig_class <= 0x13 ) { - log_info(_( - "moving a key signature to the correct place\n")); - last->next = node->next; - node->next = subkey->next; - subkey->next = node; - node = last; - fixed=1; - } - } - break; - default: break; - } - } - - return fixed; -} - -/**************** - * Menu driven key editor. If sign_mode is true semi-automatical signing - * will be performed. commands are ignore in this case - * - * Note: to keep track of some selection we use node->mark MARKBIT_xxxx. - */ - -void -keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, - int sign_mode ) -{ - enum cmdids { cmdNONE = 0, - cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN, - cmdTSIGN, cmdLSIGN, cmdNRSIGN, cmdNRLSIGN, cmdREVSIG, cmdREVKEY, - cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG, cmdSAVE, cmdADDUID, - cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY, cmdADDREVOKER, - cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE, - cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF, cmdUPDPREF, - cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST, - cmdNOP }; - static struct { const char *name; - enum cmdids id; - int need_sk; - int not_with_sk; - int signmode; - const char *desc; - } cmds[] = { - { N_("quit") , cmdQUIT , 0,0,1, N_("quit this menu") }, - { N_("q") , cmdQUIT , 0,0,1, NULL }, - { N_("save") , cmdSAVE , 0,0,1, N_("save and quit") }, - { N_("help") , cmdHELP , 0,0,1, N_("show this help") }, - { "?" , cmdHELP , 0,0,1, NULL }, - { N_("fpr") , cmdFPR , 0,0,1, N_("show fingerprint") }, - { N_("list") , cmdLIST , 0,0,1, N_("list key and user IDs") }, - { N_("l") , cmdLIST , 0,0,1, NULL }, - { N_("uid") , cmdSELUID , 0,0,1, N_("select user ID N") }, - { N_("key") , cmdSELKEY , 0,0,0, N_("select secondary key N") }, - { N_("check") , cmdCHECK , 0,0,1, N_("list signatures") }, - { N_("c") , cmdCHECK , 0,0,1, NULL }, - { N_("sign") , cmdSIGN , 0,1,1, N_("sign the key") }, - { N_("s") , cmdSIGN , 0,1,1, NULL }, - { N_("tsign") , cmdTSIGN , 0,1,1, N_("make a trust signature")}, - { N_("lsign") , cmdLSIGN , 0,1,1, N_("sign the key locally") }, - { N_("nrsign") , cmdNRSIGN , 0,1,1, N_("sign the key non-revocably") }, - { N_("nrlsign") , cmdNRLSIGN , 0,1,1, N_("sign the key locally and non-revocably") }, - { N_("debug") , cmdDEBUG , 0,0,0, NULL }, - { N_("adduid") , cmdADDUID , 1,1,0, N_("add a user ID") }, - { N_("addphoto"), cmdADDPHOTO , 1,1,0, N_("add a photo ID") }, - { N_("deluid") , cmdDELUID , 0,1,0, N_("delete user ID") }, - /* delphoto is really deluid in disguise */ - { N_("delphoto"), cmdDELUID , 0,1,0, NULL }, - { N_("addkey") , cmdADDKEY , 1,1,0, N_("add a secondary key") }, - { N_("delkey") , cmdDELKEY , 0,1,0, N_("delete a secondary key") }, - { N_("addrevoker"),cmdADDREVOKER,1,1,0, N_("add a revocation key") }, - { N_("delsig") , cmdDELSIG , 0,1,0, N_("delete signatures") }, - { N_("expire") , cmdEXPIRE , 1,1,0, N_("change the expire date") }, - { N_("primary") , cmdPRIMARY , 1,1,0, N_("flag user ID as primary")}, - { N_("toggle") , cmdTOGGLE , 1,0,0, N_("toggle between secret " - "and public key listing") }, - { N_("t" ) , cmdTOGGLE , 1,0,0, NULL }, - { N_("pref") , cmdPREF , 0,1,0, - N_("list preferences (expert)")}, - { N_("showpref"), cmdSHOWPREF , 0,1,0, - N_("list preferences (verbose)")}, - { N_("setpref") , cmdSETPREF , 1,1,0, N_("set preference list") }, - { N_("updpref") , cmdUPDPREF , 1,1,0, N_("updated preferences") }, - { N_("keyserver"),cmdPREFKS , 1,1,0, - N_("set preferred keyserver URL")}, - { N_("passwd") , cmdPASSWD , 1,1,0, N_("change the passphrase") }, - { N_("trust") , cmdTRUST , 0,1,0, N_("change the ownertrust") }, - { N_("revsig") , cmdREVSIG , 0,1,0, N_("revoke signatures") }, - { N_("revuid") , cmdREVUID , 1,1,0, N_("revoke a user ID") }, - { N_("revkey") , cmdREVKEY , 1,1,0, N_("revoke a secondary key") }, - { N_("disable") , cmdDISABLEKEY, 0,1,0, N_("disable a key") }, - { N_("enable") , cmdENABLEKEY , 0,1,0, N_("enable a key") }, - { N_("showphoto"),cmdSHOWPHOTO , 0,0,0, N_("show photo ID") }, - - { NULL, cmdNONE } }; - enum cmdids cmd = 0; - int rc = 0; - KBNODE keyblock = NULL; - KEYDB_HANDLE kdbhd = NULL; - KBNODE sec_keyblock = NULL; - KEYDB_HANDLE sec_kdbhd = NULL; - KBNODE cur_keyblock; - char *answer = NULL; - int redisplay = 1; - int modified = 0; - int sec_modified = 0; - int toggle; - int have_commands = !!commands; - - if ( opt.command_fd != -1 ) - ; - else if( opt.batch && !have_commands ) { - log_error(_("can't do that in batchmode\n")); - goto leave; - } - - if( sign_mode ) { - commands = NULL; - append_to_strlist( &commands, sign_mode == 1? "sign": - sign_mode == 2?"lsign": - sign_mode == 3?"nrsign":"nrlsign"); - have_commands = 1; - } - - /* get the public key */ - rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1); - if( rc ) - goto leave; - if( fix_keyblock( keyblock ) ) - modified++; - if( collapse_uids( &keyblock ) ) - modified++; - reorder_keyblock(keyblock); - - if( !sign_mode ) {/* see whether we have a matching secret key */ - PKT_public_key *pk = keyblock->pkt->pkt.public_key; - - sec_kdbhd = keydb_new (1); - { - byte afp[MAX_FINGERPRINT_LEN]; - size_t an; - - fingerprint_from_pk (pk, afp, &an); - while (an < MAX_FINGERPRINT_LEN) - afp[an++] = 0; - rc = keydb_search_fpr (sec_kdbhd, afp); - } - if (!rc) { - rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock); - if (rc) { - log_error (_("error reading secret keyblock `%s': %s\n"), - username, gpg_strerror (rc)); - } - else { - merge_keys_and_selfsig( sec_keyblock ); - if( fix_keyblock( sec_keyblock ) ) - sec_modified++; - } - } - - if (rc) { - sec_keyblock = NULL; - keydb_release (sec_kdbhd); sec_kdbhd = NULL; - rc = 0; - } - } - - if( sec_keyblock ) { - tty_printf(_("Secret key is available.\n")); - } - - toggle = 0; - cur_keyblock = keyblock; - for(;;) { /* main loop */ - int i, arg_number, photo; - const char *arg_string = ""; - char *p; - PKT_public_key *pk=keyblock->pkt->pkt.public_key; - - tty_printf("\n"); - if( redisplay ) { - show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 ); - tty_printf("\n"); - redisplay = 0; - } - do { - xfree (answer); - if( have_commands ) { - if( commands ) { - answer = xstrdup ( commands->d ); - commands = commands->next; - } - else if( opt.batch ) { - answer = xstrdup ("quit"); - } - else - have_commands = 0; - } - if( !have_commands ) { - answer = cpr_get_no_help("keyedit.prompt", _("Command> ")); - cpr_kill_prompt(); - } - trim_spaces(answer); - } while( *answer == '#' ); - - arg_number = 0; /* Yes, here is the init which egcc complains about */ - photo = 0; /* This too */ - if( !*answer ) - cmd = cmdLIST; - else if( *answer == CONTROL_D ) - cmd = cmdQUIT; - else if( digitp( answer ) ) { - cmd = cmdSELUID; - arg_number = atoi(answer); - } - else { - if( (p=strchr(answer,' ')) ) { - *p++ = 0; - trim_spaces(answer); - trim_spaces(p); - arg_number = atoi(p); - arg_string = p; - } - - for(i=0; cmds[i].name; i++ ) { - if( !ascii_strcasecmp( answer, cmds[i].name ) ) - break; - } - if( sign_mode && !cmds[i].signmode ) - cmd = cmdINVCMD; - else if( cmds[i].need_sk && !sec_keyblock ) { - tty_printf(_("Need the secret key to do this.\n")); - cmd = cmdNOP; - } - else if( cmds[i].not_with_sk && sec_keyblock && toggle ) { - tty_printf(_("Please use the command \"toggle\" first.\n")); - cmd = cmdNOP; - } - else - cmd = cmds[i].id; - } - switch( cmd ) { - case cmdHELP: - for(i=0; cmds[i].name; i++ ) { - if( sign_mode && !cmds[i].signmode ) - ; - else if( cmds[i].need_sk && !sec_keyblock ) - ; /* skip if we do not have the secret key */ - else if( cmds[i].desc ) - tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) ); - } - break; - - case cmdLIST: - redisplay = 1; - break; - - case cmdFPR: - show_key_and_fingerprint( keyblock ); - break; - - case cmdSELUID: - if( menu_select_uid( cur_keyblock, arg_number ) ) - redisplay = 1; - break; - - case cmdSELKEY: - if( menu_select_key( cur_keyblock, arg_number ) ) - redisplay = 1; - break; - - case cmdCHECK: - /* we can only do this with the public key becuase the - * check functions can't cope with secret keys and it - * is questionable whether this would make sense at all */ - check_all_keysigs( keyblock, count_selected_uids(keyblock) ); - break; - - case cmdSIGN: /* sign (only the public key) */ - case cmdLSIGN: /* sign (only the public key) */ - case cmdNRSIGN: /* sign (only the public key) */ - case cmdNRLSIGN: /* sign (only the public key) */ - case cmdTSIGN: - if( pk->is_revoked ) - { - tty_printf(_("Key is revoked.")); - - if(opt.expert) - { - tty_printf(" "); - if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay", - _("Are you sure you still want " - "to sign it? (y/N) "))) - break; - } - else - { - tty_printf(_(" Unable to sign.\n")); - break; - } - } - - if( count_uids(keyblock) > 1 && !count_selected_uids(keyblock) ) { - if( !cpr_get_answer_is_yes("keyedit.sign_all.okay", - _("Really sign all user IDs? ")) ) { - tty_printf(_("Hint: Select the user IDs to sign\n")); - break; - } - } - if( !sign_uids( keyblock, locusr, &modified, - (cmd == cmdLSIGN) || (cmd == cmdNRLSIGN), - (cmd == cmdNRSIGN) || (cmd==cmdNRLSIGN), - (cmd == cmdTSIGN)) - && sign_mode ) - goto do_cmd_save; - break; - - case cmdDEBUG: - dump_kbnode( cur_keyblock ); - break; - - case cmdTOGGLE: - toggle = !toggle; - cur_keyblock = toggle? sec_keyblock : keyblock; - redisplay = 1; - break; - - case cmdADDPHOTO: - if (RFC2440 || RFC1991 || PGP2) - { - tty_printf( - _("This command is not allowed while in %s mode.\n"), - RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991"); - break; - } - photo=1; - /* fall through */ - - case cmdADDUID: - if( menu_adduid( keyblock, sec_keyblock, photo ) ) { - redisplay = 1; - sec_modified = modified = 1; - merge_keys_and_selfsig( sec_keyblock ); - merge_keys_and_selfsig( keyblock ); - } - break; - - case cmdDELUID: { - int n1; - - if( !(n1=count_selected_uids(keyblock)) ) - tty_printf(_("You must select at least one user ID.\n")); - else if( real_uids_left(keyblock) < 1 ) - tty_printf(_("You can't delete the last user ID!\n")); - else if( cpr_get_answer_is_yes( - "keyedit.remove.uid.okay", - n1 > 1? _("Really remove all selected user IDs? ") - : _("Really remove this user ID? ") - ) ) { - menu_deluid( keyblock, sec_keyblock ); - redisplay = 1; - modified = 1; - if( sec_keyblock ) - sec_modified = 1; - } - } - break; - - case cmdDELSIG: { - int n1; - - if( !(n1=count_selected_uids(keyblock)) ) - tty_printf(_("You must select at least one user ID.\n")); - else if( menu_delsig( keyblock ) ) { - /* no redisplay here, because it may scroll away some - * status output of delsig */ - modified = 1; - } - } - break; - - case cmdADDKEY: - if( generate_subkeypair( keyblock, sec_keyblock ) ) { - redisplay = 1; - sec_modified = modified = 1; - merge_keys_and_selfsig( sec_keyblock ); - merge_keys_and_selfsig( keyblock ); - } - break; - - - case cmdDELKEY: { - int n1; - - if( !(n1=count_selected_keys( keyblock )) ) - tty_printf(_("You must select at least one key.\n")); - else if( sec_keyblock && !cpr_get_answer_is_yes( - "keyedit.remove.subkey.okay", - n1 > 1? - _("Do you really want to delete the selected keys? "): - _("Do you really want to delete this key? ") - )) - ; - else { - menu_delkey( keyblock, sec_keyblock ); - redisplay = 1; - modified = 1; - if( sec_keyblock ) - sec_modified = 1; - } - } - break; - - case cmdADDREVOKER: - { - int sensitive=0; - - if(arg_string && ascii_strcasecmp(arg_string,"sensitive")==0) - sensitive=1; - if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) { - redisplay = 1; - sec_modified = modified = 1; - merge_keys_and_selfsig( sec_keyblock ); - merge_keys_and_selfsig( keyblock ); - } - } - break; - - case cmdREVUID: { - int n1; - - if( !(n1=count_selected_uids(keyblock)) ) - tty_printf(_("You must select at least one user ID.\n")); - else if( cpr_get_answer_is_yes( - "keyedit.revoke.uid.okay", - n1 > 1? _("Really revoke all selected user IDs? ") - : _("Really revoke this user ID? ") - ) ) { - if(menu_revuid(keyblock,sec_keyblock)) - { - modified=1; - redisplay=1; - } - } - } - break; - - case cmdREVKEY: { - int n1; - - if( !(n1=count_selected_keys( keyblock )) ) - tty_printf(_("You must select at least one key.\n")); - else if( sec_keyblock && !cpr_get_answer_is_yes( - "keyedit.revoke.subkey.okay", - n1 > 1? - _("Do you really want to revoke the selected keys? "): - _("Do you really want to revoke this key? ") - )) - ; - else { - if( menu_revkey( keyblock, sec_keyblock ) ) { - modified = 1; - /*sec_modified = 1;*/ - } - redisplay = 1; - } - } - break; - - case cmdEXPIRE: - if( menu_expire( keyblock, sec_keyblock ) ) { - merge_keys_and_selfsig( sec_keyblock ); - merge_keys_and_selfsig( keyblock ); - sec_modified = 1; - modified = 1; - redisplay = 1; - } - break; - - case cmdPRIMARY: - if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) { - merge_keys_and_selfsig( keyblock ); - modified = 1; - redisplay = 1; - } - break; - - case cmdPASSWD: - if( change_passphrase( sec_keyblock ) ) - sec_modified = 1; - break; - - case cmdTRUST: - show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 ); - tty_printf("\n"); - if( edit_ownertrust( find_kbnode( keyblock, - PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) { - redisplay = 1; - /* No real need to set update_trust here as - edit_ownertrust() calls revalidation_mark() - anyway. */ - update_trust=1; - } - break; - - case cmdPREF: - show_key_with_all_names( keyblock, 0, 0, 0, 0, 1 ); - break; - - case cmdSHOWPREF: - show_key_with_all_names( keyblock, 0, 0, 0, 0, 2 ); - break; - - case cmdSETPREF: - keygen_set_std_prefs ( !*arg_string? "default" : arg_string, 0); - break; - - case cmdUPDPREF: - { - PKT_user_id *temp=keygen_get_std_prefs(); - tty_printf(_("Current preference list:\n")); - show_prefs(temp,1); - xfree (temp); - } - if (cpr_get_answer_is_yes ("keyedit.updpref.okay", - count_selected_uids (keyblock)? - _("Really update the preferences" - " for the selected user IDs? "): - _("Really update the preferences? "))){ - - if ( menu_set_preferences (keyblock, sec_keyblock) ) { - merge_keys_and_selfsig (keyblock); - modified = 1; - redisplay = 1; - } - } - break; - - case cmdPREFKS: - if( menu_set_keyserver_url ( keyblock, sec_keyblock ) ) { - merge_keys_and_selfsig( keyblock ); - modified = 1; - redisplay = 1; - } - break; - - case cmdNOP: - break; - - case cmdREVSIG: - if( menu_revsig( keyblock ) ) { - redisplay = 1; - modified = 1; - } - break; - - case cmdENABLEKEY: - case cmdDISABLEKEY: - if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) { - redisplay = 1; - modified = 1; - } - break; - - case cmdSHOWPHOTO: - menu_showphoto(keyblock); - break; - - case cmdQUIT: - if( have_commands ) - goto leave; - if( !modified && !sec_modified ) - goto leave; - if( !cpr_get_answer_is_yes("keyedit.save.okay", - _("Save changes? ")) ) { - if( cpr_enabled() - || cpr_get_answer_is_yes("keyedit.cancel.okay", - _("Quit without saving? ")) ) - goto leave; - break; - } - /* fall thru */ - case cmdSAVE: - do_cmd_save: - if( modified || sec_modified ) { - if( modified ) { - rc = keydb_update_keyblock (kdbhd, keyblock); - if( rc ) { - log_error(_("update failed: %s\n"), gpg_strerror (rc) ); - break; - } - } - if( sec_modified ) { - rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock ); - if( rc ) { - log_error( _("update secret failed: %s\n"), - gpg_strerror (rc) ); - break; - } - } - } - else - tty_printf(_("Key not changed so no update needed.\n")); - - if( update_trust ) - { - revalidation_mark (); - update_trust=0; - } - goto leave; - - case cmdINVCMD: - default: - tty_printf("\n"); - tty_printf(_("Invalid command (try \"help\")\n")); - break; - } - } /* end main loop */ - - leave: - release_kbnode( keyblock ); - release_kbnode( sec_keyblock ); - keydb_release (kdbhd); - xfree (answer); -} - - -/**************** - * show preferences of a public keyblock. - */ -static void -show_prefs (PKT_user_id *uid, int verbose) -{ - const prefitem_t fake={0,0}; - const prefitem_t *prefs; - int i; - - if( !uid ) - return; - - if( uid->prefs ) - prefs=uid->prefs; - else if(verbose) - prefs=&fake; - else - return; - - if (verbose) { - int any, des_seen=0, sha1_seen=0, uncomp_seen=0; - tty_printf (" "); - tty_printf (_("Cipher: ")); - for(i=any=0; prefs[i].type; i++ ) { - if( prefs[i].type == PREFTYPE_SYM ) { - const char *s = gcry_cipher_algo_name (prefs[i].value); - - if (any) - tty_printf (", "); - any = 1; - /* We don't want to display strings for experimental algos */ - if (s && prefs[i].value < 100 ) - tty_printf ("%s", s ); - else - tty_printf ("[%d]", prefs[i].value); - if (prefs[i].value == CIPHER_ALGO_3DES ) - des_seen = 1; - } - } - if (!des_seen) { - if (any) - tty_printf (", "); - tty_printf ("%s", gcry_cipher_algo_name (CIPHER_ALGO_3DES)); - } - tty_printf ("\n "); - tty_printf (_("Digest: ")); - for(i=any=0; prefs[i].type; i++ ) { - if( prefs[i].type == PREFTYPE_HASH ) { - const char *s = gcry_md_algo_name (prefs[i].value); - - if (any) - tty_printf (", "); - any = 1; - /* We don't want to display strings for experimental algos */ - if (s && prefs[i].value < 100 ) - tty_printf ("%s", s ); - else - tty_printf ("[%d]", prefs[i].value); - if (prefs[i].value == DIGEST_ALGO_SHA1 ) - sha1_seen = 1; - } - } - if (!sha1_seen) { - if (any) - tty_printf (", "); - tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1)); - } - tty_printf ("\n "); - tty_printf (_("Compression: ")); - for(i=any=0; prefs[i].type; i++ ) { - if( prefs[i].type == PREFTYPE_ZIP ) { - const char *s=compress_algo_to_string(prefs[i].value); - - if (any) - tty_printf (", "); - any = 1; - /* We don't want to display strings for experimental algos */ - if (s && prefs[i].value < 100 ) - tty_printf ("%s", s ); - else - tty_printf ("[%d]", prefs[i].value); - if (prefs[i].value == 0 ) - uncomp_seen = 1; - } - } - if (!uncomp_seen) { - if (any) - tty_printf (", "); - else { - tty_printf ("%s",compress_algo_to_string(1)); - tty_printf (", "); - } - tty_printf ("%s",compress_algo_to_string(0)); - } - if(uid->mdc_feature || !uid->ks_modify) - { - tty_printf ("\n "); - tty_printf (_("Features: ")); - any=0; - if(uid->mdc_feature) - { - tty_printf ("MDC"); - any=1; - } - if(!uid->ks_modify) - { - if(any) - tty_printf (", "); - tty_printf (_("Keyserver no-modify")); - } - } - tty_printf("\n"); - } - else { - tty_printf(" "); - for(i=0; prefs[i].type; i++ ) { - tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' : - prefs[i].type == PREFTYPE_HASH ? 'H' : - prefs[i].type == PREFTYPE_ZIP ? 'Z':'?', - prefs[i].value); - } - if (uid->mdc_feature) - tty_printf (" [mdc]"); - if (!uid->ks_modify) - tty_printf (" [no-ks-modify]"); - tty_printf("\n"); - } -} - - -/* This is the version of show_key_with_all_names used when - opt.with_colons is used. It prints all available data in a easy to - parse format and does not translate utf8 */ -static void -show_key_with_all_names_colon (KBNODE keyblock) -{ - KBNODE node; - int i, j, ulti_hack=0; - byte pk_version=0; - PKT_public_key *primary=NULL; - - /* the keys */ - for ( node = keyblock; node; node = node->next ) - { - if (node->pkt->pkttype == PKT_PUBLIC_KEY - || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) - { - PKT_public_key *pk = node->pkt->pkt.public_key; - u32 keyid[2]; - - if (node->pkt->pkttype == PKT_PUBLIC_KEY) - { - pk_version = pk->version; - primary=pk; - } - - keyid_from_pk (pk, keyid); - - fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout); - if (!pk->is_valid) - putchar ('i'); - else if (pk->is_revoked) - putchar ('r'); - else if (pk->has_expired) - putchar ('e'); - else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks )) - { - int trust = get_validity_info (pk, NULL); - if(trust=='u') - ulti_hack=1; - putchar (trust); - } - - printf (":%u:%d:%08lX%08lX:%lu:%lu:", - nbits_from_pk (pk), - pk->pubkey_algo, - (ulong)keyid[0], (ulong)keyid[1], - (ulong)pk->timestamp, - (ulong)pk->expiredate ); - if (pk->local_id) - printf ("%lu", pk->local_id); - putchar (':'); - if (node->pkt->pkttype==PKT_PUBLIC_KEY - && !(opt.fast_list_mode || opt.no_expensive_trust_checks )) - putchar(get_ownertrust_info (pk)); - putchar(':'); - putchar('\n'); - - print_fingerprint (pk, NULL, 0); - - /* print the revoker record */ - if( !pk->revkey && pk->numrevkeys ) - BUG(); - else - { - for (i=0; i < pk->numrevkeys; i++) - { - byte *p; - - printf ("rvk:::%d::::::", pk->revkey[i].algid); - p = pk->revkey[i].fpr; - for (j=0; j < 20; j++, p++ ) - printf ("%02X", *p); - printf (":%02x%s:\n", pk->revkey[i].class, - (pk->revkey[i].class&0x40)?"s":""); - } - } - } - } - - /* the user ids */ - i = 0; - for (node = keyblock; node; node = node->next) - { - if ( node->pkt->pkttype == PKT_USER_ID ) - { - PKT_user_id *uid = node->pkt->pkt.user_id; - - ++i; - - if(uid->attrib_data) - printf("uat:"); - else - printf("uid:"); - - if ( uid->is_revoked ) - printf("r::::::::"); - else if ( uid->is_expired ) - printf("e::::::::"); - else if ( opt.fast_list_mode || opt.no_expensive_trust_checks ) - printf("::::::::"); - else - { - int uid_validity; - - if( primary && !ulti_hack ) - uid_validity = get_validity_info( primary, uid ); - else - uid_validity = 'u'; - printf("%c::::::::",uid_validity); - } - - if(uid->attrib_data) - printf ("%u %lu",uid->numattribs,uid->attrib_len); - else - print_string (stdout, uid->name, uid->len, ':'); - - putchar (':'); - /* signature class */ - putchar (':'); - /* capabilities */ - putchar (':'); - /* preferences */ - if (pk_version>3 || uid->selfsigversion>3) - { - const prefitem_t *prefs = uid->prefs; - - for (j=0; prefs && prefs[j].type; j++) - { - if (j) - putchar (' '); - printf ("%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' : - prefs[j].type == PREFTYPE_HASH ? 'H' : - prefs[j].type == PREFTYPE_ZIP ? 'Z':'?', - prefs[j].value); - } - if (uid->mdc_feature) - printf (",mdc"); - if (!uid->ks_modify) - printf (",no-ks-modify"); - } - putchar (':'); - /* flags */ - printf ("%d,", i); - if (uid->is_primary) - putchar ('p'); - if (uid->is_revoked) - putchar ('r'); - if (uid->is_expired) - putchar ('e'); - if ((node->flag & NODFLG_SELUID)) - putchar ('s'); - if ((node->flag & NODFLG_MARK_A)) - putchar ('m'); - putchar (':'); - putchar('\n'); - } - } -} - - -/**************** - * Display the key a the user ids, if only_marked is true, do only - * so for user ids with mark A flag set and dont display the index number - */ -static void -show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker, - int with_fpr, int with_subkeys, int with_prefs ) -{ - KBNODE node; - int i, rc; - int do_warn = 0; - byte pk_version=0; - PKT_public_key *primary=NULL; - - if (opt.with_colons) - { - show_key_with_all_names_colon (keyblock); - return; - } - - /* the keys */ - for( node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_KEY - || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) { - PKT_public_key *pk = node->pkt->pkt.public_key; - const char *otrust="err",*trust="err"; - - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - /* do it here, so that debug messages don't clutter the - * output */ - static int did_warn = 0; - - trust = get_validity_string (pk, NULL); - otrust = get_ownertrust_string (pk); - - /* Show a warning once */ - if (!did_warn - && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) { - did_warn = 1; - do_warn = 1; - } - - pk_version = pk->version; - primary = pk; - } - - if(with_revoker) { - if( !pk->revkey && pk->numrevkeys ) - BUG(); - else - for(i=0;i<pk->numrevkeys;i++) { - u32 r_keyid[2]; - char *user; - const char *algo= - gcry_pk_algo_name (pk->revkey[i].algid); - - keyid_from_fingerprint(pk->revkey[i].fpr, - MAX_FINGERPRINT_LEN,r_keyid); - - user=get_user_id_string (r_keyid); - tty_printf (_("This key may be revoked by %s key "), - algo?algo:"?"); - tty_print_utf8_string (user, strlen (user)); - if ((pk->revkey[i].class&0x40)) - tty_printf (_(" (sensitive)")); - tty_printf ("\n"); - xfree (user); - } - } - - keyid_from_pk(pk,NULL); - tty_printf("%s%c %4u%c/", - node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub", - (node->flag & NODFLG_SELKEY)? '*':' ', - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo )); - - if(opt.list_options&LIST_SHOW_LONG_KEYID) - tty_printf("%08lX",(ulong)pk->keyid[0]); - - tty_printf("%08lX ",(ulong)pk->keyid[1]); - tty_printf(_("created: %s expires: %s"), - datestr_from_pk(pk), - expirestr_from_pk(pk) ); - tty_printf("\n"); - - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) - { - tty_printf(" "); - if(opt.list_options&LIST_SHOW_LONG_KEYID) - tty_printf(" "); - tty_printf(_("trust: %-13s"), otrust); - tty_printf(_("validity: %s"), trust ); - tty_printf("\n"); - if( node->pkt->pkttype == PKT_PUBLIC_KEY - && (get_ownertrust (pk)&TRUST_FLAG_DISABLED)) - { - tty_printf("*** "); - tty_printf(_("This key has been disabled")); - tty_printf("\n"); - } - } - - if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr ) - { - print_fingerprint ( pk, NULL, 2 ); - tty_printf("\n"); - } - } - else if( node->pkt->pkttype == PKT_SECRET_KEY - || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) ) { - PKT_secret_key *sk = node->pkt->pkt.secret_key; - tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"), - node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb", - (node->flag & NODFLG_SELKEY)? '*':' ', - nbits_from_sk( sk ), - pubkey_letter( sk->pubkey_algo ), - (ulong)keyid_from_sk(sk,NULL), - datestr_from_sk(sk), - expirestr_from_sk(sk) ); - tty_printf("\n"); - } - else if( with_subkeys && node->pkt->pkttype == PKT_SIGNATURE - && node->pkt->pkt.signature->sig_class == 0x28 ) { - PKT_signature *sig = node->pkt->pkt.signature; - - rc = check_key_signature( keyblock, node, NULL ); - if( !rc ) - tty_printf( _("rev! subkey has been revoked: %s\n"), - datestr_from_sig( sig ) ); - else if( gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE ) - tty_printf( _("rev- faked revocation found\n") ); - else if( rc ) - tty_printf( _("rev? problem checking revocation: %s\n"), - gpg_strerror (rc) ); - } - } - /* the user ids */ - i = 0; - for( node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = node->pkt->pkt.user_id; - ++i; - if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A))){ - if(opt.list_options&LIST_SHOW_VALIDITY && primary) - tty_printf("[%8.8s] ", - trust_value_to_string(get_validity(primary,uid))); - if( only_marked ) - tty_printf(" "); - else if( node->flag & NODFLG_SELUID ) - tty_printf("(%d)* ", i); - else if( uid->is_primary ) - tty_printf("(%d). ", i); - else - tty_printf("(%d) ", i); - if ( uid->is_revoked ) - tty_printf (_("[revoked] ")); - if ( uid->is_expired ) - tty_printf (_("[expired] ")); - tty_print_utf8_string( uid->name, uid->len ); - tty_printf("\n"); - if( with_prefs ) - { - if(pk_version>3 || uid->selfsigversion>3) - show_prefs (uid, with_prefs == 2); - else - tty_printf(_("There are no preferences on a " - "PGP 2.x-style user ID.\n")); - } - } - } - } - - if (do_warn) - tty_printf (_("Please note that the shown key validity " - "is not necessarily correct\n" - "unless you restart the program.\n")); - -} - - -/* Display basic key information. This fucntion is suitable to show - information on the key without any dependencies on the trustdb or - any other internal GnuPG stuff. KEYBLOCK may either be a public or - a secret key.*/ -void -show_basic_key_info ( KBNODE keyblock ) -{ - KBNODE node; - int i; - - /* The primary key */ - for (node = keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_PUBLIC_KEY) - { - PKT_public_key *pk = node->pkt->pkt.public_key; - - /* Note, we use the same format string as in other show - functions to make the translation job easier. */ - tty_printf (_("%s%c %4u%c/%08lX created: %s expires: %s"), - node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub", - ' ', - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo ), - (ulong)keyid_from_pk(pk,NULL), - datestr_from_pk(pk), - expirestr_from_pk(pk) ); - tty_printf("\n"); - print_fingerprint ( pk, NULL, 3 ); - tty_printf("\n"); - } - else if (node->pkt->pkttype == PKT_SECRET_KEY) - { - PKT_secret_key *sk = node->pkt->pkt.secret_key; - tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"), - node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb", - ' ', - nbits_from_sk( sk ), - pubkey_letter( sk->pubkey_algo ), - (ulong)keyid_from_sk(sk,NULL), - datestr_from_sk(sk), - expirestr_from_sk(sk) ); - tty_printf("\n"); - print_fingerprint (NULL, sk, 3 ); - tty_printf("\n"); - } - } - - /* The user IDs. */ - for (i=0, node = keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID) - { - PKT_user_id *uid = node->pkt->pkt.user_id; - ++i; - - tty_printf (" "); - if (uid->is_revoked) - tty_printf ("[revoked] "); - if ( uid->is_expired ) - tty_printf ("[expired] "); - tty_print_utf8_string (uid->name, uid->len); - tty_printf ("\n"); - } - } -} - -static void -show_key_and_fingerprint( KBNODE keyblock ) -{ - KBNODE node; - PKT_public_key *pk = NULL; - - for( node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - pk = node->pkt->pkt.public_key; - tty_printf("pub %4u%c/%08lX %s ", - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo ), - (ulong)keyid_from_pk(pk,NULL), - datestr_from_pk(pk) ); - } - else if( node->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = node->pkt->pkt.user_id; - tty_print_utf8_string( uid->name, uid->len ); - break; - } - } - tty_printf("\n"); - if( pk ) - print_fingerprint( pk, NULL, 2 ); -} - - -/* Show a warning if no uids on the key have the primary uid flag - set. */ -static void -no_primary_warning(KBNODE keyblock, int uids) -{ - KBNODE node; - int select_all=1,have_uid=0,uid_count=0; - - if(uids) - select_all=!count_selected_uids(keyblock); - - /* TODO: if we ever start behaving differently with a primary or - non-primary attribute ID, we will need to check for attributes - here as well. */ - - for(node=keyblock; node; node = node->next) - { - if(node->pkt->pkttype==PKT_USER_ID - && node->pkt->pkt.user_id->attrib_data==NULL) - { - uid_count++; - - if((select_all || (node->flag & NODFLG_SELUID)) - && node->pkt->pkt.user_id->is_primary==2) - have_uid|=2; - else - have_uid|=1; - } - } - - if(uid_count>1 && have_uid&1 && !(have_uid&2)) - log_info(_("WARNING: no user ID has been marked as primary. This command " - "may\n cause a different user ID to become the assumed primary.\n")); -} - -/**************** - * Ask for a new user id, do the selfsignature and put it into - * both keyblocks. - * Return true if there is a new user id - */ -static int -menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo) -{ - PKT_user_id *uid; - PKT_public_key *pk=NULL; - PKT_secret_key *sk=NULL; - PKT_signature *sig=NULL; - PACKET *pkt; - KBNODE node; - KBNODE pub_where=NULL, sec_where=NULL; - int rc; - - for( node = pub_keyblock; node; pub_where = node, node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) - pk = node->pkt->pkt.public_key; - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - break; - } - if( !node ) /* no subkey */ - pub_where = NULL; - for( node = sec_keyblock; node; sec_where = node, node = node->next ) { - if( node->pkt->pkttype == PKT_SECRET_KEY ) - sk = copy_secret_key( NULL, node->pkt->pkt.secret_key); - else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) - break; - } - if( !node ) /* no subkey */ - sec_where = NULL; - assert(pk && sk); - - if(photo) { - int hasattrib=0; - - for( node = pub_keyblock; node; node = node->next ) - if( node->pkt->pkttype == PKT_USER_ID && - node->pkt->pkt.user_id->attrib_data!=NULL) - { - hasattrib=1; - break; - } - - /* It is legal but bad for compatibility to add a photo ID to a - v3 key as it means that PGP2 will not be able to use that key - anymore. Also, PGP may not expect a photo on a v3 key. - Don't bother to ask this if the key already has a photo - any - damage has already been done at that point. -dms */ - if(pk->version==3 && !hasattrib) - { - if(opt.expert) - { - tty_printf(_("WARNING: This is a PGP2-style key. " - "Adding a photo ID may cause some versions\n" - " of PGP to reject this key.\n")); - - if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay", - _("Are you sure you still want " - "to add it? (y/N) "))) - return 0; - } - else - { - tty_printf(_("You may not add a photo ID to " - "a PGP2-style key.\n")); - return 0; - } - } - - uid = generate_photo_id(pk); - } else - uid = generate_user_id(); - if( !uid ) - return 0; - - rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0, - keygen_add_std_prefs, pk ); - free_secret_key( sk ); - if( rc ) { - log_error("signing failed: %s\n", gpg_strerror (rc) ); - free_user_id(uid); - return 0; - } - - /* insert/append to secret keyblock */ - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_USER_ID; - pkt->pkt.user_id = scopy_user_id(uid); - node = new_kbnode(pkt); - if( sec_where ) - insert_kbnode( sec_where, node, 0 ); - else - add_kbnode( sec_keyblock, node ); - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = copy_signature(NULL, sig); - if( sec_where ) - insert_kbnode( node, new_kbnode(pkt), 0 ); - else - add_kbnode( sec_keyblock, new_kbnode(pkt) ); - /* insert/append to public keyblock */ - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_USER_ID; - pkt->pkt.user_id = uid; - node = new_kbnode(pkt); - if( pub_where ) - insert_kbnode( pub_where, node, 0 ); - else - add_kbnode( pub_keyblock, node ); - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = copy_signature(NULL, sig); - if( pub_where ) - insert_kbnode( node, new_kbnode(pkt), 0 ); - else - add_kbnode( pub_keyblock, new_kbnode(pkt) ); - return 1; -} - - -/**************** - * Remove all selceted userids from the keyrings - */ -static void -menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - KBNODE node; - int selected=0; - - for( node = pub_keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - selected = node->flag & NODFLG_SELUID; - if( selected ) { - /* Only cause a trust update if we delete a - non-revoked user id */ - if(!node->pkt->pkt.user_id->is_revoked) - update_trust=1; - delete_kbnode( node ); - if( sec_keyblock ) { - KBNODE snode; - int s_selected = 0; - PKT_user_id *uid = node->pkt->pkt.user_id; - for( snode = sec_keyblock; snode; snode = snode->next ) { - if( snode->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *suid = snode->pkt->pkt.user_id; - - s_selected = - (uid->len == suid->len - && !memcmp( uid->name, suid->name, uid->len)); - if( s_selected ) - delete_kbnode( snode ); - } - else if( s_selected - && snode->pkt->pkttype == PKT_SIGNATURE ) - delete_kbnode( snode ); - else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) - s_selected = 0; - } - } - } - } - else if( selected && node->pkt->pkttype == PKT_SIGNATURE ) - delete_kbnode( node ); - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - selected = 0; - } - commit_kbnode( &pub_keyblock ); - if( sec_keyblock ) - commit_kbnode( &sec_keyblock ); -} - - -static int -menu_delsig( KBNODE pub_keyblock ) -{ - KBNODE node; - PKT_user_id *uid = NULL; - int changed=0; - - for( node = pub_keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL; - } - else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) { - int okay, valid, selfsig, inv_sig, no_key, other_err; - - tty_printf("uid "); - tty_print_utf8_string( uid->name, uid->len ); - tty_printf("\n"); - - okay = inv_sig = no_key = other_err = 0; - valid = print_and_check_one_sig( pub_keyblock, node, - &inv_sig, &no_key, &other_err, - &selfsig, 1 ); - - if( valid ) { - okay = cpr_get_answer_yes_no_quit( - "keyedit.delsig.valid", - _("Delete this good signature? (y/N/q)")); - - /* Only update trust if we delete a good signature. - The other two cases do not affect trust. */ - if(okay) - update_trust=1; - } - else if( inv_sig || other_err ) - okay = cpr_get_answer_yes_no_quit( - "keyedit.delsig.invalid", - _("Delete this invalid signature? (y/N/q)")); - else if( no_key ) - okay = cpr_get_answer_yes_no_quit( - "keyedit.delsig.unknown", - _("Delete this unknown signature? (y/N/q)")); - - if( okay == -1 ) - break; - if( okay && selfsig && !cpr_get_answer_is_yes( - "keyedit.delsig.selfsig", - _("Really delete this self-signature? (y/N)") )) - okay = 0; - if( okay ) { - delete_kbnode( node ); - changed++; - } - - } - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - uid = NULL; - } - - if( changed ) { - commit_kbnode( &pub_keyblock ); - tty_printf( changed == 1? _("Deleted %d signature.\n") - : _("Deleted %d signatures.\n"), changed ); - } - else - tty_printf( _("Nothing deleted.\n") ); - - return changed; -} - - -/**************** - * Remove some of the secondary keys - */ -static void -menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - KBNODE node; - int selected=0; - - for( node = pub_keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - selected = node->flag & NODFLG_SELKEY; - if( selected ) { - delete_kbnode( node ); - if( sec_keyblock ) { - KBNODE snode; - int s_selected = 0; - u32 ki[2]; - - keyid_from_pk( node->pkt->pkt.public_key, ki ); - for( snode = sec_keyblock; snode; snode = snode->next ) { - if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) { - u32 ki2[2]; - - keyid_from_sk( snode->pkt->pkt.secret_key, ki2 ); - s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]); - if( s_selected ) - delete_kbnode( snode ); - } - else if( s_selected - && snode->pkt->pkttype == PKT_SIGNATURE ) - delete_kbnode( snode ); - else - s_selected = 0; - } - } - } - } - else if( selected && node->pkt->pkttype == PKT_SIGNATURE ) - delete_kbnode( node ); - else - selected = 0; - } - commit_kbnode( &pub_keyblock ); - if( sec_keyblock ) - commit_kbnode( &sec_keyblock ); - - /* No need to set update_trust here since signing keys are no - longer used to certify other keys, so there is no change in - trust when revoking/removing them */ -} - - -/**************** - * Ask for a new revoker, do the selfsignature and put it into - * both keyblocks. - * Return true if there is a new revoker - */ -static int -menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive ) -{ - PKT_public_key *pk=NULL,*revoker_pk=NULL; - PKT_secret_key *sk=NULL; - PKT_signature *sig=NULL; - PACKET *pkt; - struct revocation_key revkey; - size_t fprlen; - int rc; - - assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY); - assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY); - - pk=pub_keyblock->pkt->pkt.public_key; - - if(pk->numrevkeys==0 && pk->version==3) - { - /* It is legal but bad for compatibility to add a revoker to a - v3 key as it means that PGP2 will not be able to use that key - anymore. Also, PGP may not expect a revoker on a v3 key. - Don't bother to ask this if the key already has a revoker - - any damage has already been done at that point. -dms */ - if(opt.expert) - { - tty_printf(_("WARNING: This is a PGP 2.x-style key. " - "Adding a designated revoker may cause\n" - " some versions of PGP to reject this key.\n")); - - if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay", - _("Are you sure you still want " - "to add it? (y/N) "))) - return 0; - } - else - { - tty_printf(_("You may not add a designated revoker to " - "a PGP 2.x-style key.\n")); - return 0; - } - } - - sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key); - - for(;;) - { - char *answer; - u32 keyid[2]; - char *p; - size_t n; - - if(revoker_pk) - free_public_key(revoker_pk); - - revoker_pk=xcalloc (1,sizeof(*revoker_pk)); - - tty_printf("\n"); - - answer=cpr_get_utf8("keyedit.add_revoker", - _("Enter the user ID of the designated revoker: ")); - if(answer[0]=='\0' || answer[0]=='\004') - { - xfree(answer); answer = NULL; - goto fail; - } - - rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1); - - if(rc) - { - log_error (_("key `%s' not found: %s\n"),answer,gpg_strerror (rc)); - xfree (answer); answer = NULL; - continue; - } - - xfree (answer); answer = NULL; - - - fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen); - if(fprlen!=20) - { - log_error(_("cannot appoint a PGP 2.x style key as a " - "designated revoker\n")); - continue; - } - - revkey.class=0x80; - if(sensitive) - revkey.class|=0x40; - revkey.algid=revoker_pk->pubkey_algo; - - if(cmp_public_keys(revoker_pk,pk)==0) - { - /* This actually causes no harm (after all, a key that - designates itself as a revoker is the same as a - regular key), but it's easy enough to check. */ - log_error(_("you cannot appoint a key as its own " - "designated revoker\n")); - - continue; - } - - keyid_from_pk(pk,NULL); - - /* Does this revkey already exist? */ - if(!pk->revkey && pk->numrevkeys) - BUG(); - else - { - int i; - - for(i=0;i<pk->numrevkeys;i++) - { - if(memcmp(&pk->revkey[i],&revkey, - sizeof(struct revocation_key))==0) - { - char buf[50]; - - log_error(_("this key has already been designated " - "as a revoker\n")); - - sprintf(buf,"%08lX%08lX", - (ulong)pk->keyid[0],(ulong)pk->keyid[1]); - write_status_text(STATUS_ALREADY_SIGNED,buf); - - break; - } - } - - if(i<pk->numrevkeys) - continue; - } - - keyid_from_pk(revoker_pk,keyid); - - tty_printf("\npub %4u%c/%08lX %s ", - nbits_from_pk( revoker_pk ), - pubkey_letter( revoker_pk->pubkey_algo ), - (ulong)keyid[1], datestr_from_pk(pk) ); - - p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ); - xfree (p); - tty_printf("\n"); - print_fingerprint(revoker_pk,NULL,2); - tty_printf("\n"); - - tty_printf(_("WARNING: appointing a key as a designated revoker " - "cannot be undone!\n")); - - tty_printf("\n"); - - if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay", - _("Are you sure you want to appoint this " - "key as a designated revoker? (y/N): "))) - continue; - - free_public_key(revoker_pk); - revoker_pk=NULL; - break; - } - - /* The 1F signature must be at least v4 to carry the revocation key - subpacket. */ - rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0, - keygen_add_revkey,&revkey ); - if( rc ) - { - log_error("signing failed: %s\n", gpg_strerror (rc) ); - goto fail; - } - - free_secret_key(sk); - sk=NULL; - - /* insert into secret keyblock */ - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = copy_signature(NULL, sig); - insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE ); - - /* insert into public keyblock */ - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE ); - - return 1; - - fail: - if(sk) - free_secret_key(sk); - if(sig) - free_seckey_enc(sig); - if(revoker_pk) - free_public_key(revoker_pk); - - return 0; -} - - -static int -menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - int n1, signumber, rc; - u32 expiredate; - int mainkey=0; - PKT_secret_key *sk; /* copy of the main sk */ - PKT_public_key *main_pk, *sub_pk; - PKT_user_id *uid; - KBNODE node; - u32 keyid[2]; - - if( count_selected_keys( sec_keyblock ) ) { - tty_printf(_("Please remove selections from the secret keys.\n")); - return 0; - } - - n1 = count_selected_keys( pub_keyblock ); - if( n1 > 1 ) { - tty_printf(_("Please select at most one secondary key.\n")); - return 0; - } - else if( n1 ) - tty_printf(_("Changing expiration time for a secondary key.\n")); - else { - tty_printf(_("Changing expiration time for the primary key.\n")); - mainkey=1; - } - - no_primary_warning(pub_keyblock,0); - - expiredate = ask_expiredate(); - node = find_kbnode( sec_keyblock, PKT_SECRET_KEY ); - sk = copy_secret_key( NULL, node->pkt->pkt.secret_key); - - /* Now we can actually change the self signature(s) */ - main_pk = sub_pk = NULL; - uid = NULL; - signumber = 0; - for( node=pub_keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - main_pk = node->pkt->pkt.public_key; - keyid_from_pk( main_pk, keyid ); - main_pk->expiredate = expiredate; - } - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - && (node->flag & NODFLG_SELKEY ) ) { - sub_pk = node->pkt->pkt.public_key; - sub_pk->expiredate = expiredate; - } - else if( node->pkt->pkttype == PKT_USER_ID ) - uid = node->pkt->pkt.user_id; - else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE - && ( mainkey || sub_pk ) ) { - PKT_signature *sig = node->pkt->pkt.signature; - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] - && ( (mainkey && uid - && uid->created && (sig->sig_class&~3) == 0x10) - || (!mainkey && sig->sig_class == 0x18) ) ) { - /* this is a selfsignature which is to be replaced */ - PKT_signature *newsig; - PACKET *newpkt; - KBNODE sn; - int signumber2 = 0; - - signumber++; - - if( (mainkey && main_pk->version < 4) - || (!mainkey && sub_pk->version < 4 ) ) { - log_info(_( - "You can't change the expiration date of a v3 key\n")); - free_secret_key( sk ); - return 0; - } - - /* find the corresponding secret self-signature */ - for( sn=sec_keyblock; sn; sn = sn->next ) { - if( sn->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *b = sn->pkt->pkt.signature; - if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1] - && sig->sig_class == b->sig_class - && ++signumber2 == signumber ) - break; - } - } - if( !sn ) - log_info(_("No corresponding signature in secret ring\n")); - - if( mainkey ) - rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL, - sk, keygen_add_key_expire, main_pk); - else - rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk, - sk, keygen_add_key_expire, sub_pk ); - if( rc ) { - log_error("make_keysig_packet failed: %s\n", - gpg_strerror (rc)); - free_secret_key( sk ); - return 0; - } - /* replace the packet */ - newpkt = xcalloc (1, sizeof *newpkt ); - newpkt->pkttype = PKT_SIGNATURE; - newpkt->pkt.signature = newsig; - free_packet( node->pkt ); - xfree ( node->pkt ); - node->pkt = newpkt; - if( sn ) { - newpkt = xcalloc (1, sizeof *newpkt ); - newpkt->pkttype = PKT_SIGNATURE; - newpkt->pkt.signature = copy_signature( NULL, newsig ); - free_packet( sn->pkt ); - xfree ( sn->pkt ); - sn->pkt = newpkt; - } - sub_pk = NULL; - } - } - } - - free_secret_key( sk ); - update_trust=1; - return 1; -} - -static int -change_primary_uid_cb ( PKT_signature *sig, void *opaque ) -{ - byte buf[1]; - - /* first clear all primary uid flags so that we are sure none are - * lingering around */ - delete_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID); - delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID); - - /* if opaque is set,we want to set the primary id */ - if (opaque) { - buf[0] = 1; - build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 ); - } - - return 0; -} - - -/* - * Set the primary uid flag for the selected UID. We will also reset - * all other primary uid flags. For this to work with have to update - * all the signature timestamps. If we would do this with the current - * time, we lose quite a lot of information, so we use a a kludge to - * do this: Just increment the timestamp by one second which is - * sufficient to updated a signature during import. - */ -static int -menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - PKT_secret_key *sk; /* copy of the main sk */ - PKT_public_key *main_pk; - PKT_user_id *uid; - KBNODE node; - u32 keyid[2]; - int selected; - int attribute = 0; - int modified = 0; - - if ( count_selected_uids (pub_keyblock) != 1 ) { - tty_printf(_("Please select exactly one user ID.\n")); - return 0; - } - - node = find_kbnode( sec_keyblock, PKT_SECRET_KEY ); - sk = copy_secret_key( NULL, node->pkt->pkt.secret_key); - - /* Now we can actually change the self signature(s) */ - main_pk = NULL; - uid = NULL; - selected = 0; - - /* Is our selected uid an attribute packet? */ - for ( node=pub_keyblock; node; node = node->next ) - if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID) - attribute = (node->pkt->pkt.user_id->attrib_data!=NULL); - - for ( node=pub_keyblock; node; node = node->next ) { - if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - break; /* ready */ - - if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - main_pk = node->pkt->pkt.public_key; - keyid_from_pk( main_pk, keyid ); - } - else if ( node->pkt->pkttype == PKT_USER_ID ) { - uid = node->pkt->pkt.user_id; - selected = node->flag & NODFLG_SELUID; - } - else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] - && (uid && (sig->sig_class&~3) == 0x10) - && attribute == (uid->attrib_data!=NULL)) { - if(sig->version < 4) { - char *user=utf8_to_native(uid->name,strlen(uid->name),0); - - log_info(_("skipping v3 self-signature on user id \"%s\"\n"), - user); - xfree (user); - } - else { - /* This is a selfsignature which is to be replaced. - We can just ignore v3 signatures because they are - not able to carry the primary ID flag. We also - ignore self-sigs on user IDs that are not of the - same type that we are making primary. That is, if - we are making a user ID primary, we alter user IDs. - If we are making an attribute packet primary, we - alter attribute packets. */ - - /* FIXME: We must make sure that we only have one - self-signature per user ID here (not counting - revocations) */ - PKT_signature *newsig; - PACKET *newpkt; - const byte *p; - int action; - - /* see whether this signature has the primary UID flag */ - p = parse_sig_subpkt (sig->hashed, - SIGSUBPKT_PRIMARY_UID, NULL ); - if ( !p ) - p = parse_sig_subpkt (sig->unhashed, - SIGSUBPKT_PRIMARY_UID, NULL ); - if ( p && *p ) /* yes */ - action = selected? 0 : -1; - else /* no */ - action = selected? 1 : 0; - - if (action) { - int rc = update_keysig_packet (&newsig, sig, - main_pk, uid, NULL, - sk, - change_primary_uid_cb, - action > 0? "x":NULL ); - if( rc ) { - log_error ("update_keysig_packet failed: %s\n", - gpg_strerror (rc)); - free_secret_key( sk ); - return 0; - } - /* replace the packet */ - newpkt = xcalloc (1, sizeof *newpkt ); - newpkt->pkttype = PKT_SIGNATURE; - newpkt->pkt.signature = newsig; - free_packet( node->pkt ); - xfree ( node->pkt ); - node->pkt = newpkt; - modified = 1; - } - } - } - } - } - - free_secret_key( sk ); - return modified; -} - - -/* - * Set preferences to new values for the selected user IDs - */ -static int -menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - PKT_secret_key *sk; /* copy of the main sk */ - PKT_public_key *main_pk; - PKT_user_id *uid; - KBNODE node; - u32 keyid[2]; - int selected, select_all; - int modified = 0; - - no_primary_warning(pub_keyblock,1); - - select_all = !count_selected_uids (pub_keyblock); - - node = find_kbnode( sec_keyblock, PKT_SECRET_KEY ); - sk = copy_secret_key( NULL, node->pkt->pkt.secret_key); - - /* Now we can actually change the self signature(s) */ - main_pk = NULL; - uid = NULL; - selected = 0; - for ( node=pub_keyblock; node; node = node->next ) { - if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - break; /* ready */ - - if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - main_pk = node->pkt->pkt.public_key; - keyid_from_pk( main_pk, keyid ); - } - else if ( node->pkt->pkttype == PKT_USER_ID ) { - uid = node->pkt->pkt.user_id; - selected = select_all || (node->flag & NODFLG_SELUID); - } - else if ( main_pk && uid && selected - && node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] - && (uid && (sig->sig_class&~3) == 0x10) ) { - if( sig->version < 4 ) { - char *user=utf8_to_native(uid->name,strlen(uid->name),0); - - log_info(_("skipping v3 self-signature on user id \"%s\"\n"), - user); - xfree (user); - } - else { - /* This is a selfsignature which is to be replaced - * We have to ignore v3 signatures because they are - * not able to carry the preferences */ - PKT_signature *newsig; - PACKET *newpkt; - int rc; - - rc = update_keysig_packet (&newsig, sig, - main_pk, uid, NULL, - sk, - keygen_upd_std_prefs, - NULL ); - if( rc ) { - log_error ("update_keysig_packet failed: %s\n", - gpg_strerror (rc)); - free_secret_key( sk ); - return 0; - } - /* replace the packet */ - newpkt = xcalloc (1, sizeof *newpkt ); - newpkt->pkttype = PKT_SIGNATURE; - newpkt->pkt.signature = newsig; - free_packet( node->pkt ); - xfree ( node->pkt ); - node->pkt = newpkt; - modified = 1; - } - } - } - } - - free_secret_key( sk ); - return modified; -} - - - -static int -menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - PKT_secret_key *sk; /* copy of the main sk */ - PKT_public_key *main_pk; - PKT_user_id *uid; - KBNODE node; - u32 keyid[2]; - int selected, select_all; - int modified = 0; - char *answer; - - no_primary_warning(pub_keyblock,1); - - answer=cpr_get_utf8("keyedit.add_keyserver", - _("Enter your preferred keyserver URL: ")); - if(answer[0]=='\0' || answer[0]=='\004') - { - xfree(answer); - return 0; - } - - select_all = !count_selected_uids (pub_keyblock); - - node = find_kbnode( sec_keyblock, PKT_SECRET_KEY ); - sk = copy_secret_key( NULL, node->pkt->pkt.secret_key); - - /* Now we can actually change the self signature(s) */ - main_pk = NULL; - uid = NULL; - selected = 0; - for ( node=pub_keyblock; node; node = node->next ) { - if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - break; /* ready */ - - if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - main_pk = node->pkt->pkt.public_key; - keyid_from_pk( main_pk, keyid ); - } - else if ( node->pkt->pkttype == PKT_USER_ID ) { - uid = node->pkt->pkt.user_id; - selected = select_all || (node->flag & NODFLG_SELUID); - } - else if ( main_pk && uid && selected - && node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] - && (uid && (sig->sig_class&~3) == 0x10) ) { - if( sig->version < 4 ) { - char *user=utf8_to_native(uid->name,strlen(uid->name),0); - - log_info(_("skipping v3 self-signature on user id \"%s\"\n"), - user); - xfree(user); - } - else { - /* This is a selfsignature which is to be replaced - * We have to ignore v3 signatures because they are - * not able to carry the preferences */ - PKT_signature *newsig; - PACKET *newpkt; - int rc; - - rc = update_keysig_packet (&newsig, sig, - main_pk, uid, NULL, - sk, - keygen_add_keyserver_url, - answer ); - if( rc ) { - log_error ("update_keysig_packet failed: %s\n", - gpg_strerror (rc)); - xfree(answer); - free_secret_key( sk ); - return 0; - } - /* replace the packet */ - newpkt = xcalloc (1, sizeof *newpkt ); - newpkt->pkttype = PKT_SIGNATURE; - newpkt->pkt.signature = newsig; - free_packet( node->pkt ); - xfree (node->pkt); - node->pkt = newpkt; - modified = 1; - } - } - } - } - - xfree(answer); - free_secret_key( sk ); - return modified; -} - - -/**************** - * Select one user id or remove all selection if index is 0. - * Returns: True if the selection changed; - */ -static int -menu_select_uid( KBNODE keyblock, int idx ) -{ - KBNODE node; - int i; - - /* first check that the index is valid */ - if( idx ) { - for( i=0, node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - if( ++i == idx ) - break; - } - } - if( !node ) { - tty_printf(_("No user ID with index %d\n"), idx ); - return 0; - } - } - else { /* reset all */ - for( i=0, node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) - node->flag &= ~NODFLG_SELUID; - } - return 1; - } - /* and toggle the new index */ - for( i=0, node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - if( ++i == idx ) { - if( (node->flag & NODFLG_SELUID) ) - node->flag &= ~NODFLG_SELUID; - else - node->flag |= NODFLG_SELUID; - } - } - } - - return 1; -} - -/**************** - * Select secondary keys - * Returns: True if the selection changed; - */ -static int -menu_select_key( KBNODE keyblock, int idx ) -{ - KBNODE node; - int i; - - /* first check that the index is valid */ - if( idx ) { - for( i=0, node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - if( ++i == idx ) - break; - } - } - if( !node ) { - tty_printf(_("No secondary key with index %d\n"), idx ); - return 0; - } - } - else { /* reset all */ - for( i=0, node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) - node->flag &= ~NODFLG_SELKEY; - } - return 1; - } - /* and set the new index */ - for( i=0, node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - if( ++i == idx ) { - if( (node->flag & NODFLG_SELKEY) ) - node->flag &= ~NODFLG_SELKEY; - else - node->flag |= NODFLG_SELKEY; - } - } - } - - return 1; -} - - -static int -count_uids_with_flag( KBNODE keyblock, unsigned flag ) -{ - KBNODE node; - int i=0; - - for( node = keyblock; node; node = node->next ) - if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) ) - i++; - return i; -} - -static int -count_keys_with_flag( KBNODE keyblock, unsigned flag ) -{ - KBNODE node; - int i=0; - - for( node = keyblock; node; node = node->next ) - if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY) - && (node->flag & flag) ) - i++; - return i; -} - -static int -count_uids( KBNODE keyblock ) -{ - KBNODE node; - int i=0; - - for( node = keyblock; node; node = node->next ) - if( node->pkt->pkttype == PKT_USER_ID ) - i++; - return i; -} - - -/**************** - * Returns true if there is at least one selected user id - */ -static int -count_selected_uids( KBNODE keyblock ) -{ - return count_uids_with_flag( keyblock, NODFLG_SELUID); -} - -static int -count_selected_keys( KBNODE keyblock ) -{ - return count_keys_with_flag( keyblock, NODFLG_SELKEY); -} - -/* returns how many real (i.e. not attribute) uids are unmarked */ -static int -real_uids_left( KBNODE keyblock ) -{ - KBNODE node; - int real=0; - - for(node=keyblock;node;node=node->next) - if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) && - !node->pkt->pkt.user_id->attrib_data) - real++; - - return real; -} - -/* - * Ask whether the signature should be revoked. If the user commits this, - * flag bit MARK_A is set on the signature and the user ID. - */ -static void -ask_revoke_sig( KBNODE keyblock, KBNODE node ) -{ - int doit=0; - PKT_signature *sig = node->pkt->pkt.signature; - KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID ); - - if( !unode ) { - log_error("Oops: no user ID for signature\n"); - return; - } - - tty_printf(_("user ID: \"")); - tty_print_utf8_string( unode->pkt->pkt.user_id->name, - unode->pkt->pkt.user_id->len ); - - if(sig->flags.exportable) - tty_printf(_("\"\nsigned with your key %08lX at %s\n"), - (ulong)sig->keyid[1], datestr_from_sig(sig) ); - else - tty_printf(_("\"\nlocally signed with your key %08lX at %s\n"), - (ulong)sig->keyid[1], datestr_from_sig(sig) ); - - if(sig->flags.expired) - { - tty_printf(_("This signature expired on %s.\n"), - expirestr_from_sig(sig)); - /* Use a different question so we can have different help text */ - doit=cpr_get_answer_is_yes("ask_revoke_sig.expired", - _("Are you sure you still want to revoke it? (y/N) ")); - } - else - doit=cpr_get_answer_is_yes("ask_revoke_sig.one", - _("Create a revocation certificate for this signature? (y/N) ")); - - if(doit) { - node->flag |= NODFLG_MARK_A; - unode->flag |= NODFLG_MARK_A; - } -} - -/**************** - * Display all user ids of the current public key together with signatures - * done by one of our keys. Then walk over all this sigs and ask the user - * whether he wants to revoke this signature. - * Return: True when the keyblock has changed. - */ -static int -menu_revsig( KBNODE keyblock ) -{ - PKT_signature *sig; - PKT_public_key *primary_pk; - KBNODE node; - int changed = 0; - int rc, any, skip=1, all=!count_selected_uids(keyblock); - struct revocation_reason_info *reason = NULL; - - /* FIXME: detect duplicates here */ - tty_printf(_("You have signed these user IDs:\n")); - for( node = keyblock; node; node = node->next ) { - node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A); - if( node->pkt->pkttype == PKT_USER_ID ) { - if( node->flag&NODFLG_SELUID || all ) { - PKT_user_id *uid = node->pkt->pkt.user_id; - /* Hmmm: Should we show only UIDs with a signature? */ - tty_printf(" "); - tty_print_utf8_string( uid->name, uid->len ); - tty_printf("\n"); - skip=0; - } - else - skip=1; - } - else if( !skip && node->pkt->pkttype == PKT_SIGNATURE - && ((sig = node->pkt->pkt.signature), - !seckey_available(sig->keyid) ) ) { - if( (sig->sig_class&~3) == 0x10 ) { - tty_printf(_(" signed by %08lX at %s%s%s\n"), - (ulong)sig->keyid[1], datestr_from_sig(sig), - sig->flags.exportable?"":" (non-exportable)", - sig->flags.revocable?"":" (non-revocable)"); - if(sig->flags.revocable) - node->flag |= NODFLG_SELSIG; - } - else if( sig->sig_class == 0x30 ) { - tty_printf(_(" revoked by %08lX at %s\n"), - (ulong)sig->keyid[1], datestr_from_sig(sig) ); - } - } - } - - /* ask */ - for( node = keyblock; node; node = node->next ) { - if( !(node->flag & NODFLG_SELSIG) ) - continue; - ask_revoke_sig( keyblock, node ); - } - - /* present selected */ - any = 0; - for( node = keyblock; node; node = node->next ) { - if( !(node->flag & NODFLG_MARK_A) ) - continue; - if( !any ) { - any = 1; - tty_printf(_("You are about to revoke these signatures:\n")); - } - if( node->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = node->pkt->pkt.user_id; - tty_printf(" "); - tty_print_utf8_string( uid->name, uid->len ); - tty_printf("\n"); - } - else if( node->pkt->pkttype == PKT_SIGNATURE ) { - sig = node->pkt->pkt.signature; - tty_printf(_(" signed by %08lX at %s%s\n"), - (ulong)sig->keyid[1], datestr_from_sig(sig), - sig->flags.exportable?"":_(" (non-exportable)") ); - } - } - if( !any ) - return 0; /* none selected */ - - if( !cpr_get_answer_is_yes("ask_revoke_sig.okay", - _("Really create the revocation certificates? (y/N) ")) ) - return 0; /* forget it */ - - reason = ask_revocation_reason( 0, 1, 0 ); - if( !reason ) { /* user decided to cancel */ - return 0; - } - - /* now we can sign the user ids */ - reloop: /* (must use this, because we are modifing the list) */ - primary_pk = keyblock->pkt->pkt.public_key; - for( node=keyblock; node; node = node->next ) { - KBNODE unode; - PACKET *pkt; - struct sign_attrib attrib; - PKT_secret_key *sk; - - if( !(node->flag & NODFLG_MARK_A) - || node->pkt->pkttype != PKT_SIGNATURE ) - continue; - unode = find_prev_kbnode( keyblock, node, PKT_USER_ID ); - assert( unode ); /* we already checked this */ - - memset( &attrib, 0, sizeof attrib ); - attrib.reason = reason; - attrib.non_exportable=!node->pkt->pkt.signature->flags.exportable; - - node->flag &= ~NODFLG_MARK_A; - sk = xcalloc_secure (1, sizeof *sk ); - if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) { - log_info(_("no secret key\n")); - continue; - } - rc = make_keysig_packet( &sig, primary_pk, - unode->pkt->pkt.user_id, - NULL, - sk, - 0x30, 0, 0, 0, 0, - sign_mk_attrib, - &attrib ); - free_secret_key(sk); - if( rc ) { - log_error(_("signing failed: %s\n"), gpg_strerror (rc)); - release_revocation_reason_info( reason ); - return changed; - } - changed = 1; /* we changed the keyblock */ - update_trust = 1; - /* Are we revoking our own uid? */ - if(primary_pk->keyid[0]==sig->keyid[0] && - primary_pk->keyid[1]==sig->keyid[1]) - unode->pkt->pkt.user_id->is_revoked=1; - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - insert_kbnode( unode, new_kbnode(pkt), 0 ); - goto reloop; - } - - release_revocation_reason_info( reason ); - return changed; -} - -/* Revoke a user ID (i.e. revoke a user ID selfsig). Return true if - keyblock changed. */ -static int -menu_revuid( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key; - PKT_secret_key *sk = copy_secret_key( NULL, - sec_keyblock->pkt->pkt.secret_key ); - KBNODE node; - int changed = 0; - int rc; - struct revocation_reason_info *reason = NULL; - - /* Note that this is correct as per the RFCs, but nevertheless - somewhat meaningless in the real world. 1991 did define the 0x30 - sig class, but PGP 2.x did not actually implement it, so it would - probably be safe to use v4 revocations everywhere. -ds */ - - for( node = pub_keyblock; node; node = node->next ) - if(pk->version>3 || (node->pkt->pkttype==PKT_USER_ID && - node->pkt->pkt.user_id->selfsigversion>3)) - { - if((reason = ask_revocation_reason( 0, 1, 4 ))) - break; - else - goto leave; - } - - reloop: /* (better this way because we are modifing the keyring) */ - for( node = pub_keyblock; node; node = node->next ) - if(node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID)) - { - PKT_user_id *uid=node->pkt->pkt.user_id; - - if(uid->is_revoked) - { - char *user=utf8_to_native(uid->name,uid->len,0); - log_info(_("user ID \"%s\" is already revoked\n"),user); - xfree (user); - } - else - { - PACKET *pkt; - PKT_signature *sig; - struct sign_attrib attrib; - u32 timestamp=make_timestamp(); - - if(uid->created>=timestamp) - { - /* Okay, this is a problem. The user ID selfsig was - created in the future, so we need to warn the user and - set our revocation timestamp one second after that so - everything comes out clean. */ - - log_info(_("WARNING: a user ID signature is dated %d" - " seconds in the future\n"),uid->created-timestamp); - - timestamp=uid->created+1; - } - - memset( &attrib, 0, sizeof attrib ); - attrib.reason = reason; - - node->flag &= ~NODFLG_SELUID; - - rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x30, 0, - (reason==NULL)?3:0, timestamp, 0, - sign_mk_attrib, &attrib ); - if( rc ) - { - log_error(_("signing failed: %s\n"), gpg_strerror (rc)); - goto leave; - } - else - { - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - insert_kbnode( node, new_kbnode(pkt), 0 ); - - /* If the trustdb has an entry for this key+uid then the - trustdb needs an update. */ - if(!update_trust - && (get_validity(pk,uid)&TRUST_MASK)>=TRUST_UNDEFINED) - update_trust=1; - - changed = 1; - node->pkt->pkt.user_id->is_revoked=1; - - goto reloop; - } - } - } - - if(changed) - commit_kbnode( &pub_keyblock ); - - leave: - free_secret_key(sk); - release_revocation_reason_info( reason ); - return changed; -} - -/**************** - * Revoke some of the secondary keys. - * Hmmm: Should we add a revocation to the secret keyring too? - * Does its all make sense to duplicate most of the information? - */ -static int -menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - PKT_public_key *mainpk; - KBNODE node; - int changed = 0; - int rc; - struct revocation_reason_info *reason = NULL; - - reason = ask_revocation_reason( 1, 0, 0 ); - if( !reason ) { /* user decided to cancel */ - return 0; - } - - reloop: /* (better this way because we are modifing the keyring) */ - mainpk = pub_keyblock->pkt->pkt.public_key; - for( node = pub_keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - && (node->flag & NODFLG_SELKEY) ) { - PACKET *pkt; - PKT_signature *sig; - PKT_secret_key *sk; - PKT_public_key *subpk = node->pkt->pkt.public_key; - struct sign_attrib attrib; - - memset( &attrib, 0, sizeof attrib ); - attrib.reason = reason; - - node->flag &= ~NODFLG_SELKEY; - sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key ); - rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk, - 0x28, 0, 0, 0, 0, - sign_mk_attrib, &attrib ); - free_secret_key(sk); - if( rc ) { - log_error(_("signing failed: %s\n"), gpg_strerror (rc)); - release_revocation_reason_info( reason ); - return changed; - } - changed = 1; /* we changed the keyblock */ - - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - insert_kbnode( node, new_kbnode(pkt), 0 ); - goto reloop; - } - } - commit_kbnode( &pub_keyblock ); - /*commit_kbnode( &sec_keyblock );*/ - - /* No need to set update_trust here since signing keys no longer - are used to certify other keys, so there is no change in trust - when revoking/removing them */ - - release_revocation_reason_info( reason ); - return changed; -} - -/* Note that update_ownertrust is going to mark the trustdb dirty when - enabling or disabling a key. This is arguably sub-optimal as - disabled keys are still counted in the web of trust, but perhaps - not worth adding extra complexity to change. -ds */ -static int -enable_disable_key( KBNODE keyblock, int disable ) -{ - PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY ) - ->pkt->pkt.public_key; - unsigned int trust, newtrust; - - trust = newtrust = get_ownertrust (pk); - newtrust &= ~TRUST_FLAG_DISABLED; - if( disable ) - newtrust |= TRUST_FLAG_DISABLED; - if( trust == newtrust ) - return 0; /* already in that state */ - update_ownertrust(pk, newtrust ); - return 0; -} - - -static void -menu_showphoto( KBNODE keyblock ) -{ - KBNODE node; - int select_all = !count_selected_uids(keyblock); - int count=0; - PKT_public_key *pk=NULL; - u32 keyid[2]; - - /* Look for the public key first. We have to be really, really, - explicit as to which photo this is, and what key it is a UID on - since people may want to sign it. */ - - for( node = keyblock; node; node = node->next ) - { - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) - { - pk = node->pkt->pkt.public_key; - keyid_from_pk(pk, keyid); - } - else if( node->pkt->pkttype == PKT_USER_ID ) - { - PKT_user_id *uid = node->pkt->pkt.user_id; - count++; - - if((select_all || (node->flag & NODFLG_SELUID)) && - uid->attribs!=NULL) - { - int i; - - for(i=0;i<uid->numattribs;i++) - { - byte type; - u32 size; - - if(uid->attribs[i].type==ATTRIB_IMAGE && - parse_image_header(&uid->attribs[i],&type,&size)) - { - tty_printf(_("Displaying %s photo ID of size %ld for " - "key 0x%08lX (uid %d)\n"), - image_type_to_string(type,1), - (ulong)size,(ulong)keyid[1],count); - show_photos(&uid->attribs[i],1,pk,NULL); - } - } - } - } - } -} diff --git a/g10/keygen.c b/g10/keygen.c deleted file mode 100644 index 72c5e1e8a..000000000 --- a/g10/keygen.c +++ /dev/null @@ -1,2916 +0,0 @@ -/* keygen.c - generate a key pair - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "main.h" -#include "packet.h" -#include "cipher.h" -#include "ttyio.h" -#include "options.h" -#include "keydb.h" -#include "trustdb.h" -#include "status.h" -#include "i18n.h" -#include "call-agent.h" - - -#define MAX_PREFS 30 - -enum para_name { - pKEYTYPE, - pKEYLENGTH, - pKEYUSAGE, - pSUBKEYTYPE, - pSUBKEYLENGTH, - pSUBKEYUSAGE, - pAUTHKEYTYPE, - pNAMEREAL, - pNAMEEMAIL, - pNAMECOMMENT, - pPREFERENCES, - pREVOKER, - pUSERID, - pEXPIREDATE, - pKEYEXPIRE, /* in n seconds */ - pSUBKEYEXPIRE, /* in n seconds */ - pPASSPHRASE, - pPASSPHRASE_DEK, - pPASSPHRASE_S2K, - pSERIALNO -}; - -struct para_data_s { - struct para_data_s *next; - int lnr; - enum para_name key; - union { - DEK *dek; - STRING2KEY *s2k; - u32 expire; - unsigned int usage; - struct revocation_key revkey; - char value[1]; - } u; -}; - -struct output_control_s { - int lnr; - int dryrun; - int use_files; - struct { - char *fname; - char *newfname; - iobuf_t stream; - armor_filter_context_t afx; - } pub; - struct { - char *fname; - char *newfname; - iobuf_t stream; - armor_filter_context_t afx; - } sec; -}; - - -struct opaque_data_usage_and_pk { - unsigned int usage; - PKT_public_key *pk; -}; - - -static int prefs_initialized = 0; -static byte sym_prefs[MAX_PREFS]; -static int nsym_prefs; -static byte hash_prefs[MAX_PREFS]; -static int nhash_prefs; -static byte zip_prefs[MAX_PREFS]; -static int nzip_prefs; -static int mdc_available,ks_modify; - -static void do_generate_keypair( struct para_data_s *para, - struct output_control_s *outctrl, int card); -static int write_keyblock( iobuf_t out, KBNODE node ); -static int gen_card_key (int algo, int keyno, KBNODE pub_root, KBNODE sec_root, - u32 expireval, struct para_data_s *para); - - - -static void -write_uid( KBNODE root, const char *s ) -{ - PACKET *pkt = xcalloc (1,sizeof *pkt ); - size_t n = strlen(s); - - pkt->pkttype = PKT_USER_ID; - pkt->pkt.user_id = xcalloc (1, sizeof *pkt->pkt.user_id + n - 1 ); - pkt->pkt.user_id->len = n; - pkt->pkt.user_id->ref = 1; - strcpy(pkt->pkt.user_id->name, s); - add_kbnode( root, new_kbnode( pkt ) ); -} - -static void -do_add_key_flags (PKT_signature *sig, unsigned int use) -{ - byte buf[1]; - - if (!use) - return; - - buf[0] = 0; - if (use & PUBKEY_USAGE_SIG) - { - if(sig->sig_class==0x18) - buf[0] |= 0x02; /* Don't set the certify flag for subkeys */ - else - buf[0] |= 0x01 | 0x02; - } - if (use & PUBKEY_USAGE_ENC) - buf[0] |= 0x04 | 0x08; - if (use & PUBKEY_USAGE_AUTH) - buf[0] |= 0x20; - build_sig_subpkt (sig, SIGSUBPKT_KEY_FLAGS, buf, 1); -} - - -int -keygen_add_key_expire( PKT_signature *sig, void *opaque ) -{ - PKT_public_key *pk = opaque; - byte buf[8]; - u32 u; - - if( pk->expiredate ) { - if(pk->expiredate > pk->timestamp) - u= pk->expiredate - pk->timestamp; - else - u= 0; - - buf[0] = (u >> 24) & 0xff; - buf[1] = (u >> 16) & 0xff; - buf[2] = (u >> 8) & 0xff; - buf[3] = u & 0xff; - build_sig_subpkt( sig, SIGSUBPKT_KEY_EXPIRE, buf, 4 ); - } - else - { - /* Make sure we don't leave a key expiration subpacket lying - around */ - delete_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE); - } - - return 0; -} - -static int -keygen_add_key_flags_and_expire (PKT_signature *sig, void *opaque) -{ - struct opaque_data_usage_and_pk *oduap = opaque; - - do_add_key_flags (sig, oduap->usage); - return keygen_add_key_expire (sig, oduap->pk); -} - -static int -set_one_pref (int val, int type, const char *item, byte *buf, int *nbuf) -{ - int i; - - for (i=0; i < *nbuf; i++ ) - if (buf[i] == val) - { - log_info (_("preference `%s' duplicated\n"), item); - return -1; - } - - if (*nbuf >= MAX_PREFS) - { - if(type==1) - log_info(_("too many cipher preferences\n")); - else if(type==2) - log_info(_("too many digest preferences\n")); - else if(type==3) - log_info(_("too many compression preferences\n")); - else - BUG(); - - return -1; - } - - buf[(*nbuf)++] = val; - return 0; -} - -#ifdef USE_AES -#define AES "S9 S8 S7 " -#else -#define AES "" -#endif - -#ifdef USE_CAST5 -#define CAST5 "S3 " -#else -#define CAST5 "" -#endif - -/* - * Parse the supplied string and use it to set the standard - * preferences. The string may be in a form like the one printed by - * "pref" (something like: "S10 S3 H3 H2 Z2 Z1") or the actual - * cipher/hash/compress names. Use NULL to set the default - * preferences. Returns: 0 = okay - */ -int -keygen_set_std_prefs (const char *string,int personal) -{ - byte sym[MAX_PREFS], hash[MAX_PREFS], zip[MAX_PREFS]; - int nsym=0, nhash=0, nzip=0, val, rc=0; - int mdc=1, modify=0; /* mdc defaults on, modify defaults off. */ - - if (!string || !ascii_strcasecmp (string, "default")) { - if (opt.def_preference_list) - string=opt.def_preference_list; - else if ( !openpgp_cipher_test_algo(CIPHER_ALGO_IDEA) ) - string = AES CAST5 "S2 S1 H2 H3 Z2 Z1"; - else - string = AES CAST5 "S2 H2 H3 Z2 Z1"; - - /* If we have it, IDEA goes *after* 3DES so it won't be used - unless we're encrypting along with a V3 key. Ideally, we - would only put the S1 preference in if the key was RSA and - <=2048 bits, as that is what won't break PGP2, but that is - difficult with the current code, and not really worth - checking as a non-RSA <=2048 bit key wouldn't be usable by - PGP2 anyway. -dms */ - } - else if (!ascii_strcasecmp (string, "none")) - string = ""; - - if(strlen(string)) - { - char *tok,*prefstring; - - prefstring=xstrdup (string); /* need a writable string! */ - - while((tok=strsep(&prefstring," ,"))) - { - if((val=openpgp_cipher_map_name(tok))) - { - if(set_one_pref(val,1,tok,sym,&nsym)) - rc=-1; - } - else if((val=openpgp_md_map_name(tok))) - { - if(set_one_pref(val,2,tok,hash,&nhash)) - rc=-1; - } - else if((val=string_to_compress_algo(tok))>-1) - { - if(set_one_pref(val,3,tok,zip,&nzip)) - rc=-1; - } - else if (ascii_strcasecmp(tok,"mdc")==0) - mdc=1; - else if (ascii_strcasecmp(tok,"no-mdc")==0) - mdc=0; - else if (ascii_strcasecmp(tok,"ks-modify")==0) - modify=1; - else if (ascii_strcasecmp(tok,"no-ks-modify")==0) - modify=0; - else - { - log_info (_("invalid item `%s' in preference string\n"),tok); - - /* Complain if IDEA is not available. */ - if(ascii_strcasecmp(tok,"s1")==0 - || ascii_strcasecmp(tok,"idea")==0) - idea_cipher_warn(1); - - rc=-1; - } - } - - xfree (prefstring); - } - - if(!rc) - { - if(personal) - { - if(personal==PREFTYPE_SYM) - { - xfree (opt.personal_cipher_prefs); - - if(nsym==0) - opt.personal_cipher_prefs=NULL; - else - { - int i; - - opt.personal_cipher_prefs= - xmalloc (sizeof(prefitem_t *)*(nsym+1)); - - for (i=0; i<nsym; i++) - { - opt.personal_cipher_prefs[i].type = PREFTYPE_SYM; - opt.personal_cipher_prefs[i].value = sym[i]; - } - - opt.personal_cipher_prefs[i].type = PREFTYPE_NONE; - opt.personal_cipher_prefs[i].value = 0; - } - } - else if(personal==PREFTYPE_HASH) - { - xfree (opt.personal_digest_prefs); - - if(nhash==0) - opt.personal_digest_prefs=NULL; - else - { - int i; - - opt.personal_digest_prefs= - xmalloc (sizeof(prefitem_t *)*(nhash+1)); - - for (i=0; i<nhash; i++) - { - opt.personal_digest_prefs[i].type = PREFTYPE_HASH; - opt.personal_digest_prefs[i].value = hash[i]; - } - - opt.personal_digest_prefs[i].type = PREFTYPE_NONE; - opt.personal_digest_prefs[i].value = 0; - } - } - else if(personal==PREFTYPE_ZIP) - { - xfree (opt.personal_compress_prefs); - - if(nzip==0) - opt.personal_compress_prefs=NULL; - else - { - int i; - - opt.personal_compress_prefs= - xmalloc (sizeof(prefitem_t *)*(nzip+1)); - - for (i=0; i<nzip; i++) - { - opt.personal_compress_prefs[i].type = PREFTYPE_ZIP; - opt.personal_compress_prefs[i].value = zip[i]; - } - - opt.personal_compress_prefs[i].type = PREFTYPE_NONE; - opt.personal_compress_prefs[i].value = 0; - } - } - } - else - { - memcpy (sym_prefs, sym, (nsym_prefs=nsym)); - memcpy (hash_prefs, hash, (nhash_prefs=nhash)); - memcpy (zip_prefs, zip, (nzip_prefs=nzip)); - mdc_available = mdc; - ks_modify = modify; - prefs_initialized = 1; - } - } - - return rc; -} - -#undef CAST5 -#undef AES - -/* Return a fake user ID containing the preferences. Caller must - free. */ -PKT_user_id *keygen_get_std_prefs(void) -{ - int i,j=0; - PKT_user_id *uid=xcalloc (1,sizeof(PKT_user_id)); - - if(!prefs_initialized) - keygen_set_std_prefs(NULL,0); - - uid->prefs=xmalloc ((sizeof(prefitem_t *)* - (nsym_prefs+nhash_prefs+nzip_prefs+1))); - - for(i=0;i<nsym_prefs;i++,j++) - { - uid->prefs[j].type=PREFTYPE_SYM; - uid->prefs[j].value=sym_prefs[i]; - } - - for(i=0;i<nhash_prefs;i++,j++) - { - uid->prefs[j].type=PREFTYPE_HASH; - uid->prefs[j].value=hash_prefs[i]; - } - - for(i=0;i<nzip_prefs;i++,j++) - { - uid->prefs[j].type=PREFTYPE_ZIP; - uid->prefs[j].value=zip_prefs[i]; - } - - uid->prefs[j].type=PREFTYPE_NONE; - uid->prefs[j].value=0; - - uid->mdc_feature=mdc_available; - uid->ks_modify=ks_modify; - - return uid; -} - -static void -add_feature_mdc (PKT_signature *sig,int enabled) -{ - const byte *s; - size_t n; - int i; - char *buf; - - s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n ); - /* Already set or cleared */ - if (s && n && - ((enabled && (s[0] & 0x01)) || (!enabled && !(s[0] & 0x01)))) - return; - - if (!s || !n) { /* create a new one */ - n = 1; - buf = xcalloc (1,n); - } - else { - buf = xmalloc (n); - memcpy (buf, s, n); - } - - if(enabled) - buf[0] |= 0x01; /* MDC feature */ - else - buf[0] &= ~0x01; - - /* Are there any bits set? */ - for(i=0;i<n;i++) - if(buf[i]!=0) - break; - - if(i==n) - delete_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES); - else - build_sig_subpkt (sig, SIGSUBPKT_FEATURES, buf, n); - - xfree (buf); -} - -static void -add_keyserver_modify (PKT_signature *sig,int enabled) -{ - const byte *s; - size_t n; - int i; - char *buf; - - /* The keyserver modify flag is a negative flag (i.e. no-modify) */ - enabled=!enabled; - - s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS, &n ); - /* Already set or cleared */ - if (s && n && - ((enabled && (s[0] & 0x80)) || (!enabled && !(s[0] & 0x80)))) - return; - - if (!s || !n) { /* create a new one */ - n = 1; - buf = xcalloc (1,n); - } - else { - buf = xmalloc (n); - memcpy (buf, s, n); - } - - if(enabled) - buf[0] |= 0x80; /* no-modify flag */ - else - buf[0] &= ~0x80; - - /* Are there any bits set? */ - for(i=0;i<n;i++) - if(buf[i]!=0) - break; - - if(i==n) - delete_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS); - else - build_sig_subpkt (sig, SIGSUBPKT_KS_FLAGS, buf, n); - - xfree (buf); -} - -int -keygen_upd_std_prefs( PKT_signature *sig, void *opaque ) -{ - if (!prefs_initialized) - keygen_set_std_prefs (NULL, 0); - - if (nsym_prefs) - build_sig_subpkt (sig, SIGSUBPKT_PREF_SYM, sym_prefs, nsym_prefs); - else - { - delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_SYM); - delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_SYM); - } - - if (nhash_prefs) - build_sig_subpkt (sig, SIGSUBPKT_PREF_HASH, hash_prefs, nhash_prefs); - else - { - delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_HASH); - delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_HASH); - } - - if (nzip_prefs) - build_sig_subpkt (sig, SIGSUBPKT_PREF_COMPR, zip_prefs, nzip_prefs); - else - { - delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_COMPR); - delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_COMPR); - } - - /* Make sure that the MDC feature flag is set if needed */ - add_feature_mdc (sig,mdc_available); - add_keyserver_modify (sig,ks_modify); - - return 0; -} - - -/**************** - * Add preference to the self signature packet. - * This is only called for packets with version > 3. - - */ -int -keygen_add_std_prefs( PKT_signature *sig, void *opaque ) -{ - PKT_public_key *pk = opaque; - - do_add_key_flags (sig, pk->pubkey_usage); - keygen_add_key_expire( sig, opaque ); - keygen_upd_std_prefs (sig, opaque); - - return 0; -} - - -int -keygen_add_keyserver_url(PKT_signature *sig, void *opaque) -{ - const char *url=opaque; - - build_sig_subpkt(sig,SIGSUBPKT_PREF_KS,url,strlen(url)); - - return 0; -} - - -int -keygen_add_revkey(PKT_signature *sig, void *opaque) -{ - struct revocation_key *revkey=opaque; - byte buf[2+MAX_FINGERPRINT_LEN]; - - buf[0]=revkey->class; - buf[1]=revkey->algid; - memcpy(&buf[2],revkey->fpr,MAX_FINGERPRINT_LEN); - - build_sig_subpkt(sig,SIGSUBPKT_REV_KEY,buf,2+MAX_FINGERPRINT_LEN); - - /* All sigs with revocation keys set are nonrevocable */ - sig->flags.revocable=0; - buf[0] = 0; - build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 ); - - parse_revkeys(sig); - - return 0; -} - -static int -write_direct_sig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk, - struct revocation_key *revkey ) -{ - PACKET *pkt; - PKT_signature *sig; - int rc=0; - KBNODE node; - PKT_public_key *pk; - - if( opt.verbose ) - log_info(_("writing direct signature\n")); - - /* get the pk packet from the pub_tree */ - node = find_kbnode( pub_root, PKT_PUBLIC_KEY ); - if( !node ) - BUG(); - pk = node->pkt->pkt.public_key; - - /* we have to cache the key, so that the verification of the signature - * creation is able to retrieve the public key */ - cache_public_key (pk); - - /* and make the signature */ - rc = make_keysig_packet(&sig,pk,NULL,NULL,sk,0x1F,0,0,0,0, - keygen_add_revkey,revkey); - if( rc ) { - log_error("make_keysig_packet failed: %s\n", gpg_strerror (rc) ); - return rc; - } - - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - add_kbnode( root, new_kbnode( pkt ) ); - return rc; -} - -static int -write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk, - unsigned int use ) -{ - PACKET *pkt; - PKT_signature *sig; - PKT_user_id *uid; - int rc=0; - KBNODE node; - PKT_public_key *pk; - - if( opt.verbose ) - log_info(_("writing self signature\n")); - - /* get the uid packet from the list */ - node = find_kbnode( root, PKT_USER_ID ); - if( !node ) - BUG(); /* no user id packet in tree */ - uid = node->pkt->pkt.user_id; - /* get the pk packet from the pub_tree */ - node = find_kbnode( pub_root, PKT_PUBLIC_KEY ); - if( !node ) - BUG(); - pk = node->pkt->pkt.public_key; - pk->pubkey_usage = use; - /* we have to cache the key, so that the verification of the signature - * creation is able to retrieve the public key */ - cache_public_key (pk); - - /* and make the signature */ - rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0, - keygen_add_std_prefs, pk ); - if( rc ) { - log_error("make_keysig_packet failed: %s\n", gpg_strerror (rc) ); - return rc; - } - - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - add_kbnode( root, new_kbnode( pkt ) ); - return rc; -} - -static int -write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *sk, - unsigned int use ) -{ - PACKET *pkt; - PKT_signature *sig; - int rc=0; - KBNODE node; - PKT_public_key *pk, *subpk; - struct opaque_data_usage_and_pk oduap; - - if( opt.verbose ) - log_info(_("writing key binding signature\n")); - - /* get the pk packet from the pub_tree */ - node = find_kbnode( pub_root, PKT_PUBLIC_KEY ); - if( !node ) - BUG(); - pk = node->pkt->pkt.public_key; - /* we have to cache the key, so that the verification of the signature - * creation is able to retrieve the public key */ - cache_public_key (pk); - - /* find the last subkey */ - subpk = NULL; - for(node=pub_root; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - subpk = node->pkt->pkt.public_key; - } - if( !subpk ) - BUG(); - - /* and make the signature */ - oduap.usage = use; - oduap.pk = subpk; - rc = make_keysig_packet( &sig, pk, NULL, subpk, sk, 0x18, 0, 0, 0, 0, - keygen_add_key_flags_and_expire, &oduap ); - if( rc ) { - log_error("make_keysig_packet failed: %s\n", gpg_strerror (rc) ); - return rc; - } - - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - add_kbnode( root, new_kbnode( pkt ) ); - return rc; -} - - -static int -key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, - const char *topname, const char *elems) -{ - gcry_sexp_t list, l2; - const char *s; - int i, idx; - int rc = 0; - - list = gcry_sexp_find_token (sexp, topname, 0); - if (!list) - return gpg_error (GPG_ERR_INV_OBJ); - l2 = gcry_sexp_cadr (list); - gcry_sexp_release (list); - list = l2; - if (!list) - return gpg_error (GPG_ERR_NO_OBJ); - - for (idx=0,s=elems; *s; s++, idx++) - { - l2 = gcry_sexp_find_token (list, s, 1); - if (!l2) - { - rc = gpg_error (GPG_ERR_NO_OBJ); /* required parameter not found */ - goto leave; - } - array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); - gcry_sexp_release (l2); - if (!array[idx]) - { - rc = gpg_error (GPG_ERR_INV_OBJ); /* required parameter invalid */ - goto leave; - } - } - gcry_sexp_release (list); - - leave: - if (rc) - { - for (i=0; i<idx; i++) - { - xfree (array[i]); - array[i] = NULL; - } - gcry_sexp_release (list); - } - return rc; -} - - -static int -genhelp_protect (DEK *dek, STRING2KEY *s2k, PKT_secret_key *sk) -{ - int rc = 0; - - if (dek) - { - sk->protect.algo = dek->algo; - sk->protect.s2k = *s2k; - rc = protect_secret_key (sk, dek); - if (rc) - log_error ("protect_secret_key failed: %s\n", gpg_strerror (rc) ); - } - - return rc; -} - -static void -genhelp_factors (gcry_sexp_t misc_key_info, KBNODE sec_root) -{ - size_t n; - char *buf; - - if (misc_key_info) - { - /* DSA: don't know whether it makes sense to have the factors, so for now - we store them in the secret keyring (but they are not secret) - p = 2 * q * f1 * f2 * ... * fn - We store only f1 to f_n-1; fn can be calculated because p and q - are known. */ - n = gcry_sexp_sprint (misc_key_info, 0, NULL, 0); - buf = xmalloc (n+4); - strcpy (buf, "#::"); - n = gcry_sexp_sprint (misc_key_info, 0, buf+3, n); - if (n) - { - n += 3; - add_kbnode (sec_root, make_comment_node_from_buffer (buf, n)); - } - xfree (buf); - gcry_sexp_release (misc_key_info); - } -} - - -static int -gen_elg(int algo, unsigned int nbits, - KBNODE pub_root, KBNODE sec_root, DEK *dek, - STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval ) -{ - int rc; - PACKET *pkt; - PKT_secret_key *sk; - PKT_public_key *pk; - gcry_sexp_t s_parms, s_key; - gcry_sexp_t misc_key_info; - - assert (is_ELGAMAL(algo)); - - if (nbits < 512) - { - nbits = 1024; - log_info (_("keysize invalid; using %u bits\n"), nbits); - } - - if ((nbits % 32)) - { - nbits = ((nbits + 31) / 32) * 32; - log_info (_("keysize rounded up to %u bits\n"), nbits); - } - - rc = gcry_sexp_build ( &s_parms, NULL, - "(genkey(%s(nbits %d)))", - algo == GCRY_PK_ELG_E ? "openpgp-elg" : - algo == GCRY_PK_ELG ? "elg" : "x-oops" , - (int)nbits); - if (rc) - log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc)); - - rc = gcry_pk_genkey (&s_key, s_parms); - gcry_sexp_release (s_parms); - if (rc) - { - log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) ); - return rc; - } - - sk = xcalloc (1, sizeof *sk); - pk = xcalloc (1, sizeof *pk); - sk->timestamp = pk->timestamp = make_timestamp(); - sk->version = pk->version = 4; - if (expireval) - sk->expiredate = pk->expiredate = sk->timestamp + expireval; - sk->pubkey_algo = pk->pubkey_algo = algo; - - rc = key_from_sexp (pk->pkey, s_key, "public-key", "pgy"); - if (rc) - { - log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) ); - gcry_sexp_release (s_key); - return rc; - } - rc = key_from_sexp (sk->skey, s_key, "private-key", "pgyx"); - if (rc) - { - log_error("key_from_sexp failed: %s\n", gpg_strerror (rc) ); - gcry_sexp_release (s_key); - return rc; - } - misc_key_info = gcry_sexp_find_token (s_key, "misc-key-info", 0); - gcry_sexp_release (s_key); - - sk->is_protected = 0; - sk->protect.algo = 0; - - sk->csum = checksum_mpi (sk->skey[3]); - if (ret_sk) /* not a subkey: return an unprotected version of the sk */ - *ret_sk = copy_secret_key (NULL, sk); - - rc = genhelp_protect (dek, s2k, sk); - if (rc) - { - free_public_key (pk); - free_secret_key (sk); - gcry_sexp_release (misc_key_info); - return rc; - } - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY; - pkt->pkt.public_key = pk; - add_kbnode(pub_root, new_kbnode( pkt )); - - /* don't know whether it makes sense to have the factors, so for now - * we store them in the secret keyring (but they are not secret) */ - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY; - pkt->pkt.secret_key = sk; - add_kbnode(sec_root, new_kbnode( pkt )); - - genhelp_factors (misc_key_info, sec_root); - - return 0; -} - - -/**************** - * Generate a DSA key - */ -static int -gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, - STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval ) -{ - int rc; - PACKET *pkt; - PKT_secret_key *sk; - PKT_public_key *pk; - gcry_sexp_t s_parms, s_key; - gcry_sexp_t misc_key_info; - - if (nbits > 1024 || nbits < 512) - { - nbits = 1024; - log_info(_("keysize invalid; using %u bits\n"), nbits); - } - - if ((nbits % 64)) - { - nbits = ((nbits + 63) / 64) * 64; - log_info (_("keysize rounded up to %u bits\n"), nbits); - } - - rc = gcry_sexp_build (&s_parms, NULL, - "(genkey(dsa(nbits %d)))", - (int)nbits); - if (rc) - log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc)); - - rc = gcry_pk_genkey (&s_key, s_parms); - gcry_sexp_release (s_parms); - if (rc) - { - log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) ); - return rc; - } - - sk = xcalloc (1, sizeof *sk ); - pk = xcalloc (1, sizeof *pk ); - sk->timestamp = pk->timestamp = make_timestamp(); - sk->version = pk->version = 4; - if (expireval) - sk->expiredate = pk->expiredate = sk->timestamp + expireval; - sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_DSA; - - rc = key_from_sexp (pk->pkey, s_key, "public-key", "pqgy"); - if (rc) - { - log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc)); - gcry_sexp_release (s_key); - return rc; - } - rc = key_from_sexp (sk->skey, s_key, "private-key", "pqgyx"); - if (rc) - { - log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) ); - gcry_sexp_release (s_key); - return rc; - } - misc_key_info = gcry_sexp_find_token (s_key, "misc-key-info", 0); - gcry_sexp_release (s_key); - - sk->is_protected = 0; - sk->protect.algo = 0; - - sk->csum = checksum_mpi ( sk->skey[4] ); - if (ret_sk) /* not a subkey: return an unprotected version of the sk */ - *ret_sk = copy_secret_key( NULL, sk ); - - rc = genhelp_protect (dek, s2k, sk); - if (rc) - { - free_public_key (pk); - free_secret_key (sk); - gcry_sexp_release (misc_key_info); - return rc; - } - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY; - pkt->pkt.public_key = pk; - add_kbnode(pub_root, new_kbnode( pkt )); - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY; - pkt->pkt.secret_key = sk; - add_kbnode(sec_root, new_kbnode( pkt )); - - genhelp_factors (misc_key_info, sec_root); - - return 0; -} - - -/* - * Generate an RSA key. - */ -static int -gen_rsa(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, - STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval ) -{ - int rc; - PACKET *pkt; - PKT_secret_key *sk; - PKT_public_key *pk; - gcry_sexp_t s_parms, s_key; - - assert (is_RSA(algo)); - - if (nbits < 1024) - { - nbits = 1024; - log_info(_("keysize invalid; using %u bits\n"), nbits); - } - - if ((nbits % 32)) - { - nbits = ((nbits + 31) / 32) * 32; - log_info (_("keysize rounded up to %u bits\n"), nbits); - } - - rc = gcry_sexp_build (&s_parms, NULL, - "(genkey(rsa(nbits %d)))", - (int)nbits); - if (rc) - log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc)); - - rc = gcry_pk_genkey (&s_key, s_parms); - gcry_sexp_release (s_parms); - if (rc) - { - log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) ); - return rc; - } - - sk = xcalloc (1, sizeof *sk ); - pk = xcalloc (1, sizeof *pk ); - sk->timestamp = pk->timestamp = make_timestamp(); - sk->version = pk->version = 4; - if (expireval) - sk->expiredate = pk->expiredate = sk->timestamp + expireval; - sk->pubkey_algo = pk->pubkey_algo = algo; - - rc = key_from_sexp (pk->pkey, s_key, "public-key", "ne"); - if (rc) - { - log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc)); - gcry_sexp_release (s_key); - return rc; - } - rc = key_from_sexp (sk->skey, s_key, "private-key", "nedpqu"); - if (rc) - { - log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) ); - gcry_sexp_release (s_key); - return rc; - } - gcry_sexp_release (s_key); - - sk->is_protected = 0; - sk->protect.algo = 0; - - sk->csum = checksum_mpi (sk->skey[2] ); - sk->csum += checksum_mpi (sk->skey[3] ); - sk->csum += checksum_mpi (sk->skey[4] ); - sk->csum += checksum_mpi (sk->skey[5] ); - if (ret_sk) /* not a subkey: return an unprotected version of the sk */ - *ret_sk = copy_secret_key (NULL, sk); - - rc = genhelp_protect (dek, s2k, sk); - if (rc) - { - free_public_key (pk); - free_secret_key (sk); - return rc; - } - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY; - pkt->pkt.public_key = pk; - add_kbnode (pub_root, new_kbnode( pkt )); - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY; - pkt->pkt.secret_key = sk; - add_kbnode(sec_root, new_kbnode( pkt )); - - return 0; -} - - -/**************** - * check valid days: - * return 0 on error or the multiplier - */ -static int -check_valid_days( const char *s ) -{ - if( !digitp(s) ) - return 0; - for( s++; *s; s++) - if( !digitp(s) ) - break; - if( !*s ) - return 1; - if( s[1] ) - return 0; /* e.g. "2323wc" */ - if( *s == 'd' || *s == 'D' ) - return 1; - if( *s == 'w' || *s == 'W' ) - return 7; - if( *s == 'm' || *s == 'M' ) - return 30; - if( *s == 'y' || *s == 'Y' ) - return 365; - return 0; -} - - -/**************** - * Returns: 0 to create both a DSA and a ElGamal key. - * and only if key flags are to be written the desired usage. - */ -static int -ask_algo (int addmode, unsigned int *r_usage) -{ - char *answer; - int algo; - - *r_usage = 0; - tty_printf(_("Please select what kind of key you want:\n")); - if( !addmode ) - tty_printf(_(" (%d) DSA and ElGamal (default)\n"), 1 ); - tty_printf( _(" (%d) DSA (sign only)\n"), 2 ); - if( addmode ) - tty_printf( _(" (%d) ElGamal (encrypt only)\n"), 3 ); - if (opt.expert) - tty_printf( _(" (%d) ElGamal (sign and encrypt)\n"), 4 ); - tty_printf( _(" (%d) RSA (sign only)\n"), 5 ); - if (addmode) - tty_printf( _(" (%d) RSA (encrypt only)\n"), 6 ); - if (opt.expert) - tty_printf( _(" (%d) RSA (sign and encrypt)\n"), 7 ); - - for(;;) { - answer = cpr_get("keygen.algo",_("Your selection? ")); - cpr_kill_prompt(); - algo = *answer? atoi(answer): 1; - xfree (answer); - if( algo == 1 && !addmode ) { - algo = 0; /* create both keys */ - break; - } - else if( algo == 7 && opt.expert ) { - algo = PUBKEY_ALGO_RSA; - *r_usage = PUBKEY_USAGE_ENC | PUBKEY_USAGE_SIG; - break; - } - else if( algo == 6 && addmode ) { - algo = PUBKEY_ALGO_RSA; - *r_usage = PUBKEY_USAGE_ENC; - break; - } - else if( algo == 5 ) { - algo = PUBKEY_ALGO_RSA; - *r_usage = PUBKEY_USAGE_SIG; - break; - } - else if( algo == 4 && opt.expert) - { - tty_printf(_( -"The use of this algorithm is only supported by GnuPG. You will not be\n" -"able to use this key to communicate with PGP users. This algorithm is also\n" -"very slow, and may not be as secure as the other choices.\n")); - - if( cpr_get_answer_is_yes("keygen.algo.elg_se", - _("Create anyway? "))) - { - algo = PUBKEY_ALGO_ELGAMAL; - *r_usage = PUBKEY_USAGE_ENC | PUBKEY_USAGE_SIG; - break; - } - } - else if( algo == 3 && addmode ) { - algo = PUBKEY_ALGO_ELGAMAL_E; - *r_usage = PUBKEY_USAGE_ENC; - break; - } - else if( algo == 2 ) { - algo = PUBKEY_ALGO_DSA; - *r_usage = PUBKEY_USAGE_SIG; - break; - } - else - tty_printf(_("Invalid selection.\n")); - } - return algo; -} - - -static unsigned -ask_keysize( int algo ) -{ - char *answer; - unsigned nbits; - - if (algo != PUBKEY_ALGO_DSA && algo != PUBKEY_ALGO_RSA) { - tty_printf (_("About to generate a new %s keypair.\n" - " minimum keysize is 768 bits\n" - " default keysize is 1024 bits\n" - " highest suggested keysize is 2048 bits\n"), - gcry_pk_algo_name (algo) ); - } - - for(;;) { - answer = cpr_get("keygen.size", - _("What keysize do you want? (1024) ")); - cpr_kill_prompt(); - nbits = *answer? atoi(answer): 1024; - xfree (answer); - if( algo == PUBKEY_ALGO_DSA && (nbits < 512 || nbits > 1024) ) - tty_printf(_("DSA only allows keysizes from 512 to 1024\n")); - else if( algo == PUBKEY_ALGO_RSA && nbits < 1024 ) - tty_printf(_("keysize too small;" - " 1024 is smallest value allowed for RSA.\n")); - else if( nbits < 768 ) - tty_printf(_("keysize too small;" - " 768 is smallest value allowed.\n")); - else if( nbits > 4096 ) { - /* It is ridiculous and an annoyance to use larger key sizes! - * GnuPG can handle much larger sizes; but it takes an eternity - * to create such a key (but less than the time the Sirius - * Computer Corporation needs to process one of the usual - * complaints) and {de,en}cryption although needs some time. - * So, before you complain about this limitation, I suggest that - * you start a discussion with Marvin about this theme and then - * do whatever you want. */ - tty_printf(_("keysize too large; %d is largest value allowed.\n"), - 4096); - } - else if( nbits > 2048 && !cpr_enabled() ) { - tty_printf( - _("Keysizes larger than 2048 are not suggested because\n" - "computations take REALLY long!\n")); - if( cpr_get_answer_is_yes("keygen.size.huge.okay",_( - "Are you sure that you want this keysize? ")) ) { - tty_printf(_("Okay, but keep in mind that your monitor " - "and keyboard radiation is also very vulnerable " - "to attacks!\n")); - break; - } - } - else - break; - } - tty_printf(_("Requested keysize is %u bits\n"), nbits ); - if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) { - nbits = ((nbits + 63) / 64) * 64; - tty_printf(_("rounded up to %u bits\n"), nbits ); - } - else if( (nbits % 32) ) { - nbits = ((nbits + 31) / 32) * 32; - tty_printf(_("rounded up to %u bits\n"), nbits ); - } - return nbits; -} - - -/**************** - * Parse an expire string and return it's value in days. - * Returns -1 on error. - */ -static int -parse_expire_string( const char *string ) -{ - int mult; - u32 abs_date=0; - u32 curtime = make_timestamp(); - int valid_days; - - if( !*string ) - valid_days = 0; - else if( (abs_date = scan_isodatestr(string)) && abs_date > curtime ) { - /* This calculation is not perfectly okay because we - * are later going to simply multiply by 86400 and don't - * correct for leapseconds. A solution would be to change - * the whole implemenation to work with dates and not intervals - * which are required for v3 keys. - */ - valid_days = abs_date/86400-curtime/86400+1; - } - else if( (mult=check_valid_days(string)) ) { - valid_days = atoi(string) * mult; - if( valid_days < 0 || valid_days > 39447 ) - valid_days = 0; - } - else { - valid_days = -1; - } - return valid_days; -} - -/* object == 0 for a key, and 1 for a sig */ -u32 -ask_expire_interval(int object) -{ - char *answer; - int valid_days=0; - u32 interval = 0; - - switch(object) - { - case 0: - tty_printf(_("Please specify how long the key should be valid.\n" - " 0 = key does not expire\n" - " <n> = key expires in n days\n" - " <n>w = key expires in n weeks\n" - " <n>m = key expires in n months\n" - " <n>y = key expires in n years\n")); - break; - - case 1: - tty_printf(_("Please specify how long the signature should be valid.\n" - " 0 = signature does not expire\n" - " <n> = signature expires in n days\n" - " <n>w = signature expires in n weeks\n" - " <n>m = signature expires in n months\n" - " <n>y = signature expires in n years\n")); - break; - - default: - BUG(); - } - - /* Note: The elgamal subkey for DSA has no expiration date because - * it must be signed with the DSA key and this one has the expiration - * date */ - - answer = NULL; - for(;;) { - u32 curtime=make_timestamp(); - - xfree (answer); - if(object==0) - answer = cpr_get("keygen.valid",_("Key is valid for? (0) ")); - else - answer = cpr_get("siggen.valid",_("Signature is valid for? (0) ")); - cpr_kill_prompt(); - trim_spaces(answer); - valid_days = parse_expire_string( answer ); - if( valid_days < 0 ) { - tty_printf(_("invalid value\n")); - continue; - } - - if( !valid_days ) { - tty_printf(_("%s does not expire at all\n"), - object==0?"Key":"Signature"); - interval = 0; - } - else { - interval = valid_days * 86400L; - /* print the date when the key expires */ - tty_printf(_("%s expires at %s\n"), - object==0?"Key":"Signature", - asctimestamp((ulong)(curtime + interval) ) ); - /* FIXME: This check yields warning some machines: write a - configure check and do this check here only for 32 bit - machines */ - if( (time_t)((ulong)(curtime+interval)) < 0 ) - tty_printf(_("Your system can't display dates beyond 2038.\n" - "However, it will be correctly handled up to 2106.\n")); - } - - if( cpr_enabled() || cpr_get_answer_is_yes("keygen.valid.okay", - _("Is this correct (y/n)? ")) ) - break; - } - xfree (answer); - return interval; -} - -u32 -ask_expiredate() -{ - u32 x = ask_expire_interval(0); - return x? make_timestamp() + x : 0; -} - - -static int -count_chr( const char *string, int c ) -{ - int count; - - for (count=0; *string; string++ ) - if ( *string == c ) - count++; - return count; -} - - -static int -has_invalid_email_chars( const char *s ) -{ - int at_seen=0; - static char valid_chars[] = "01234567890_-." - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - for( ; *s; s++ ) { - if( *s & 0x80 ) - return 1; - if( *s == '@' ) - at_seen=1; - else if( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) ) - return 1; - else if( at_seen && !strchr( valid_chars, *s ) ) - return 1; - } - return 0; -} - - -static char * -ask_user_id( int mode ) -{ - char *answer; - char *aname, *acomment, *amail, *uid; - - if( !mode ) - tty_printf( _("\n" -"You need a User-ID to identify your key; the software constructs the user id\n" -"from Real Name, Comment and Email Address in this form:\n" -" \"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>\"\n\n") ); - uid = aname = acomment = amail = NULL; - for(;;) { - char *p; - int fail=0; - - if( !aname ) { - for(;;) { - xfree (aname); - aname = cpr_get("keygen.name",_("Real name: ")); - trim_spaces(aname); - cpr_kill_prompt(); - - if( opt.allow_freeform_uid ) - break; - - if( strpbrk( aname, "<>" ) ) - tty_printf(_("Invalid character in name\n")); - else if( digitp(aname) ) - tty_printf(_("Name may not start with a digit\n")); - else if( strlen(aname) < 5 ) - tty_printf(_("Name must be at least 5 characters long\n")); - else - break; - } - } - if( !amail ) { - for(;;) { - xfree (amail); - amail = cpr_get("keygen.email",_("Email address: ")); - trim_spaces(amail); - cpr_kill_prompt(); - if( !*amail || opt.allow_freeform_uid ) - break; /* no email address is okay */ - else if( has_invalid_email_chars(amail) - || count_chr(amail,'@') != 1 - || *amail == '@' - || amail[strlen(amail)-1] == '@' - || amail[strlen(amail)-1] == '.' - || strstr(amail, "..") ) - tty_printf(_("Not a valid email address\n")); - else - break; - } - } - if( !acomment ) { - for(;;) { - xfree (acomment); - acomment = cpr_get("keygen.comment",_("Comment: ")); - trim_spaces(acomment); - cpr_kill_prompt(); - if( !*acomment ) - break; /* no comment is okay */ - else if( strpbrk( acomment, "()" ) ) - tty_printf(_("Invalid character in comment\n")); - else - break; - } - } - - - xfree (uid); - uid = p = xmalloc (strlen(aname)+strlen(amail)+strlen(acomment)+12+10); - p = stpcpy(p, aname ); - if( *acomment ) - p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")"); - if( *amail ) - p = stpcpy(stpcpy(stpcpy(p," <"), amail),">"); - - /* print a note in case that UTF8 mapping has to be done */ - for(p=uid; *p; p++ ) { - if( *p & 0x80 ) { - tty_printf(_("You are using the `%s' character set.\n"), - get_native_charset() ); - break; - } - } - - tty_printf(_("You selected this USER-ID:\n \"%s\"\n\n"), uid); - /* fixme: add a warning if this user-id already exists */ - if( !*amail && !opt.allow_freeform_uid - && (strchr( aname, '@' ) || strchr( acomment, '@'))) { - fail = 1; - tty_printf(_("Please don't put the email address " - "into the real name or the comment\n") ); - } - - for(;;) { - const char *ansstr = _("NnCcEeOoQq"); - - if( strlen(ansstr) != 10 ) - BUG(); - if( cpr_enabled() ) { - answer = xstrdup (ansstr+6); - answer[1] = 0; - } - else { - answer = cpr_get("keygen.userid.cmd", fail? - _("Change (N)ame, (C)omment, (E)mail or (Q)uit? ") : - _("Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? ")); - cpr_kill_prompt(); - } - if( strlen(answer) > 1 ) - ; - else if( *answer == ansstr[0] || *answer == ansstr[1] ) { - xfree (aname); aname = NULL; - break; - } - else if( *answer == ansstr[2] || *answer == ansstr[3] ) { - xfree (acomment); acomment = NULL; - break; - } - else if( *answer == ansstr[4] || *answer == ansstr[5] ) { - xfree (amail); amail = NULL; - break; - } - else if( *answer == ansstr[6] || *answer == ansstr[7] ) { - if( fail ) { - tty_printf(_("Please correct the error first\n")); - } - else { - xfree (aname); aname = NULL; - xfree (acomment); acomment = NULL; - xfree (amail); amail = NULL; - break; - } - } - else if( *answer == ansstr[8] || *answer == ansstr[9] ) { - xfree (aname); aname = NULL; - xfree (acomment); acomment = NULL; - xfree (amail); amail = NULL; - xfree (uid); uid = NULL; - break; - } - xfree (answer); - } - xfree (answer); - if( !amail && !acomment && !amail ) - break; - xfree (uid); uid = NULL; - } - if( uid ) { - char *p = native_to_utf8( uid ); - xfree ( uid ); - uid = p; - } - return uid; -} - - -static DEK * -ask_passphrase( STRING2KEY **ret_s2k ) -{ - DEK *dek = NULL; - STRING2KEY *s2k; - const char *errtext = NULL; - - tty_printf(_("You need a Passphrase to protect your secret key.\n\n") ); - - s2k = xmalloc ( sizeof *s2k ); - for(;;) { - s2k->mode = opt.s2k_mode; - s2k->hash_algo = opt.s2k_digest_algo; - dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k,2, - errtext, NULL); - if( !dek ) { - errtext = N_("passphrase not correctly repeated; try again"); - tty_printf(_("%s.\n"), _(errtext)); - } - else if( !dek->keylen ) { - xfree (dek); dek = NULL; - xfree (s2k); s2k = NULL; - tty_printf(_( - "You don't want a passphrase - this is probably a *bad* idea!\n" - "I will do it anyway. You can change your passphrase at any time,\n" - "using this program with the option \"--edit-key\".\n\n")); - break; - } - else - break; /* okay */ - } - *ret_s2k = s2k; - return dek; -} - - -static int -do_create( int algo, unsigned int nbits, KBNODE pub_root, KBNODE sec_root, - DEK *dek, STRING2KEY *s2k, PKT_secret_key **sk, u32 expiredate ) -{ - int rc=0; - - if( !opt.batch ) - tty_printf(_( -"We need to generate a lot of random bytes. It is a good idea to perform\n" -"some other action (type on the keyboard, move the mouse, utilize the\n" -"disks) during the prime generation; this gives the random number\n" -"generator a better chance to gain enough entropy.\n") ); - - if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E ) - rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate); - else if( algo == PUBKEY_ALGO_DSA ) - rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk, expiredate); - else if( algo == PUBKEY_ALGO_RSA ) - rc = gen_rsa(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate); - else - BUG(); - -#ifdef ENABLE_COMMENT_PACKETS - if( !rc ) { - add_kbnode( pub_root, - make_comment_node("#created by GNUPG v" VERSION " (" - PRINTABLE_OS_NAME ")")); - add_kbnode( sec_root, - make_comment_node("#created by GNUPG v" VERSION " (" - PRINTABLE_OS_NAME ")")); - } -#endif - return rc; -} - - -/**************** - * Generate a new user id packet, or return NULL if canceled - */ -PKT_user_id * -generate_user_id() -{ - PKT_user_id *uid; - char *p; - size_t n; - - p = ask_user_id( 1 ); - if( !p ) - return NULL; - n = strlen(p); - uid = xcalloc (1, sizeof *uid + n - 1 ); - uid->len = n; - strcpy(uid->name, p); - uid->ref = 1; - return uid; -} - - -static void -release_parameter_list( struct para_data_s *r ) -{ - struct para_data_s *r2; - - for( ; r ; r = r2 ) { - r2 = r->next; - if( r->key == pPASSPHRASE_DEK ) - xfree ( r->u.dek ); - else if( r->key == pPASSPHRASE_S2K ) - xfree ( r->u.s2k ); - - xfree (r); - } -} - -static struct para_data_s * -get_parameter( struct para_data_s *para, enum para_name key ) -{ - struct para_data_s *r; - - for( r = para; r && r->key != key; r = r->next ) - ; - return r; -} - -static const char * -get_parameter_value( struct para_data_s *para, enum para_name key ) -{ - struct para_data_s *r = get_parameter( para, key ); - return (r && *r->u.value)? r->u.value : NULL; -} - -static int -get_parameter_algo( struct para_data_s *para, enum para_name key ) -{ - int i; - struct para_data_s *r = get_parameter( para, key ); - if( !r ) - return -1; - if( digitp( r->u.value ) ) - i = atoi( r->u.value ); - else - i = openpgp_pk_map_name ( r->u.value ); - if (i == PUBKEY_ALGO_RSA_E || i == PUBKEY_ALGO_RSA_S) - i = 0; /* we don't want to allow generation of these algorithms */ - return i; -} - -/* - * parse the usage parameter and set the keyflags. Return true on error. - */ -static int -parse_parameter_usage (const char *fname, - struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter( para, key ); - char *p, *pn; - unsigned int use; - - if( !r ) - return 0; /* none (this is an optional parameter)*/ - - use = 0; - pn = r->u.value; - while ( (p = strsep (&pn, " \t,")) ) { - if ( !*p) - ; - else if ( !ascii_strcasecmp (p, "sign") ) - use |= PUBKEY_USAGE_SIG; - else if ( !ascii_strcasecmp (p, "encrypt") ) - use |= PUBKEY_USAGE_ENC; - else if ( !ascii_strcasecmp (p, "auth") ) - use |= PUBKEY_USAGE_AUTH; - else { - log_error("%s:%d: invalid usage list\n", fname, r->lnr ); - return -1; /* error */ - } - } - r->u.usage = use; - return 0; -} - -static int -parse_revocation_key (const char *fname, - struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter( para, key ); - struct revocation_key revkey; - char *pn; - int i; - - if( !r ) - return 0; /* none (this is an optional parameter) */ - - pn = r->u.value; - - revkey.class=0x80; - revkey.algid=atoi(pn); - if(!revkey.algid) - goto fail; - - /* Skip to the fpr */ - while(*pn && *pn!=':') - pn++; - - if(*pn!=':') - goto fail; - - pn++; - - for(i=0;i<MAX_FINGERPRINT_LEN && *pn;i++,pn+=2) - { - int c=hextobyte(pn); - if(c==-1) - goto fail; - - revkey.fpr[i]=c; - } - - /* skip to the tag */ - while(*pn && *pn!='s' && *pn!='S') - pn++; - - if(ascii_strcasecmp(pn,"sensitive")==0) - revkey.class|=0x40; - - memcpy(&r->u.revkey,&revkey,sizeof(struct revocation_key)); - - return 0; - - fail: - log_error("%s:%d: invalid revocation key\n", fname, r->lnr ); - return -1; /* error */ -} - - -static u32 -get_parameter_u32( struct para_data_s *para, enum para_name key ) -{ - struct para_data_s *r = get_parameter( para, key ); - - if( !r ) - return 0; - if( r->key == pKEYEXPIRE || r->key == pSUBKEYEXPIRE ) - return r->u.expire; - if( r->key == pKEYUSAGE || r->key == pSUBKEYUSAGE ) - return r->u.usage; - - return (unsigned int)strtoul( r->u.value, NULL, 10 ); -} - -static unsigned int -get_parameter_uint( struct para_data_s *para, enum para_name key ) -{ - return get_parameter_u32( para, key ); -} - -static DEK * -get_parameter_dek( struct para_data_s *para, enum para_name key ) -{ - struct para_data_s *r = get_parameter( para, key ); - return r? r->u.dek : NULL; -} - -static STRING2KEY * -get_parameter_s2k( struct para_data_s *para, enum para_name key ) -{ - struct para_data_s *r = get_parameter( para, key ); - return r? r->u.s2k : NULL; -} - -static struct revocation_key * -get_parameter_revkey( struct para_data_s *para, enum para_name key ) -{ - struct para_data_s *r = get_parameter( para, key ); - return r? &r->u.revkey : NULL; -} - -static int -proc_parameter_file( struct para_data_s *para, const char *fname, - struct output_control_s *outctrl, int card ) -{ - struct para_data_s *r; - const char *s1, *s2, *s3; - size_t n; - char *p; - int i; - - /* check that we have all required parameters */ - assert( get_parameter( para, pKEYTYPE ) ); - i = get_parameter_algo( para, pKEYTYPE ); - if( i < 1 || openpgp_pk_test_algo ( i, PUBKEY_USAGE_SIG ) ) { - r = get_parameter( para, pKEYTYPE ); - log_error("%s:%d: invalid algorithm\n", fname, r->lnr ); - return -1; - } - - if (parse_parameter_usage (fname, para, pKEYUSAGE)) - return -1; - - i = get_parameter_algo( para, pSUBKEYTYPE ); - if( i > 0 && openpgp_pk_test_algo ( i, 0 ) ) { - r = get_parameter( para, pSUBKEYTYPE ); - log_error("%s:%d: invalid algorithm\n", fname, r->lnr ); - return -1; - } - if (i > 0 && parse_parameter_usage (fname, para, pSUBKEYUSAGE)) - return -1; - - - if( !get_parameter_value( para, pUSERID ) ) { - /* create the formatted user ID */ - s1 = get_parameter_value( para, pNAMEREAL ); - s2 = get_parameter_value( para, pNAMECOMMENT ); - s3 = get_parameter_value( para, pNAMEEMAIL ); - if( s1 || s2 || s3 ) { - n = (s1?strlen(s1):0) + (s2?strlen(s2):0) + (s3?strlen(s3):0); - r = xcalloc (1, sizeof *r + n + 20 ); - r->key = pUSERID; - p = r->u.value; - if( s1 ) - p = stpcpy(p, s1 ); - if( s2 ) - p = stpcpy(stpcpy(stpcpy(p," ("), s2 ),")"); - if( s3 ) - p = stpcpy(stpcpy(stpcpy(p," <"), s3 ),">"); - r->next = para; - para = r; - } - } - - /* Set preferences, if any. */ - keygen_set_std_prefs(get_parameter_value( para, pPREFERENCES ), 0); - - /* Set revoker, if any. */ - if (parse_revocation_key (fname, para, pREVOKER)) - return -1; - - /* make DEK and S2K from the Passphrase */ - r = get_parameter( para, pPASSPHRASE ); - if( r && *r->u.value ) { - /* we have a plain text passphrase - create a DEK from it. - * It is a little bit ridiculous to keep it in secure memory - * but because we do this always, why not here. */ - STRING2KEY *s2k; - DEK *dek; - - s2k = xmalloc_secure ( sizeof *s2k ); - s2k->mode = opt.s2k_mode; - s2k->hash_algo = opt.s2k_digest_algo; - set_next_passphrase( r->u.value ); - dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2, - NULL, NULL); - set_next_passphrase( NULL ); - assert( dek ); - memset( r->u.value, 0, strlen(r->u.value) ); - - r = xcalloc (1, sizeof *r ); - r->key = pPASSPHRASE_S2K; - r->u.s2k = s2k; - r->next = para; - para = r; - r = xcalloc (1, sizeof *r ); - r->key = pPASSPHRASE_DEK; - r->u.dek = dek; - r->next = para; - para = r; - } - - /* make KEYEXPIRE from Expire-Date */ - r = get_parameter( para, pEXPIREDATE ); - if( r && *r->u.value ) { - i = parse_expire_string( r->u.value ); - if( i < 0 ) { - log_error("%s:%d: invalid expire date\n", fname, r->lnr ); - return -1; - } - r->u.expire = i * 86400L; - r->key = pKEYEXPIRE; /* change hat entry */ - /* also set it for the subkey */ - r = xcalloc (1, sizeof *r + 20 ); - r->key = pSUBKEYEXPIRE; - r->u.expire = i * 86400L; - r->next = para; - para = r; - } - - if( !!outctrl->pub.newfname ^ !!outctrl->sec.newfname ) { - log_error("%s:%d: only one ring name is set\n", fname, outctrl->lnr ); - return -1; - } - - do_generate_keypair( para, outctrl, card); - return 0; -} - - -/**************** - * Kludge to allow non interactive key generation controlled - * by a parameter file (which currently is only stdin) - * Note, that string parameters are expected to be in UTF-8 - */ -static void -read_parameter_file( const char *fname ) -{ - static struct { const char *name; - enum para_name key; - } keywords[] = { - { "Key-Type", pKEYTYPE}, - { "Key-Length", pKEYLENGTH }, - { "Key-Usage", pKEYUSAGE }, - { "Subkey-Type", pSUBKEYTYPE }, - { "Subkey-Length", pSUBKEYLENGTH }, - { "Subkey-Usage", pSUBKEYUSAGE }, - { "Name-Real", pNAMEREAL }, - { "Name-Email", pNAMEEMAIL }, - { "Name-Comment", pNAMECOMMENT }, - { "Expire-Date", pEXPIREDATE }, - { "Passphrase", pPASSPHRASE }, - { "Preferences", pPREFERENCES }, - { "Revoker", pREVOKER }, - { NULL, 0 } - }; - FILE *fp; - char line[1024], *p; - int lnr; - const char *err = NULL; - struct para_data_s *para, *r; - int i; - struct output_control_s outctrl; - - memset( &outctrl, 0, sizeof( outctrl ) ); - - if( !fname || !*fname || !strcmp(fname,"-") ) { - fp = stdin; - fname = "-"; - } - else { - fp = fopen( fname, "r" ); - if( !fp ) { - log_error(_("can't open `%s': %s\n"), fname, strerror(errno) ); - return; - } - } - - lnr = 0; - err = NULL; - para = NULL; - while( fgets( line, DIM(line)-1, fp ) ) { - char *keyword, *value; - - lnr++; - if( *line && line[strlen(line)-1] != '\n' ) { - err = "line too long"; - break; - } - for( p = line; isspace(*(byte*)p); p++ ) - ; - if( !*p || *p == '#' ) - continue; - keyword = p; - if( *keyword == '%' ) { - for( ; !isspace(*(byte*)p); p++ ) - ; - if( *p ) - *p++ = 0; - for( ; isspace(*(byte*)p); p++ ) - ; - value = p; - trim_trailing_ws( value, strlen(value) ); - if( !ascii_strcasecmp( keyword, "%echo" ) ) - log_info("%s\n", value ); - else if( !ascii_strcasecmp( keyword, "%dry-run" ) ) - outctrl.dryrun = 1; - else if( !ascii_strcasecmp( keyword, "%commit" ) ) { - outctrl.lnr = lnr; - proc_parameter_file( para, fname, &outctrl, 0 ); - release_parameter_list( para ); - para = NULL; - } - else if( !ascii_strcasecmp( keyword, "%pubring" ) ) { - if( outctrl.pub.fname && !strcmp( outctrl.pub.fname, value ) ) - ; /* still the same file - ignore it */ - else { - xfree ( outctrl.pub.newfname ); - outctrl.pub.newfname = xstrdup ( value ); - outctrl.use_files = 1; - } - } - else if( !ascii_strcasecmp( keyword, "%secring" ) ) { - if( outctrl.sec.fname && !strcmp( outctrl.sec.fname, value ) ) - ; /* still the same file - ignore it */ - else { - xfree ( outctrl.sec.newfname ); - outctrl.sec.newfname = xstrdup ( value ); - outctrl.use_files = 1; - } - } - else - log_info("skipping control `%s' (%s)\n", keyword, value ); - - - continue; - } - - - if( !(p = strchr( p, ':' )) || p == keyword ) { - err = "missing colon"; - break; - } - if( *p ) - *p++ = 0; - for( ; isspace(*(byte*)p); p++ ) - ; - if( !*p ) { - err = "missing argument"; - break; - } - value = p; - trim_trailing_ws( value, strlen(value) ); - - for(i=0; keywords[i].name; i++ ) { - if( !ascii_strcasecmp( keywords[i].name, keyword ) ) - break; - } - if( !keywords[i].name ) { - err = "unknown keyword"; - break; - } - if( keywords[i].key != pKEYTYPE && !para ) { - err = "parameter block does not start with \"Key-Type\""; - break; - } - - if( keywords[i].key == pKEYTYPE && para ) { - outctrl.lnr = lnr; - proc_parameter_file( para, fname, &outctrl, 0 ); - release_parameter_list( para ); - para = NULL; - } - else { - for( r = para; r; r = r->next ) { - if( r->key == keywords[i].key ) - break; - } - if( r ) { - err = "duplicate keyword"; - break; - } - } - r = xcalloc (1, sizeof *r + strlen( value ) ); - r->lnr = lnr; - r->key = keywords[i].key; - strcpy( r->u.value, value ); - r->next = para; - para = r; - } - if( err ) - log_error("%s:%d: %s\n", fname, lnr, err ); - else if( ferror(fp) ) { - log_error("%s:%d: read error: %s\n", fname, lnr, strerror(errno) ); - } - else if( para ) { - outctrl.lnr = lnr; - proc_parameter_file( para, fname, &outctrl, 0 ); - } - - if( outctrl.use_files ) { /* close open streams */ - iobuf_close( outctrl.pub.stream ); - iobuf_close( outctrl.sec.stream ); - xfree ( outctrl.pub.fname ); - xfree ( outctrl.pub.newfname ); - xfree ( outctrl.sec.fname ); - xfree ( outctrl.sec.newfname ); - } - - release_parameter_list( para ); - if( strcmp( fname, "-" ) ) - fclose(fp); -} - - -/**************** - * Generate a keypair (fname is only used in batch mode) If - * CARD_SERIALNO is not NULL the fucntion will create the keys on an - * OpenPGP Card. - */ -void -generate_keypair( const char *fname, const char *card_serialno ) -{ - unsigned int nbits; - char *uid = NULL; - DEK *dek; - STRING2KEY *s2k; - int algo; - unsigned int use; - int both = 0; - u32 expire; - struct para_data_s *para = NULL; - struct para_data_s *r; - struct output_control_s outctrl; - - memset (&outctrl, 0, sizeof (outctrl)); - - if (opt.batch && card_serialno) - { - /* We don't yet support unattended key generation. */ - log_error (_("sorry, can't do this in batch mode\n")); - return; - } - - if (opt.batch) - { - read_parameter_file( fname ); - return; - } - - if (card_serialno) - { - r = xcalloc (1, sizeof *r + strlen (card_serialno) ); - r->key = pSERIALNO; - strcpy( r->u.value, card_serialno); - r->next = para; - para = r; - - algo = PUBKEY_ALGO_RSA; - - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYTYPE; - sprintf( r->u.value, "%d", algo ); - r->next = para; - para = r; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYUSAGE; - strcpy (r->u.value, "sign"); - r->next = para; - para = r; - - r = xcalloc (1, sizeof *r + 20 ); - r->key = pSUBKEYTYPE; - sprintf( r->u.value, "%d", algo ); - r->next = para; - para = r; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pSUBKEYUSAGE; - strcpy (r->u.value, "encrypt"); - r->next = para; - para = r; - - r = xcalloc (1, sizeof *r + 20 ); - r->key = pAUTHKEYTYPE; - sprintf( r->u.value, "%d", algo ); - r->next = para; - para = r; - } - else - { - algo = ask_algo (0, &use); - - if (!algo) - { /* default: DSA with ElG subkey of the specified size */ - both = 1; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYTYPE; - sprintf( r->u.value, "%d", PUBKEY_ALGO_DSA ); - r->next = para; - para = r; - tty_printf(_("DSA keypair will have 1024 bits.\n")); - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYLENGTH; - strcpy( r->u.value, "1024" ); - r->next = para; - para = r; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYUSAGE; - strcpy( r->u.value, "sign" ); - r->next = para; - para = r; - - algo = PUBKEY_ALGO_ELGAMAL_E; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pSUBKEYTYPE; - sprintf( r->u.value, "%d", algo ); - r->next = para; - para = r; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pSUBKEYUSAGE; - strcpy( r->u.value, "encrypt" ); - r->next = para; - r->next = para; - para = r; - } - else - { - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYTYPE; - sprintf( r->u.value, "%d", algo ); - r->next = para; - para = r; - - if (use) - { - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYUSAGE; - sprintf( r->u.value, "%s%s", - (use & PUBKEY_USAGE_SIG)? "sign ":"", - (use & PUBKEY_USAGE_ENC)? "encrypt ":"" ); - r->next = para; - para = r; - } - } - - nbits = ask_keysize( algo ); - r = xcalloc (1, sizeof *r + 20 ); - r->key = both? pSUBKEYLENGTH : pKEYLENGTH; - sprintf( r->u.value, "%u", nbits); - r->next = para; - para = r; - } - - expire = ask_expire_interval(0); - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYEXPIRE; - r->u.expire = expire; - r->next = para; - para = r; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pSUBKEYEXPIRE; - r->u.expire = expire; - r->next = para; - para = r; - - uid = ask_user_id(0); - if (!uid) - { - log_error(_("Key generation canceled.\n")); - release_parameter_list( para ); - return; - } - r = xcalloc (1, sizeof *r + strlen(uid) ); - r->key = pUSERID; - strcpy( r->u.value, uid ); - r->next = para; - para = r; - - dek = card_serialno? NULL : ask_passphrase( &s2k ); - if (dek) - { - r = xcalloc (1, sizeof *r ); - r->key = pPASSPHRASE_DEK; - r->u.dek = dek; - r->next = para; - para = r; - r = xcalloc (1, sizeof *r ); - r->key = pPASSPHRASE_S2K; - r->u.s2k = s2k; - r->next = para; - para = r; - } - - proc_parameter_file (para, "[internal]", &outctrl, !!card_serialno); - release_parameter_list (para); -} - - -static void -print_status_key_created (int letter, PKT_public_key *pk) -{ - byte array[MAX_FINGERPRINT_LEN], *s; - char buf[MAX_FINGERPRINT_LEN*2+30], *p; - size_t i, n; - - p = buf; - *p++ = letter; - *p++ = ' '; - fingerprint_from_pk (pk, array, &n); - s = array; - for (i=0; i < n ; i++, s++, p += 2) - sprintf (p, "%02X", *s); - *p = 0; - write_status_text (STATUS_KEY_CREATED, buf); -} - - - -static void -do_generate_keypair (struct para_data_s *para, - struct output_control_s *outctrl, int card) -{ - KBNODE pub_root = NULL; - KBNODE sec_root = NULL; - PKT_secret_key *sk = NULL; - const char *s; - struct revocation_key *revkey; - int rc; - int did_sub = 0; - - if (outctrl->dryrun) - { - log_info ("dry-run mode - key generation skipped\n"); - return; - } - - - if (outctrl->use_files) - { - if (outctrl->pub.newfname) - { - iobuf_close (outctrl->pub.stream); - outctrl->pub.stream = NULL; - xfree (outctrl->pub.fname); - outctrl->pub.fname = outctrl->pub.newfname; - outctrl->pub.newfname = NULL; - - outctrl->pub.stream = iobuf_create (outctrl->pub.fname); - if (!outctrl->pub.stream) - { - log_error ("can't create `%s': %s\n", outctrl->pub.fname, - strerror (errno)); - return; - } - if (opt.armor) - { - outctrl->pub.afx.what = 1; - iobuf_push_filter (outctrl->pub.stream, armor_filter, - &outctrl->pub.afx); - } - } - if (outctrl->sec.newfname) - { - iobuf_close (outctrl->sec.stream); - outctrl->sec.stream = NULL; - xfree (outctrl->sec.fname); - outctrl->sec.fname = outctrl->sec.newfname; - outctrl->sec.newfname = NULL; - - outctrl->sec.stream = iobuf_create (outctrl->sec.fname); - if (!outctrl->sec.stream) - { - log_error ("can't create `%s': %s\n", outctrl->sec.fname, - strerror (errno)); - return; - } - if (opt.armor) - { - outctrl->sec.afx.what = 5; - iobuf_push_filter (outctrl->sec.stream, armor_filter, - &outctrl->sec.afx); - } - } - assert (outctrl->pub.stream); - assert (outctrl->sec.stream); - if (opt.verbose) - { - log_info (_("writing public key to `%s'\n"), outctrl->pub.fname); - if (card) - log_info (_("writing secret key stub to `%s'\n"), - outctrl->sec.fname); - else - log_info (_("writing secret key to `%s'\n"), outctrl->sec.fname); - } - } - - - /* We create the packets as a tree of kbnodes. Because the structure - * we create is known in advance we simply generate a linked list. - * The first packet is a dummy comment packet which we flag - * as deleted. The very first packet must always be a KEY packet. - */ - pub_root = make_comment_node ("#"); - delete_kbnode (pub_root); - sec_root = make_comment_node ("#"); - delete_kbnode (sec_root); - if (!card) - { - rc = do_create (get_parameter_algo (para, pKEYTYPE), - get_parameter_uint (para, pKEYLENGTH), - pub_root, sec_root, - get_parameter_dek (para, pPASSPHRASE_DEK), - get_parameter_s2k (para, pPASSPHRASE_S2K), - &sk, get_parameter_u32 (para, pKEYEXPIRE)); - } - else - { - rc = gen_card_key (PUBKEY_ALGO_RSA, 1, pub_root, sec_root, - get_parameter_u32 (para, pKEYEXPIRE), para); - if (!rc) - { - sk = sec_root->next->pkt->pkt.secret_key; - assert (sk); - } - - } - - if (!rc && (revkey = get_parameter_revkey (para, pREVOKER))) - { - rc = write_direct_sig (pub_root, pub_root, sk, revkey); - if (!rc) - write_direct_sig (sec_root, pub_root, sk, revkey); - } - - if (!rc && (s = get_parameter_value (para, pUSERID))) - { - write_uid (pub_root, s); - if (!rc) - write_uid (sec_root, s); - if (!rc) - rc = write_selfsig (pub_root, pub_root, sk, - get_parameter_uint (para, pKEYUSAGE)); - if (!rc) - rc = write_selfsig (sec_root, pub_root, sk, - get_parameter_uint (para, pKEYUSAGE)); - } - - if ((! rc) && get_parameter (para, pSUBKEYTYPE)) - { - if (!card) - { - rc = do_create (get_parameter_algo (para, pSUBKEYTYPE), - get_parameter_uint (para, pSUBKEYLENGTH), - pub_root, sec_root, - get_parameter_dek (para, pPASSPHRASE_DEK), - get_parameter_s2k (para, pPASSPHRASE_S2K), - NULL, get_parameter_u32 (para, pSUBKEYEXPIRE)); - } - else - { - rc = gen_card_key (PUBKEY_ALGO_RSA, 2, pub_root, sec_root, - get_parameter_u32 (para, pKEYEXPIRE), para); - } - - if (!rc) - rc = write_keybinding (pub_root, pub_root, sk, - get_parameter_uint (para, pSUBKEYUSAGE)); - if (!rc) - rc = write_keybinding (sec_root, pub_root, sk, - get_parameter_uint (para, pSUBKEYUSAGE)); - did_sub = 1; - } - - if ((! rc) && card && get_parameter (para, pAUTHKEYTYPE)) - { - rc = gen_card_key (PUBKEY_ALGO_RSA, 3, pub_root, sec_root, - get_parameter_u32 (para, pKEYEXPIRE), para); - - if (!rc) - rc = write_keybinding (pub_root, pub_root, sk, PUBKEY_USAGE_AUTH); - if (!rc) - rc = write_keybinding (sec_root, pub_root, sk, PUBKEY_USAGE_AUTH); - } - - - if (!rc && outctrl->use_files) - { /* direct write to specified files */ - rc = write_keyblock (outctrl->pub.stream, pub_root); - if (rc) - log_error ("can't write public key: %s\n", gpg_strerror (rc)); - if (!rc) - { - rc = write_keyblock (outctrl->sec.stream, sec_root); - if (rc) - log_error ("can't write secret key: %s\n", gpg_strerror (rc)); - } - - } - else if (!rc) - { /* write to the standard keyrings */ - KEYDB_HANDLE pub_hd = keydb_new (0); - KEYDB_HANDLE sec_hd = keydb_new (1); - - /* FIXME: we may have to create the keyring first */ - rc = keydb_locate_writable (pub_hd, NULL); - if (rc) - log_error (_("no writable public keyring found: %s\n"), - gpg_strerror (rc)); - - if (!rc) - { - rc = keydb_locate_writable (sec_hd, NULL); - if (rc) - log_error (_("no writable secret keyring found: %s\n"), - gpg_strerror (rc)); - } - - if (!rc && opt.verbose) - { - log_info (_("writing public key to `%s'\n"), - keydb_get_resource_name (pub_hd)); - if (card) - log_info (_("writing secret key stub to `%s'\n"), - keydb_get_resource_name (sec_hd)); - else - log_info (_("writing secret key to `%s'\n"), - keydb_get_resource_name (sec_hd)); - } - - if (!rc) - { - rc = keydb_insert_keyblock (pub_hd, pub_root); - if (rc) - log_error (_("error writing public keyring `%s': %s\n"), - keydb_get_resource_name (pub_hd), gpg_strerror (rc)); - } - - if (!rc) - { - rc = keydb_insert_keyblock (sec_hd, sec_root); - if (rc) - log_error (_("error writing secret keyring `%s': %s\n"), - keydb_get_resource_name (pub_hd), gpg_strerror (rc)); - } - - keydb_release (pub_hd); - keydb_release (sec_hd); - - if (!rc) - { - int no_enc_rsa = - get_parameter_algo (para, pKEYTYPE) == PUBKEY_ALGO_RSA - && get_parameter_uint (para, pKEYUSAGE) - && !(get_parameter_uint (para, pKEYUSAGE) & PUBKEY_USAGE_ENC); - PKT_public_key *pk = find_kbnode (pub_root, - PKT_PUBLIC_KEY)->pkt->pkt. - public_key; - - update_ownertrust (pk, - ((get_ownertrust (pk) & ~TRUST_MASK) - | TRUST_ULTIMATE)); - - if (!opt.batch) - { - tty_printf (_("public and secret key created and signed.\n")); - tty_printf (_("key marked as ultimately trusted.\n")); - tty_printf ("\n"); - list_keyblock (pub_root, 0, 1, NULL); - } - - - if (!opt.batch - && (get_parameter_algo (para, pKEYTYPE) == PUBKEY_ALGO_DSA - || no_enc_rsa) && !get_parameter (para, pSUBKEYTYPE)) - { - tty_printf (_("Note that this key cannot be used for " - "encryption. You may want to use\n" - "the command \"--edit-key\" to generate a " - "secondary key for this purpose.\n")); - } - - if (!opt.batch && card) - { - tty_printf(_( -"Please create a revocation certificate now, so that you are able\n" -"to revoke the key if it ever happens that you lose your card or\n" -"the card gets damaged. Use the command \"--gen-revoke\".\n" - )); - } - } - } - - if (rc) - { - if (opt.batch) - log_error ("key generation failed: %s\n", gpg_strerror (rc)); - else - tty_printf (_("Key generation failed: %s\n"), gpg_strerror (rc)); - } - else - { - PKT_public_key *pk = find_kbnode (pub_root, - PKT_PUBLIC_KEY)->pkt->pkt.public_key; - print_status_key_created (did_sub ? 'B' : 'P', pk); - } - - release_kbnode (pub_root); - release_kbnode (sec_root); - if (sk && !card) /* The unprotected secret key unless we have */ - free_secret_key (sk); /* a shallow copy in card mode. */ -} - - -/**************** - * add a new subkey to an existing key. - * Returns true if a new key has been generated and put into the keyblocks. - */ -int -generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - int okay=0, rc=0; - KBNODE node; - PKT_secret_key *sk = NULL; /* this is the primary sk */ - int algo; - unsigned int use; - u32 expire; - unsigned nbits; - char *passphrase = NULL; - DEK *dek = NULL; - STRING2KEY *s2k = NULL; - u32 cur_time; - - /* break out the primary secret key */ - node = find_kbnode( sec_keyblock, PKT_SECRET_KEY ); - if( !node ) { - log_error("Oops; secret key not found anymore!\n"); - goto leave; - } - - /* make a copy of the sk to keep the protected one in the keyblock */ - sk = copy_secret_key( NULL, node->pkt->pkt.secret_key ); - - cur_time = make_timestamp(); - if( sk->timestamp > cur_time ) { - ulong d = sk->timestamp - cur_time; - log_info( d==1 ? _("key has been created %lu second " - "in future (time warp or clock problem)\n") - : _("key has been created %lu seconds " - "in future (time warp or clock problem)\n"), d ); - if( !opt.ignore_time_conflict ) { - rc = GPG_ERR_TIME_CONFLICT; - goto leave; - } - } - - if (sk->version < 4) { - log_info (_("NOTE: creating subkeys for v3 keys " - "is not OpenPGP compliant\n")); - goto leave; - } - - /* unprotect to get the passphrase */ - switch( is_secret_key_protected( sk ) ) { - case -1: - rc = GPG_ERR_PUBKEY_ALGO; - break; - case 0: - tty_printf("This key is not protected.\n"); - break; - default: - tty_printf("Key is protected.\n"); - rc = check_secret_key( sk, 0 ); - if( !rc ) - passphrase = get_last_passphrase(); - break; - } - if( rc ) - goto leave; - - - algo = ask_algo( 1, &use ); - assert(algo); - nbits = ask_keysize( algo ); - expire = ask_expire_interval(0); - if( !cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay", - _("Really create? ") ) ) - goto leave; - - if( passphrase ) { - s2k = xmalloc_secure ( sizeof *s2k ); - s2k->mode = opt.s2k_mode; - s2k->hash_algo = opt.s2k_digest_algo; - set_next_passphrase( passphrase ); - dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2, - NULL, NULL ); - } - - rc = do_create( algo, nbits, pub_keyblock, sec_keyblock, - dek, s2k, NULL, expire ); - if( !rc ) - rc = write_keybinding(pub_keyblock, pub_keyblock, sk, use); - if( !rc ) - rc = write_keybinding(sec_keyblock, pub_keyblock, sk, use); - if( !rc ) { - okay = 1; - write_status_text (STATUS_KEY_CREATED, "S"); - } - - leave: - if( rc ) - log_error(_("Key generation failed: %s\n"), gpg_strerror (rc) ); - xfree ( passphrase ); - xfree ( dek ); - xfree ( s2k ); - if( sk ) /* release the copy of the (now unprotected) secret key */ - free_secret_key(sk); - set_next_passphrase( NULL ); - return okay; -} - -/**************** - * Write a keyblock to an output stream - */ -static int -write_keyblock( iobuf_t out, KBNODE node ) -{ - for( ; node ; node = node->next ) { - int rc = build_packet( out, node->pkt ); - if( rc ) { - log_error("build_packet(%d) failed: %s\n", - node->pkt->pkttype, gpg_strerror (rc) ); - return rc; - } - } - return 0; -} - - - -static int -gen_card_key (int algo, int keyno, KBNODE pub_root, KBNODE sec_root, - u32 expireval, struct para_data_s *para) -{ - int rc; - const char *s; - struct agent_card_genkey_s info; - PACKET *pkt; - PKT_secret_key *sk; - PKT_public_key *pk; - - assert (algo == PUBKEY_ALGO_RSA); - - rc = agent_scd_genkey (&info, keyno, 1); -/* if (gpg_err_code (rc) == GPG_ERR_EEXIST) */ -/* { */ -/* tty_printf ("\n"); */ -/* log_error ("WARNING: key does already exists!\n"); */ -/* tty_printf ("\n"); */ -/* if ( cpr_get_answer_is_yes( "keygen.card.replace_key", */ -/* _("Replace existing key? "))) */ -/* rc = agent_scd_genkey (&info, keyno, 1); */ -/* } */ - - if (rc) - return rc; - - if ( !info.n || !info.e ) - { - log_error ("communication error with SCD\n"); - gcry_mpi_release (info.n); - gcry_mpi_release (info.e); - return gpg_error (GPG_ERR_GENERAL); - } - - - pk = xcalloc (1, sizeof *pk ); - sk = xcalloc (1, sizeof *sk ); - sk->timestamp = pk->timestamp = info.created_at; - sk->version = pk->version = 4; - if (expireval) - sk->expiredate = pk->expiredate = pk->timestamp + expireval; - sk->pubkey_algo = pk->pubkey_algo = algo; - pk->pkey[0] = info.n; - pk->pkey[1] = info.e; - sk->skey[0] = gcry_mpi_copy (pk->pkey[0]); - sk->skey[1] = gcry_mpi_copy (pk->pkey[1]); - sk->skey[2] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8); - sk->is_protected = 1; - sk->protect.s2k.mode = 1002; - s = get_parameter_value (para, pSERIALNO); - if (s) - { - for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1]; - sk->protect.ivlen++, s += 2) - sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s); - } - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = keyno == 1 ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY; - pkt->pkt.public_key = pk; - add_kbnode(pub_root, new_kbnode( pkt )); - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = keyno == 1 ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY; - pkt->pkt.secret_key = sk; - add_kbnode(sec_root, new_kbnode( pkt )); - - return 0; -} - - - diff --git a/g10/keyid.c b/g10/keyid.c deleted file mode 100644 index aaa70cccb..000000000 --- a/g10/keyid.c +++ /dev/null @@ -1,609 +0,0 @@ -/* keyid.c - key ID and fingerprint handling - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "main.h" -#include "packet.h" -#include "options.h" -#include "mpi.h" -#include "keydb.h" -#include "i18n.h" - - -int -pubkey_letter( int algo ) -{ - switch( algo ) { - case PUBKEY_ALGO_RSA: return 'R' ; - case PUBKEY_ALGO_RSA_E: return 'r' ; - case PUBKEY_ALGO_RSA_S: return 's' ; - case PUBKEY_ALGO_ELGAMAL_E: return 'g'; - case PUBKEY_ALGO_ELGAMAL: return 'G' ; - case PUBKEY_ALGO_DSA: return 'D' ; - default: return '?'; - } -} - -static gcry_md_hd_t -do_fingerprint_md( PKT_public_key *pk ) -{ - gcry_md_hd_t md; - unsigned int n; - unsigned int nn[PUBKEY_MAX_NPKEY]; - byte *pp[PUBKEY_MAX_NPKEY]; - int i; - int npkey = pubkey_get_npkey( pk->pubkey_algo ); - - gcry_md_open (&md, pk->version < 4 ? DIGEST_ALGO_RMD160 - : DIGEST_ALGO_SHA1, 0); - - n = pk->version < 4 ? 8 : 6; - for(i=0; i < npkey; i++ ) { - size_t nbytes; - - if (gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i] )) - BUG (); - /* fixme: we should try to allocate a buffer on the stack */ - pp[i] = xmalloc(nbytes); - if (gcry_mpi_print ( GCRYMPI_FMT_PGP, pp[i], nbytes, &nbytes, - pk->pkey[i] )) - BUG (); - nn[i] = nbytes; - n += nn[i]; - } - - gcry_md_putc ( md, 0x99 ); /* ctb */ - gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */ - gcry_md_putc ( md, n ); - if( pk->version < 4 ) - gcry_md_putc ( md, 3 ); - else - gcry_md_putc ( md, 4 ); - - { u32 a = pk->timestamp; - gcry_md_putc ( md, a >> 24 ); - gcry_md_putc ( md, a >> 16 ); - gcry_md_putc ( md, a >> 8 ); - gcry_md_putc ( md, a ); - } - if( pk->version < 4 ) { - u16 a; - - if( pk->expiredate ) - a = (u16)((pk->expiredate - pk->timestamp) / 86400L); - else - a = 0; - gcry_md_putc ( md, a >> 8 ); - gcry_md_putc ( md, a ); - } - gcry_md_putc ( md, pk->pubkey_algo ); - for(i=0; i < npkey; i++ ) { - gcry_md_write( md, pp[i], nn[i] ); - xfree (pp[i]); - } - gcry_md_final ( md ); - - return md; -} - -static gcry_md_hd_t -do_fingerprint_md_sk( PKT_secret_key *sk ) -{ - PKT_public_key pk; - int npkey = pubkey_get_npkey( sk->pubkey_algo ); /* npkey is correct! */ - int i; - - pk.pubkey_algo = sk->pubkey_algo; - pk.version = sk->version; - pk.timestamp = sk->timestamp; - pk.expiredate = sk->expiredate; - pk.pubkey_algo = sk->pubkey_algo; - for( i=0; i < npkey; i++ ) - pk.pkey[i] = sk->skey[i]; - return do_fingerprint_md( &pk ); -} - - -u32 -v3_keyid (gcry_mpi_t a, u32 *ki) -{ - byte *buffer; - size_t nbytes; - - if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nbytes, a )) - BUG (); - /* fixme: allocate it on the stack */ - buffer = xmalloc (nbytes); - if (gcry_mpi_print( GCRYMPI_FMT_USG, buffer, nbytes, NULL, a )) - BUG (); - if (nbytes < 8) /* oops */ - ki[0] = ki[1] = 0; - else - { - memcpy (ki+0, buffer+nbytes-8, 4); - memcpy (ki+1, buffer+nbytes-4, 4); - } - xfree (buffer); - return ki[1]; -} - - - -/**************** - * Get the keyid from the secret key and put it into keyid - * if this is not NULL. Return the 32 low bits of the keyid. - */ -u32 -keyid_from_sk( PKT_secret_key *sk, u32 *keyid ) -{ - u32 lowbits; - u32 dummy_keyid[2]; - - if( !keyid ) - keyid = dummy_keyid; - - if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) { - keyid[0] = keyid[1] = 0; - lowbits = pubkey_get_npkey(sk->pubkey_algo) ? - v3_keyid (sk->skey[0], keyid) : 0; - } - else { - const byte *dp; - gcry_md_hd_t md; - md = do_fingerprint_md_sk(sk); - dp = gcry_md_read ( md, 0 ); - keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; - keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; - lowbits = keyid[1]; - gcry_md_close (md); - } - - return lowbits; -} - - -/**************** - * Get the keyid from the public key and put it into keyid - * if this is not NULL. Return the 32 low bits of the keyid. - */ -u32 -keyid_from_pk( PKT_public_key *pk, u32 *keyid ) -{ - u32 lowbits; - u32 dummy_keyid[2]; - - if( !keyid ) - keyid = dummy_keyid; - - if( pk->keyid[0] || pk->keyid[1] ) { - keyid[0] = pk->keyid[0]; - keyid[1] = pk->keyid[1]; - lowbits = keyid[1]; - } - else if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) { - keyid[0] = keyid[1] = 0; - lowbits = pubkey_get_npkey(pk->pubkey_algo) ? - v3_keyid (pk->pkey[0], keyid) : 0 ; - pk->keyid[0] = keyid[0]; - pk->keyid[1] = keyid[1]; - } - else { - const byte *dp; - gcry_md_hd_t md; - md = do_fingerprint_md(pk); - dp = gcry_md_read ( md, 0 ); - keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; - keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; - lowbits = keyid[1]; - gcry_md_close (md); - pk->keyid[0] = keyid[0]; - pk->keyid[1] = keyid[1]; - } - - return lowbits; -} - - -/**************** - * Get the keyid from the fingerprint. This function is simple for most - * keys, but has to do a keylookup for old stayle keys. - */ -u32 -keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid ) -{ - u32 dummy_keyid[2]; - - if( !keyid ) - keyid = dummy_keyid; - - if( fprint_len != 20 ) { - /* This is special as we have to lookup the key first */ - PKT_public_key pk; - int rc; - - memset( &pk, 0, sizeof pk ); - rc = get_pubkey_byfprint( &pk, fprint, fprint_len ); - if( rc ) { - log_error("Oops: keyid_from_fingerprint: no pubkey\n"); - keyid[0] = 0; - keyid[1] = 0; - } - else - keyid_from_pk( &pk, keyid ); - } - else { - const byte *dp = fprint; - keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; - keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; - } - - return keyid[1]; -} - - -u32 -keyid_from_sig( PKT_signature *sig, u32 *keyid ) -{ - if( keyid ) { - keyid[0] = sig->keyid[0]; - keyid[1] = sig->keyid[1]; - } - return sig->keyid[1]; -} - -byte * -namehash_from_uid(PKT_user_id *uid) -{ - if(uid->namehash==NULL) - { - uid->namehash=xmalloc (20); - - if(uid->attrib_data) - gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash, - uid->attrib_data,uid->attrib_len); - else - gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash, - uid->name,uid->len); - } - - return uid->namehash; -} - -/**************** - * return the number of bits used in the pk - */ -unsigned -nbits_from_pk( PKT_public_key *pk ) -{ - return pubkey_nbits( pk->pubkey_algo, pk->pkey ); -} - -/**************** - * return the number of bits used in the sk - */ -unsigned -nbits_from_sk( PKT_secret_key *sk ) -{ - return pubkey_nbits( sk->pubkey_algo, sk->skey ); -} - -static const char * -mk_datestr (char *buffer, time_t atime) -{ - struct tm *tp; - - if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */ - strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */ - else { - tp = gmtime (&atime); - sprintf (buffer,"%04d-%02d-%02d", - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday ); - } - return buffer; -} - -/**************** - * return a string with the creation date of the pk - * Note: this is alloced in a static buffer. - * Format is: yyyy-mm-dd - */ -const char * -datestr_from_pk( PKT_public_key *pk ) -{ - static char buffer[11+5]; - time_t atime = pk->timestamp; - - return mk_datestr (buffer, atime); -} - -const char * -datestr_from_sk( PKT_secret_key *sk ) -{ - static char buffer[11+5]; - time_t atime = sk->timestamp; - - return mk_datestr (buffer, atime); -} - -const char * -datestr_from_sig( PKT_signature *sig ) -{ - static char buffer[11+5]; - time_t atime = sig->timestamp; - - return mk_datestr (buffer, atime); -} - -const char * -expirestr_from_pk( PKT_public_key *pk ) -{ - static char buffer[11+5]; - time_t atime; - - if( !pk->expiredate ) - return _("never "); - atime = pk->expiredate; - return mk_datestr (buffer, atime); -} - -const char * -expirestr_from_sk( PKT_secret_key *sk ) -{ - static char buffer[11+5]; - time_t atime; - - if( !sk->expiredate ) - return _("never "); - atime = sk->expiredate; - return mk_datestr (buffer, atime); -} - -const char * -expirestr_from_sig( PKT_signature *sig ) -{ - static char buffer[11+5]; - time_t atime; - - if(!sig->expiredate) - return _("never "); - atime=sig->expiredate; - return mk_datestr (buffer, atime); -} - -const char * -colon_strtime (u32 t) -{ - if (!t) - return ""; - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)t); - return buf; - } - return strtimestamp(t); -} - -const char * -colon_datestr_from_pk (PKT_public_key *pk) -{ - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)pk->timestamp); - return buf; - } - return datestr_from_pk (pk); -} - -const char * -colon_datestr_from_sk (PKT_secret_key *sk) -{ - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)sk->timestamp); - return buf; - } - return datestr_from_sk (sk); -} - -const char * -colon_datestr_from_sig (PKT_signature *sig) -{ - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)sig->timestamp); - return buf; - } - return datestr_from_sig (sig); -} - -const char * -colon_expirestr_from_sig (PKT_signature *sig) -{ - if(!sig->expiredate) - return ""; - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)sig->expiredate); - return buf; - } - return expirestr_from_sig (sig); -} - - -/**************** . - * Return a byte array with the fingerprint for the given PK/SK - * The length of the array is returned in ret_len. Caller must free - * the array or provide an array of length MAX_FINGERPRINT_LEN. - */ - -byte * -fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len ) -{ - byte *buf; - const byte *dp; - size_t len; - - if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) { - /* RSA in version 3 packets is special */ - gcry_md_hd_t md; - - gcry_md_open (&md, DIGEST_ALGO_MD5, 0); - if( pubkey_get_npkey( pk->pubkey_algo ) > 1 ) { - size_t nbytes; - - if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, - pk->pkey[0])) - BUG (); - /* fixme: allocate it on the stack */ - buf = xmalloc(nbytes); - if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes, NULL,pk->pkey[0])) - BUG (); - gcry_md_write (md, buf, nbytes); - xfree (buf); - if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, pk->pkey[1])) - BUG (); - /* fixme: allocate it on the stack */ - buf = xmalloc(nbytes); - if (gcry_mpi_print( GCRYMPI_FMT_USG, buf, nbytes, NULL,pk->pkey[1])) - BUG (); - gcry_md_write( md, buf, nbytes ); - xfree(buf); - } - gcry_md_final (md); - if( !array ) - array = xmalloc ( 16 ); - len = 16; - memcpy(array, gcry_md_read (md, DIGEST_ALGO_MD5), 16 ); - gcry_md_close (md); - } - else { - gcry_md_hd_t md; - md = do_fingerprint_md(pk); - dp = gcry_md_read ( md, 0 ); - len = gcry_md_get_algo_dlen (gcry_md_get_algo (md)); - assert( len <= MAX_FINGERPRINT_LEN ); - if( !array ) - array = xmalloc ( len ); - memcpy(array, dp, len ); - pk->keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; - pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; - gcry_md_close (md); - } - - *ret_len = len; - return array; -} - -byte * -fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len ) -{ - byte *buf; - const char *dp; - size_t len; - - if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) { - /* RSA in version 3 packets is special */ - gcry_md_hd_t md; - - gcry_md_open (&md, DIGEST_ALGO_MD5, 0); - if( pubkey_get_npkey( sk->pubkey_algo ) > 1 ) { - size_t nbytes; - - if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, sk->skey[0])) - BUG (); - /* fixme: allocate it on the stack */ - buf = xmalloc(nbytes); - if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes, NULL,sk->skey[0])) - BUG (); - gcry_md_write (md, buf, nbytes); - xfree (buf); - if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, sk->skey[1])) - BUG (); - /* fixme: allocate it on the stack */ - buf = xmalloc(nbytes); - if (gcry_mpi_print( GCRYMPI_FMT_USG, buf,nbytes, NULL, sk->skey[1])) - BUG (); - gcry_md_write( md, buf, nbytes ); - xfree(buf); - } - gcry_md_final (md); - if( !array ) - array = xmalloc ( 16 ); - len = 16; - memcpy(array, gcry_md_read (md, DIGEST_ALGO_MD5), 16 ); - gcry_md_close (md); - } - else { - gcry_md_hd_t md; - - md = do_fingerprint_md_sk(sk); - dp = gcry_md_read ( md, 0 ); - len = gcry_md_get_algo_dlen (gcry_md_get_algo (md)); - assert( len <= MAX_FINGERPRINT_LEN ); - if( !array ) - array = xmalloc ( len ); - memcpy(array, dp, len ); - gcry_md_close (md); - } - - *ret_len = len; - return array; -} - - -/* Create a serialno/fpr string from the serial number and the secret - * key. caller must free the returned string. There is no error - * return. */ -char * -serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen, - PKT_secret_key *sk) -{ - unsigned char fpr[MAX_FINGERPRINT_LEN]; - size_t fprlen; - char *buffer, *p; - int i; - - fingerprint_from_sk (sk, fpr, &fprlen); - buffer = p= xmalloc (snlen*2 + 1 + fprlen*2 + 1); - for (i=0; i < snlen; i++, p+=2) - sprintf (p, "%02X", sn[i]); - *p++ = '/'; - for (i=0; i < fprlen; i++, p+=2) - sprintf (p, "%02X", fpr[i]); - *p = 0; - return buffer; -} - - - - - - - - diff --git a/g10/keylist.c b/g10/keylist.c deleted file mode 100644 index 50850de71..000000000 --- a/g10/keylist.c +++ /dev/null @@ -1,1466 +0,0 @@ -/* keylist.c - List all or selected keys - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "keydb.h" -#include "memory.h" -#include "photoid.h" -#include "util.h" -#include "ttyio.h" -#include "trustdb.h" -#include "main.h" -#include "i18n.h" -#include "status.h" - -static void list_all(int); -static void list_one( STRLIST names, int secret); -static void print_card_serialno (PKT_secret_key *sk); - -struct sig_stats -{ - int inv_sigs; - int no_key; - int oth_err; -}; - -static FILE *attrib_fp=NULL; - -/**************** - * List the keys - * If list is NULL, all available keys are listed - */ -void -public_key_list( STRLIST list ) -{ - if(opt.with_colons) - { - byte trust_model,marginals,completes,cert_depth; - ulong created,nextcheck; - - read_trust_options(&trust_model,&created,&nextcheck, - &marginals,&completes,&cert_depth); - - printf("tru:"); - - if(nextcheck && nextcheck <= make_timestamp()) - printf("o"); - if(trust_model!=opt.trust_model) - printf("t"); - if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC) - { - if(marginals!=opt.marginals_needed) - printf("m"); - if(completes!=opt.completes_needed) - printf("c"); - if(cert_depth!=opt.max_cert_depth) - printf("d"); - } - - printf(":%d:%lu:%lu",trust_model,created,nextcheck); - - /* Only show marginals, completes, and cert_depth in the classic - or PGP trust models since they are not meaningful - otherwise. */ - - if(trust_model==TM_PGP || trust_model==TM_CLASSIC) - printf(":%d:%d:%d",marginals,completes,cert_depth); - - printf("\n"); - } - - if( !list ) - list_all(0); - else - list_one( list, 0 ); -} - -void -secret_key_list( STRLIST list ) -{ - if( !list ) - list_all(1); - else /* List by user id */ - list_one( list, 1 ); -} - -void -print_seckey_info (PKT_secret_key *sk) -{ - u32 sk_keyid[2]; - size_t n; - char *p; - - keyid_from_sk (sk, sk_keyid); - tty_printf ("\nsec %4u%c/%08lX %s ", - nbits_from_sk (sk), - pubkey_letter (sk->pubkey_algo), - (ulong)sk_keyid[1], datestr_from_sk (sk)); - - p = get_user_id (sk_keyid, &n); - tty_print_utf8_string (p, n); - xfree (p); - - tty_printf ("\n"); -} - -/* Print information about the public key. With FP passed as NULL, - the tty output interface is used, otherwise output is directted to - the given stream. */ -void -print_pubkey_info (FILE *fp, PKT_public_key *pk) -{ - u32 pk_keyid[2]; - size_t n; - char *p; - - keyid_from_pk (pk, pk_keyid); - if (fp) - fprintf (fp, "pub %4u%c/%08lX %s ", - nbits_from_pk (pk), - pubkey_letter (pk->pubkey_algo), - (ulong)pk_keyid[1], datestr_from_pk (pk)); - else - tty_printf ("\npub %4u%c/%08lX %s ", - nbits_from_pk (pk), - pubkey_letter (pk->pubkey_algo), - (ulong)pk_keyid[1], datestr_from_pk (pk)); - - p = get_user_id (pk_keyid, &n); - if (fp) - print_utf8_string2 (fp, p, n, '\n'); - else - tty_print_utf8_string (p, n); - xfree (p); - - if (fp) - putc ('\n', fp); - else - tty_printf ("\n\n"); -} - -/* - mode=0 for stdout. - mode=1 for log_info + status messages - mode=2 for status messages only -*/ - -void -show_policy_url(PKT_signature *sig,int indent,int mode) -{ - const byte *p; - size_t len; - int seq=0,crit; - FILE *fp=mode?log_get_stream():stdout; - - while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,&len,&seq,&crit))) - { - if(mode!=2) - { - int i; - char *str; - - for(i=0;i<indent;i++) - putchar(' '); - - if(crit) - str=_("Critical signature policy: "); - else - str=_("Signature policy: "); - if(mode) - log_info("%s",str); - else - printf("%s",str); - print_utf8_string(fp,p,len); - fprintf(fp,"\n"); - } - - if(mode) - write_status_buffer ( STATUS_POLICY_URL, p, len, 0 ); - } -} - - -/* - mode=0 for stdout. - mode=1 for log_info + status messages - mode=2 for status messages only -*/ -/* TODO: use this */ -void -show_keyserver_url(PKT_signature *sig,int indent,int mode) -{ - const byte *p; - size_t len; - int seq=0,crit; - FILE *fp=mode?log_get_stream():stdout; - - while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&len,&seq,&crit))) - { - if(mode!=2) - { - int i; - char *str; - - for(i=0;i<indent;i++) - putchar(' '); - - if(crit) - str=_("Critical preferred keyserver: "); - else - str=_("Preferred keyserver: "); - if(mode) - log_info("%s",str); - else - printf("%s",str); - print_utf8_string(fp,p,len); - fprintf(fp,"\n"); - } - - /* TODO: put in a status-fd tag for preferred keyservers */ - } -} - - -/* - mode=0 for stdout. - mode=1 for log_info + status messages - mode=2 for status messages only -*/ - -void -show_notation(PKT_signature *sig,int indent,int mode) -{ - const byte *p; - size_t len; - int seq=0,crit; - FILE *fp=mode?log_get_stream():stdout; - - /* There may be multiple notations in the same sig. */ - - while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&len,&seq,&crit))) - if(len>=8) - { - int n1,n2; - - n1=(p[4]<<8)|p[5]; - n2=(p[6]<<8)|p[7]; - - if(8+n1+n2!=len) - { - log_info(_("WARNING: invalid notation data found\n")); - return; - } - - if(mode!=2) - { - int i; - char *str; - - for(i=0;i<indent;i++) - putchar(' '); - - /* This is UTF8 */ - if(crit) - str=_("Critical signature notation: "); - else - str=_("Signature notation: "); - if(mode) - log_info("%s",str); - else - printf("%s",str); - print_utf8_string(fp,p+8,n1); - fprintf(fp,"="); - - if(*p&0x80) - print_utf8_string(fp,p+8+n1,n2); - else - fprintf(fp,"[ %s ]",_("not human readable")); - - fprintf(fp,"\n"); - } - - if(mode) - { - write_status_buffer ( STATUS_NOTATION_NAME, p+8 , n1, 0 ); - write_status_buffer ( STATUS_NOTATION_DATA, p+8+n1, n2, 50 ); - } - } - else - log_info(_("WARNING: invalid notation data found\n")); -} - -static void -print_signature_stats(struct sig_stats *s) -{ - if( s->inv_sigs == 1 ) - tty_printf(_("1 bad signature\n") ); - else if( s->inv_sigs ) - tty_printf(_("%d bad signatures\n"), s->inv_sigs ); - if( s->no_key == 1 ) - tty_printf(_("1 signature not checked due to a missing key\n") ); - else if( s->no_key ) - tty_printf(_("%d signatures not checked due to missing keys\n"),s->no_key); - if( s->oth_err == 1 ) - tty_printf(_("1 signature not checked due to an error\n") ); - else if( s->oth_err ) - tty_printf(_("%d signatures not checked due to errors\n"), s->oth_err ); -} - -static void -list_all( int secret ) -{ - KEYDB_HANDLE hd; - KBNODE keyblock = NULL; - int rc=0; - const char *lastresname, *resname; - struct sig_stats stats; - - memset(&stats,0,sizeof(stats)); - - hd = keydb_new (secret); - if (!hd) - rc = GPG_ERR_GENERAL; - else - rc = keydb_search_first (hd); - if( rc ) { - if( rc != -1 ) - log_error("keydb_search_first failed: %s\n", gpg_strerror (rc) ); - goto leave; - } - - lastresname = NULL; - do { - rc = keydb_get_keyblock (hd, &keyblock); - if (rc) { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if(!opt.with_colons) - { - resname = keydb_get_resource_name (hd); - if (lastresname != resname ) - { - int i; - - printf("%s\n", resname ); - for(i=strlen(resname); i; i-- ) - putchar('-'); - putchar('\n'); - lastresname = resname; - } - } - merge_keys_and_selfsig( keyblock ); - list_keyblock( keyblock, secret, opt.fingerprint, - opt.check_sigs?&stats:NULL); - release_kbnode( keyblock ); - keyblock = NULL; - } while (!(rc = keydb_search_next (hd))); - if( rc && rc != -1 ) - log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc)); - - if(opt.check_sigs && !opt.with_colons) - print_signature_stats(&stats); - - leave: - release_kbnode (keyblock); - keydb_release (hd); -} - - -static void -list_one( STRLIST names, int secret ) -{ - int rc = 0; - KBNODE keyblock = NULL; - GETKEY_CTX ctx; - const char *resname; - char *keyring_str = _("Keyring"); - int i; - struct sig_stats stats; - - memset(&stats,0,sizeof(stats)); - - /* fixme: using the bynames function has the disadvantage that we - * don't know wether one of the names given was not found. OTOH, - * this function has the advantage to list the names in the - * sequence as defined by the keyDB and does not duplicate - * outputs. A solution could be do test whether all given have - * been listed (this needs a way to use the keyDB search - * functions) or to have the search function return indicators for - * found names. Yet another way is to use the keydb search - * facilities directly. */ - if( secret ) { - rc = get_seckey_bynames( &ctx, NULL, names, &keyblock ); - if( rc ) { - log_error("error reading key: %s\n", gpg_strerror (rc) ); - get_seckey_end( ctx ); - return; - } - do { - if ((opt.list_options&LIST_SHOW_KEYRING) && !opt.with_colons) { - resname = keydb_get_resource_name (get_ctx_handle(ctx)); - printf("%s: %s\n", keyring_str, resname); - for(i = strlen(resname) + strlen(keyring_str) + 2; i; i-- ) - putchar('-'); - putchar('\n'); - } - list_keyblock( keyblock, 1, opt.fingerprint, NULL ); - release_kbnode( keyblock ); - } while( !get_seckey_next( ctx, NULL, &keyblock ) ); - get_seckey_end( ctx ); - } - else { - rc = get_pubkey_bynames( &ctx, NULL, names, &keyblock ); - if( rc ) { - log_error("error reading key: %s\n", gpg_strerror (rc) ); - get_pubkey_end( ctx ); - return; - } - do { - if ((opt.list_options&LIST_SHOW_KEYRING) && !opt.with_colons) { - resname = keydb_get_resource_name (get_ctx_handle(ctx)); - printf("%s: %s\n", keyring_str, resname); - for(i = strlen(resname) + strlen(keyring_str) + 2; i; i-- ) - putchar('-'); - putchar('\n'); - } - list_keyblock( keyblock, 0, opt.fingerprint, - opt.check_sigs?&stats:NULL ); - release_kbnode( keyblock ); - } while( !get_pubkey_next( ctx, NULL, &keyblock ) ); - get_pubkey_end( ctx ); - } - - if(opt.check_sigs && !opt.with_colons) - print_signature_stats(&stats); -} - -static void -print_key_data( PKT_public_key *pk, u32 *keyid ) -{ - int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0; - int i; - - for(i=0; i < n; i++ ) { - printf("pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) ); - mpi_print(stdout, pk->pkey[i], 1 ); - putchar(':'); - putchar('\n'); - } -} - -static void -print_capabilities (PKT_public_key *pk, PKT_secret_key *sk, KBNODE keyblock) -{ - if(pk || (sk && sk->protect.s2k.mode!=1001)) - { - unsigned int use = pk? pk->pubkey_usage : sk->pubkey_usage; - - if ( (use & PUBKEY_USAGE_ENC) ) - putchar ('e'); - - if ( (use & PUBKEY_USAGE_SIG) ) - { - putchar ('s'); - if( pk? pk->is_primary : sk->is_primary ) - putchar ('c'); - } - - if ( (use & PUBKEY_USAGE_AUTH) ) - putchar ('a'); - } - - if ( keyblock ) { /* figure out the usable capabilities */ - KBNODE k; - int enc=0, sign=0, cert=0, auth=0, disabled=0; - - for (k=keyblock; k; k = k->next ) { - if ( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - pk = k->pkt->pkt.public_key; - - if(pk->is_primary) - disabled=pk_is_disabled(pk); - - if ( pk->is_valid && !pk->is_revoked && !pk->has_expired ) { - if ( (pk->pubkey_usage & PUBKEY_USAGE_ENC) ) - enc = 1; - if ( (pk->pubkey_usage & PUBKEY_USAGE_SIG) ) - { - sign = 1; - if(pk->is_primary) - cert = 1; - } - if ( (pk->pubkey_usage & PUBKEY_USAGE_AUTH) ) - auth = 1; - } - } - else if ( k->pkt->pkttype == PKT_SECRET_KEY - || k->pkt->pkttype == PKT_SECRET_SUBKEY ) { - sk = k->pkt->pkt.secret_key; - if ( sk->is_valid && !sk->is_revoked && !sk->has_expired - && sk->protect.s2k.mode!=1001 ) { - if ( (sk->pubkey_usage & PUBKEY_USAGE_ENC) ) - enc = 1; - if ( (sk->pubkey_usage & PUBKEY_USAGE_SIG) ) - { - sign = 1; - if(sk->is_primary) - cert = 1; - } - if ( (sk->pubkey_usage & PUBKEY_USAGE_AUTH) ) - auth = 1; - } - } - } - if (enc) - putchar ('E'); - if (sign) - putchar ('S'); - if (cert) - putchar ('C'); - if (auth) - putchar ('A'); - if (disabled) - putchar ('D'); - } - - putchar(':'); -} - -void -dump_attribs(const PKT_user_id *uid,PKT_public_key *pk,PKT_secret_key *sk) -{ - int i; - - if(!attrib_fp) - return; - - for(i=0;i<uid->numattribs;i++) - { - if(is_status_enabled()) - { - byte array[MAX_FINGERPRINT_LEN], *p; - char buf[(MAX_FINGERPRINT_LEN*2)+90]; - size_t j,n; - - if(pk) - fingerprint_from_pk( pk, array, &n ); - else if(sk) - fingerprint_from_sk( sk, array, &n ); - else - BUG(); - - p = array; - for(j=0; j < n ; j++, p++ ) - sprintf(buf+2*j, "%02X", *p ); - - sprintf(buf+strlen(buf)," %lu %u %u %u %lu %lu %u", - (ulong)uid->attribs[i].len,uid->attribs[i].type,i+1, - uid->numattribs,(ulong)uid->created,(ulong)uid->expiredate, - ((uid->is_primary?0x01:0)| - (uid->is_revoked?0x02:0)| - (uid->is_expired?0x04:0))); - write_status_text(STATUS_ATTRIBUTE,buf); - } - - fwrite(uid->attribs[i].data,uid->attribs[i].len,1,attrib_fp); - } -} - -static void -list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque ) -{ - int rc = 0; - KBNODE kbctx; - KBNODE node; - PKT_public_key *pk; - PKT_secret_key *sk; - u32 keyid[2]; - int any=0; - struct sig_stats *stats=opaque; - int newformat=((opt.list_options&LIST_SHOW_VALIDITY) && !secret) - || (opt.list_options&LIST_SHOW_LONG_KEYID); - - /* get the keyid from the keyblock */ - node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY ); - if( !node ) { - log_error("Oops; key lost!\n"); - dump_kbnode( keyblock ); - return; - } - - if( secret ) - { - pk = NULL; - sk = node->pkt->pkt.secret_key; - keyid_from_sk( sk, keyid ); - - printf("sec%c %4u%c/",(sk->protect.s2k.mode==1001)?'#':' ', - nbits_from_sk( sk ),pubkey_letter( sk->pubkey_algo )); - - if(opt.list_options&LIST_SHOW_LONG_KEYID) - printf("%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]); - else - printf("%08lX",(ulong)keyid[1]); - - printf(" %s%s",datestr_from_sk( sk ),newformat?"":" " ); - - if(newformat && sk->expiredate ) - printf(_(" [expires: %s]"), expirestr_from_sk( sk ) ); - } - else - { - int validity; - pk = node->pkt->pkt.public_key; - sk = NULL; - keyid_from_pk( pk, keyid ); - - validity=get_validity(pk,NULL); - - printf("pub %4u%c/", - nbits_from_pk(pk),pubkey_letter(pk->pubkey_algo)); - - if(opt.list_options&LIST_SHOW_LONG_KEYID) - printf("%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]); - else - printf("%08lX",(ulong)keyid[1]); - - printf(" %s%s",datestr_from_pk( pk ),newformat?"":" " ); - - /* We didn't include this before in the key listing, but there - is room in the new format, so why not? */ - if(newformat && pk->expiredate) - printf(_(" [expires: %s]"), expirestr_from_pk( pk ) ); - - if(opt.list_options&LIST_SHOW_VALIDITY) - printf(" [%s]",trust_value_to_string(validity)); - } - - for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) { - if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) { - int indent; - /* don't list revoked or expired UIDS unless we are in - * verbose mode and signature listing has not been - * requested */ - if ( !opt.verbose && !opt.list_sigs && - (node->pkt->pkt.user_id->is_revoked || - node->pkt->pkt.user_id->is_expired )) - continue; - - if(attrib_fp && node->pkt->pkt.user_id->attrib_data!=NULL) - dump_attribs(node->pkt->pkt.user_id,pk,sk); - - if(!any && newformat) - printf("\n"); - - if((opt.list_options&LIST_SHOW_VALIDITY) && pk) - { - const char *validity= - trust_value_to_string(get_validity(pk,node->pkt->pkt.user_id)); - - /* Includes the 3 spaces for [, ], and " ". */ - indent=((opt.list_options&LIST_SHOW_LONG_KEYID)?23:15) - -strlen(validity); - - if(indent<0) - indent=0; - - printf("uid%*s[%s] ",indent,"",validity); - } - else if(newformat) - printf("uid%*s",26,""); - else if(any) - printf("uid%*s",29,""); - - if ( node->pkt->pkt.user_id->is_revoked ) - fputs ("[revoked] ", stdout); - if ( node->pkt->pkt.user_id->is_expired ) - fputs ("[expired] ", stdout); - - print_utf8_string( stdout, node->pkt->pkt.user_id->name, - node->pkt->pkt.user_id->len ); - putchar('\n'); - if( !any ) { - if( fpr ) - print_fingerprint( pk, sk, 0 ); - print_card_serialno (sk); - if( opt.with_key_data ) - print_key_data( pk, keyid ); - any = 1; - } - - if((opt.list_options&LIST_SHOW_PHOTOS) - && node->pkt->pkt.user_id->attribs!=NULL) - show_photos(node->pkt->pkt.user_id->attribs, - node->pkt->pkt.user_id->numattribs,pk,sk); - } - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - u32 keyid2[2]; - PKT_public_key *pk2 = node->pkt->pkt.public_key; - - if( !any ) { - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); /* of the main key */ - any = 1; - } - - keyid_from_pk( pk2, keyid2 ); - printf("sub %4u%c/", - nbits_from_pk( pk2 ),pubkey_letter( pk2->pubkey_algo )); - if(opt.list_options&LIST_SHOW_LONG_KEYID) - printf("%08lX%08lX",(ulong)keyid2[0],(ulong)keyid2[1]); - else - printf("%08lX",(ulong)keyid2[1]); - printf(" %s",datestr_from_pk(pk2)); - if( pk2->expiredate ) - printf(_(" [expires: %s]"), expirestr_from_pk( pk2 ) ); - putchar('\n'); - if( fpr > 1 ) - print_fingerprint( pk2, NULL, 0 ); - if( opt.with_key_data ) - print_key_data( pk2, keyid2 ); - } - else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - u32 keyid2[2]; - PKT_secret_key *sk2 = node->pkt->pkt.secret_key; - - if( !any ) { - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); /* of the main key */ - print_card_serialno (sk); - any = 1; - } - - keyid_from_sk( sk2, keyid2 ); - printf("ssb %4u%c/", - nbits_from_sk( sk2 ),pubkey_letter( sk2->pubkey_algo )); - if(opt.list_options&LIST_SHOW_LONG_KEYID) - printf("%08lX%08lX",(ulong)keyid2[0],(ulong)keyid2[1]); - else - printf("%08lX",(ulong)keyid2[1]); - printf(" %s",datestr_from_sk( sk2 ) ); - if( sk2->expiredate ) - printf(_(" [expires: %s]"), expirestr_from_sk( sk2 ) ); - putchar('\n'); - if( fpr > 1 ) - { - print_fingerprint( NULL, sk2, 0 ); - print_card_serialno (sk); - } - } - else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - int sigrc; - char *sigstr; - - if( stats ) { - /*fflush(stdout);*/ - rc = check_key_signature( keyblock, node, NULL ); - switch( gpg_err_code (rc) ) { - case 0: sigrc = '!'; break; - case GPG_ERR_BAD_SIGNATURE: stats->inv_sigs++; sigrc = '-'; break; - case GPG_ERR_NO_PUBKEY: - case GPG_ERR_UNUSABLE_PUBKEY: stats->no_key++; continue; - default: stats->oth_err++; sigrc = '%'; break; - } - - /* TODO: Make sure a cached sig record here still has - the pk that issued it. See also - keyedit.c:print_and_check_one_sig */ - - } - else { - rc = 0; - sigrc = ' '; - } - - if( !any ) { /* no user id, (maybe a revocation follows)*/ - /* Check if the pk is really revoked - there could be a - 0x20 sig packet there even if we are not revoked - (say, if a revocation key issued the packet, but the - revocation key isn't present to verify it.) */ - if( sig->sig_class == 0x20 && pk->is_revoked ) - puts("[revoked]"); - else if( sig->sig_class == 0x18 ) - puts("[key binding]"); - else if( sig->sig_class == 0x28 ) - puts("[subkey revoked]"); - else - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); - print_card_serialno (sk); - any=1; - } - - if( sig->sig_class == 0x20 || sig->sig_class == 0x28 - || sig->sig_class == 0x30 ) - sigstr = "rev"; - else if( (sig->sig_class&~3) == 0x10 ) - sigstr = "sig"; - else if( sig->sig_class == 0x18 ) - sigstr = "sig"; - else if( sig->sig_class == 0x1F ) - sigstr = "sig"; - else { - printf("sig " - "[unexpected signature class 0x%02x]\n",sig->sig_class ); - continue; - } - - fputs( sigstr, stdout ); - printf("%c%c %c%c%c%c%c%c ", - sigrc,(sig->sig_class-0x10>0 && - sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ', - sig->flags.exportable?' ':'L', - sig->flags.revocable?' ':'R', - sig->flags.policy_url?'P':' ', - sig->flags.notation?'N':' ', - sig->flags.expired?'X':' ', - (sig->trust_depth>9)?'T': - (sig->trust_depth>0)?'0'+sig->trust_depth:' '); - if(opt.list_options&LIST_SHOW_LONG_KEYID) - printf("%08lX%08lX",(ulong)sig->keyid[0],(ulong)sig->keyid[1]); - else - printf("%08lX",(ulong)sig->keyid[1]); - printf(" %s ", datestr_from_sig(sig)); - if( sigrc == '%' ) - printf("[%s] ", gpg_strerror (rc) ); - else if( sigrc == '?' ) - ; - else if ( !opt.fast_list_mode ) { - size_t n; - char *p = get_user_id( sig->keyid, &n ); - print_utf8_string( stdout, p, n ); - xfree (p); - } - putchar('\n'); - - if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY)) - show_policy_url(sig,3,0); - - if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION)) - show_notation(sig,3,0); - - if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER)) - show_keyserver_url(sig,3,0); - - /* fixme: check or list other sigs here */ - } - } - putchar('\n'); -} - - -static void -list_keyblock_colon( KBNODE keyblock, int secret, int fpr ) -{ - int rc = 0; - KBNODE kbctx; - KBNODE node; - PKT_public_key *pk; - PKT_secret_key *sk; - u32 keyid[2]; - int any=0; - int trustletter = 0; - int ulti_hack = 0; - - /* get the keyid from the keyblock */ - node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY ); - if( !node ) { - log_error("Oops; key lost!\n"); - dump_kbnode( keyblock ); - return; - } - - if( secret ) { - pk = NULL; - sk = node->pkt->pkt.secret_key; - keyid_from_sk( sk, keyid ); - printf("sec::%u:%d:%08lX%08lX:%s:%s:::", - nbits_from_sk( sk ), - sk->pubkey_algo, - (ulong)keyid[0],(ulong)keyid[1], - colon_datestr_from_sk( sk ), - colon_strtime (sk->expiredate) - /* fixme: add LID here */ ); - } - else { - pk = node->pkt->pkt.public_key; - sk = NULL; - keyid_from_pk( pk, keyid ); - fputs( "pub:", stdout ); - if ( !pk->is_valid ) - putchar ('i'); - else if ( pk->is_revoked ) - putchar ('r'); - else if ( pk->has_expired ) - putchar ('e'); - else if ( opt.fast_list_mode || opt.no_expensive_trust_checks ) - ; - else { - trustletter = get_validity_info ( pk, NULL ); - if( trustletter == 'u' ) - ulti_hack = 1; - putchar(trustletter); - } - printf(":%u:%d:%08lX%08lX:%s:%s:", - nbits_from_pk( pk ), - pk->pubkey_algo, - (ulong)keyid[0],(ulong)keyid[1], - colon_datestr_from_pk( pk ), - colon_strtime (pk->expiredate) ); - if( pk->local_id ) - printf("%lu", pk->local_id ); - putchar(':'); - if( !opt.fast_list_mode && !opt.no_expensive_trust_checks ) - putchar( get_ownertrust_info(pk) ); - putchar(':'); - } - - if (opt.fixed_list_mode) { - /* do not merge the first uid with the primary key */ - putchar(':'); - putchar(':'); - print_capabilities (pk, sk, keyblock); - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); - if( opt.with_key_data ) - print_key_data( pk, keyid ); - any = 1; - } - - - for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) { - if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) { - PKT_user_id *uid=node->pkt->pkt.user_id; - if(attrib_fp && node->pkt->pkt.user_id->attrib_data!=NULL) - dump_attribs(node->pkt->pkt.user_id,pk,sk); - /* - * Fixme: We need a is_valid flag here too - */ - if( any ) { - int i; - char *str=uid->attrib_data?"uat":"uid"; - /* If we're listing a secret key, leave out the - validity values for now. FIXME: This should be - handled better in 1.9. */ - if ( sk ) - printf("%s:::::",str); - else if ( uid->is_revoked ) - printf("%s:r::::",str); - else if ( uid->is_expired ) - printf("%s:e::::",str); - else if ( opt.no_expensive_trust_checks ) - printf("%s:::::",str); - else { - int uid_validity; - - if( pk && !ulti_hack ) - uid_validity=get_validity_info (pk, uid); - else - uid_validity = 'u'; - printf("%s:%c::::",str,uid_validity); - } - - printf("%s:",colon_strtime(uid->created)); - printf("%s:",colon_strtime(uid->expiredate)); - - namehash_from_uid(uid); - - for(i=0; i < 20; i++ ) - printf("%02X",uid->namehash[i]); - - printf("::"); - } - if(uid->attrib_data) - printf("%u %lu",uid->numattribs,uid->attrib_len); - else - print_string(stdout,uid->name,uid->len, ':' ); - putchar(':'); - if (any) - putchar('\n'); - else { - putchar(':'); - print_capabilities (pk, sk, keyblock); - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); - if( opt.with_key_data ) - print_key_data( pk, keyid ); - any = 1; - } - } - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - u32 keyid2[2]; - PKT_public_key *pk2 = node->pkt->pkt.public_key; - - if( !any ) { - putchar(':'); - putchar(':'); - print_capabilities (pk, sk, keyblock); - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); /* of the main key */ - any = 1; - } - - keyid_from_pk( pk2, keyid2 ); - fputs ("sub:", stdout ); - if ( !pk2->is_valid ) - putchar ('i'); - else if ( pk2->is_revoked ) - putchar ('r'); - else if ( pk2->has_expired ) - putchar ('e'); - else if ( opt.fast_list_mode || opt.no_expensive_trust_checks ) - ; - else { - /* trustletter should always be defined here */ - if(trustletter) - printf("%c", trustletter ); - } - printf(":%u:%d:%08lX%08lX:%s:%s:", - nbits_from_pk( pk2 ), - pk2->pubkey_algo, - (ulong)keyid2[0],(ulong)keyid2[1], - colon_datestr_from_pk( pk2 ), - colon_strtime (pk2->expiredate) - /* fixme: add LID and ownertrust here */ - ); - if( pk->local_id ) /* use the local_id of the main key??? */ - printf("%lu", pk->local_id ); - putchar(':'); - putchar(':'); - putchar(':'); - putchar(':'); - print_capabilities (pk2, NULL, NULL); - putchar('\n'); - if( fpr > 1 ) - print_fingerprint( pk2, NULL, 0 ); - if( opt.with_key_data ) - print_key_data( pk2, keyid2 ); - } - else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - u32 keyid2[2]; - PKT_secret_key *sk2 = node->pkt->pkt.secret_key; - - if( !any ) { - putchar(':'); - putchar(':'); - print_capabilities (pk, sk, keyblock); - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); /* of the main key */ - any = 1; - } - - keyid_from_sk( sk2, keyid2 ); - printf("ssb::%u:%d:%08lX%08lX:%s:%s:::::", - nbits_from_sk( sk2 ), - sk2->pubkey_algo, - (ulong)keyid2[0],(ulong)keyid2[1], - colon_datestr_from_sk( sk2 ), - colon_strtime (sk2->expiredate) - /* fixme: add LID */ ); - print_capabilities (NULL, sk2, NULL); - putchar ('\n'); - if( fpr > 1 ) - print_fingerprint( NULL, sk2, 0 ); - } - else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - int sigrc, fprokay=0; - char *sigstr; - size_t fplen; - byte fparray[MAX_FINGERPRINT_LEN]; - - if( !any ) { /* no user id, (maybe a revocation follows)*/ - if( sig->sig_class == 0x20 ) - fputs("[revoked]:", stdout); - else if( sig->sig_class == 0x18 ) - fputs("[key binding]:", stdout); - else if( sig->sig_class == 0x28 ) - fputs("[subkey revoked]:", stdout); - else - putchar (':'); - putchar(':'); - print_capabilities (pk, sk, keyblock); - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); - any=1; - } - - if( sig->sig_class == 0x20 || sig->sig_class == 0x28 - || sig->sig_class == 0x30 ) - sigstr = "rev"; - else if( (sig->sig_class&~3) == 0x10 ) - sigstr = "sig"; - else if( sig->sig_class == 0x18 ) - sigstr = "sig"; - else if( sig->sig_class == 0x1F ) - sigstr = "sig"; - else { - printf ("sig::::::::::%02x%c:\n", - sig->sig_class, sig->flags.exportable?'x':'l'); - continue; - } - if( opt.check_sigs ) { - PKT_public_key *signer_pk=NULL; - - fflush(stdout); - if(opt.no_sig_cache) - signer_pk = xcalloc (1, sizeof(PKT_public_key)); - - rc = check_key_signature2( keyblock, node, NULL, signer_pk, - NULL, NULL, NULL ); - switch( gpg_err_code (rc) ) { - case 0: sigrc = '!'; break; - case GPG_ERR_BAD_SIGNATURE: sigrc = '-'; break; - case GPG_ERR_NO_PUBKEY: - case GPG_ERR_UNUSABLE_PUBKEY: sigrc = '?'; break; - default: sigrc = '%'; break; - } - - if(opt.no_sig_cache) - { - if(!rc) - { - fingerprint_from_pk (signer_pk, fparray, &fplen); - fprokay=1; - } - free_public_key(signer_pk); - } - } - else { - rc = 0; - sigrc = ' '; - } - fputs( sigstr, stdout ); - putchar(':'); - if( sigrc != ' ' ) - putchar(sigrc); - printf("::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo, - (ulong)sig->keyid[0], (ulong)sig->keyid[1], - colon_datestr_from_sig(sig), - colon_expirestr_from_sig(sig)); - - if(sig->trust_depth || sig->trust_value) - printf("%d %d",sig->trust_depth,sig->trust_value); - printf(":"); - - if(sig->trust_regexp) - print_string(stdout,sig->trust_regexp, - strlen(sig->trust_regexp),':'); - printf(":"); - - if( sigrc == '%' ) - printf("[%s] ", gpg_strerror (rc) ); - else if( sigrc == '?' ) - ; - else if ( !opt.fast_list_mode ) { - size_t n; - char *p = get_user_id( sig->keyid, &n ); - print_string( stdout, p, n, ':' ); - xfree (p); - } - printf(":%02x%c:", sig->sig_class,sig->flags.exportable?'x':'l'); - if(opt.no_sig_cache && opt.check_sigs && fprokay) - { - size_t i; - - printf(":"); - - for (i=0; i < fplen ; i++ ) - printf ("%02X", fparray[i] ); - - printf(":"); - } - - printf("\n"); - /* fixme: check or list other sigs here */ - } - } - if( !any ) {/* oops, no user id */ - putchar(':'); - putchar(':'); - print_capabilities (pk, sk, keyblock); - putchar('\n'); - } -} - -/* - * Reorder the keyblock so that the primary user ID (and not attribute - * packet) comes first. Fixme: Replace this by a generic sort - * function. */ -void -reorder_keyblock (KBNODE keyblock) -{ - KBNODE primary = NULL, primary0 = NULL, primary2 = NULL; - KBNODE last, node; - - for (node=keyblock; node; primary0=node, node = node->next) { - if( node->pkt->pkttype == PKT_USER_ID && - !node->pkt->pkt.user_id->attrib_data && - node->pkt->pkt.user_id->is_primary ) { - primary = primary2 = node; - for (node=node->next; node; primary2=node, node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - break; - } - } - break; - } - } - if ( !primary ) - return; /* no primary key flag found (should not happen) */ - - for (last=NULL, node=keyblock; node; last = node, node = node->next) { - if( node->pkt->pkttype == PKT_USER_ID ) - break; - } - assert (node); - assert (last); /* the user ID is never the first packet */ - assert (primary0); /* ditto (this is the node before primary) */ - if ( node == primary ) - return; /* already the first one */ - - last->next = primary; - primary0->next = primary2->next; - primary2->next = node; -} - -void -list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque ) -{ - reorder_keyblock (keyblock); - if (opt.with_colons) - list_keyblock_colon (keyblock, secret, fpr ); - else - list_keyblock_print (keyblock, secret, fpr, opaque ); -} - -/* - * standard function to print the finperprint. - * mode 0: as used in key listings, opt.with_colons is honored - * 1: print using log_info () - * 2: direct use of tty - * 3: direct use of tty but only primary key. - * modes 1 and 2 will try and print both subkey and primary key fingerprints - */ -void -print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode ) -{ - byte array[MAX_FINGERPRINT_LEN], *p; - size_t i, n; - FILE *fp; - const char *text; - int primary=0; - - if(sk) - { - if(sk->main_keyid[0]==sk->keyid[0] && sk->main_keyid[1]==sk->keyid[1]) - primary=1; - } - else - { - if(pk->main_keyid[0]==pk->keyid[0] && pk->main_keyid[1]==pk->keyid[1]) - primary=1; - } - - /* Just to be safe */ - if(mode&0x80 && !primary) - { - log_error("primary key is not really primary!\n"); - return; - } - - mode&=~0x80; - - if(!primary && (mode==1 || mode==2)) - { - if(sk) - { - PKT_secret_key *primary_sk=xcalloc (1,sizeof(*primary_sk)); - get_seckey(primary_sk,sk->main_keyid); - print_fingerprint(NULL,primary_sk,mode|0x80); - free_secret_key(primary_sk); - } - else - { - PKT_public_key *primary_pk=xcalloc (1,sizeof(*primary_pk)); - get_pubkey(primary_pk,pk->main_keyid); - print_fingerprint(primary_pk,NULL,mode|0x80); - free_public_key(primary_pk); - } - } - - if (mode == 1) { - fp = log_get_stream (); - if(primary) - text = _("Primary key fingerprint:"); - else - text = _(" Subkey fingerprint:"); - } - else if (mode == 2) { - fp = NULL; /* use tty */ - /* Translators: this should fit into 24 bytes to that the fingerprint - * data is properly aligned with the user ID */ - if(primary) - text = _(" Primary key fingerprint:"); - else - text = _(" Subkey fingerprint:"); - } - else if (mode == 3) { - fp = NULL; /* use tty */ - text = _(" Key fingerprint ="); - } - else { - fp = stdout; - text = _(" Key fingerprint ="); - } - - if (sk) - fingerprint_from_sk (sk, array, &n); - else - fingerprint_from_pk (pk, array, &n); - p = array; - if (opt.with_colons && !mode) { - fprintf (fp, "fpr:::::::::"); - for (i=0; i < n ; i++, p++ ) - fprintf (fp, "%02X", *p ); - putc(':', fp); - } - else { - if (fp) - fputs (text, fp); - else - tty_printf ("%s", text); - if (n == 20) { - for (i=0; i < n ; i++, i++, p += 2 ) { - if (fp) { - if (i == 10 ) - putc(' ', fp); - fprintf (fp, " %02X%02X", *p, p[1] ); - } - else { - if (i == 10 ) - tty_printf (" "); - tty_printf (" %02X%02X", *p, p[1]); - } - } - } - else { - for (i=0; i < n ; i++, p++ ) { - if (fp) { - if (i && !(i%8) ) - putc (' ', fp); - fprintf (fp, " %02X", *p ); - } - else { - if (i && !(i%8) ) - tty_printf (" "); - tty_printf (" %02X", *p ); - } - } - } - } - if (fp) - putc ('\n', fp); - else - tty_printf ("\n"); -} - - -/* Print the serial number of an OpenPGP card if available. */ -static void -print_card_serialno (PKT_secret_key *sk) -{ - int i; - - if (!sk) - return; - if (!sk->is_protected || sk->protect.s2k.mode != 1002) - return; /* Not a card. */ - if (opt.with_colons) - return; /* Format not yet defined. */ - - fputs (_(" Card serial no. ="), stdout); - putchar (' '); - if (sk->protect.ivlen == 16 - && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6) ) - { /* This is an OpenPGP card. Just print the relevant part. */ - for (i=8; i < 14; i++) - { - if (i == 10) - putchar (' '); - printf ("%02X", sk->protect.iv[i]); - } - } - else - { /* Something is wrong: Print all. */ - for (i=0; i < sk->protect.ivlen; i++) - printf ("%02X", sk->protect.iv[i]); - } - putchar ('\n'); -} - -void set_attrib_fd(int fd) -{ - static int last_fd=-1; - - if ( fd != -1 && last_fd == fd ) - return; - - if ( attrib_fp && attrib_fp != stdout && attrib_fp != stderr ) - fclose (attrib_fp); - attrib_fp = NULL; - if ( fd == -1 ) - return; - - if( fd == 1 ) - attrib_fp = stdout; - else if( fd == 2 ) - attrib_fp = stderr; - else - attrib_fp = fdopen( fd, "w" ); - if( !attrib_fp ) { - log_fatal("can't open fd %d for attribute output: %s\n", - fd, strerror(errno)); - } - last_fd = fd; -} diff --git a/g10/keyring.c b/g10/keyring.c deleted file mode 100644 index 03a22667c..000000000 --- a/g10/keyring.c +++ /dev/null @@ -1,1588 +0,0 @@ -/* keyring.c - keyring file handling - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include "gpg.h" -#include "util.h" -#include "keyring.h" -#include "packet.h" -#include "keydb.h" -#include "options.h" -#include "main.h" /*for check_key_signature()*/ -#include "i18n.h" - -/* off_item is a funny named for an object used to keep track of known - * keys. The idea was to use the offset to seek to the known keyblock, but - * this is not possible if more than one process is using the keyring. - */ -struct off_item { - struct off_item *next; - u32 kid[2]; - /*off_t off;*/ -}; - -typedef struct off_item **OffsetHashTable; - - -typedef struct keyring_name *KR_NAME; -struct keyring_name { - struct keyring_name *next; - int secret; - DOTLOCK lockhd; - int is_locked; - int did_full_scan; - char fname[1]; -}; -typedef struct keyring_name const * CONST_KR_NAME; - -static KR_NAME kr_names; -static int active_handles; - -static OffsetHashTable kr_offtbl; -static int kr_offtbl_ready; - - -struct keyring_handle { - CONST_KR_NAME resource; - int secret; /* this is for a secret keyring */ - struct { - CONST_KR_NAME kr; - iobuf_t iobuf; - int eof; - int error; - } current; - struct { - CONST_KR_NAME kr; - off_t offset; - size_t pk_no; - size_t uid_no; - unsigned int n_packets; /*used for delete and update*/ - } found; - struct { - char *name; - char *pattern; - } word_match; -}; - - - -static int do_copy (int mode, const char *fname, KBNODE root, int secret, - off_t start_offset, unsigned int n_packets ); - - - -static struct off_item * -new_offset_item (void) -{ - struct off_item *k; - - k = xcalloc (1,sizeof *k); - return k; -} - -#if 0 -static void -release_offset_items (struct off_item *k) -{ - struct off_item *k2; - - for (; k; k = k2) - { - k2 = k->next; - xfree (k); - } -} -#endif - -static OffsetHashTable -new_offset_hash_table (void) -{ - struct off_item **tbl; - - tbl = xcalloc (2048, sizeof *tbl); - return tbl; -} - -#if 0 -static void -release_offset_hash_table (OffsetHashTable tbl) -{ - int i; - - if (!tbl) - return; - for (i=0; i < 2048; i++) - release_offset_items (tbl[i]); - xfree (tbl); -} -#endif - -static struct off_item * -lookup_offset_hash_table (OffsetHashTable tbl, u32 *kid) -{ - struct off_item *k; - - for (k = tbl[(kid[1] & 0x07ff)]; k; k = k->next) - if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) - return k; - return NULL; -} - -static void -update_offset_hash_table (OffsetHashTable tbl, u32 *kid, off_t off) -{ - struct off_item *k; - - for (k = tbl[(kid[1] & 0x07ff)]; k; k = k->next) - { - if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) - { - /*k->off = off;*/ - return; - } - } - - k = new_offset_item (); - k->kid[0] = kid[0]; - k->kid[1] = kid[1]; - /*k->off = off;*/ - k->next = tbl[(kid[1] & 0x07ff)]; - tbl[(kid[1] & 0x07ff)] = k; -} - -static void -update_offset_hash_table_from_kb (OffsetHashTable tbl, KBNODE node, off_t off) -{ - for (; node; node = node->next) - { - if (node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - { - u32 aki[2]; - keyid_from_pk (node->pkt->pkt.public_key, aki); - update_offset_hash_table (tbl, aki, off); - } - } -} - -/* - * Register a filename for plain keyring files. ptr is set to a - * pointer to be used to create a handles etc, or the already-issued - * pointer if it has already been registered. The function returns 1 - * if a new keyring was registered. -*/ -int -keyring_register_filename (const char *fname, int secret, void **ptr) -{ - KR_NAME kr; - - if (active_handles) - BUG (); /* We don't allow that */ - - for (kr=kr_names; kr; kr = kr->next) - { - if ( !compare_filenames (kr->fname, fname) ) - { - *ptr=kr; - return 0; /* already registered */ - } - } - - kr = xmalloc (sizeof *kr + strlen (fname)); - strcpy (kr->fname, fname); - kr->secret = !!secret; - kr->lockhd = NULL; - kr->is_locked = 0; - kr->did_full_scan = 0; - /* keep a list of all issued pointers */ - kr->next = kr_names; - kr_names = kr; - - /* create the offset table the first time a function here is used */ - if (!kr_offtbl) - kr_offtbl = new_offset_hash_table (); - - *ptr=kr; - - return 1; -} - -int -keyring_is_writable (void *token) -{ - KR_NAME r = token; - - return r? !access (r->fname, W_OK) : 0; -} - - - -/* Create a new handle for the resource associated with TOKEN. SECRET - is just just as a cross-check. - - The returned handle must be released using keyring_release (). */ -KEYRING_HANDLE -keyring_new (void *token, int secret) -{ - KEYRING_HANDLE hd; - KR_NAME resource = token; - - assert (resource && !resource->secret == !secret); - - hd = xcalloc (1,sizeof *hd); - hd->resource = resource; - hd->secret = !!secret; - active_handles++; - return hd; -} - -void -keyring_release (KEYRING_HANDLE hd) -{ - if (!hd) - return; - assert (active_handles > 0); - active_handles--; - xfree (hd->word_match.name); - xfree (hd->word_match.pattern); - iobuf_close (hd->current.iobuf); - xfree (hd); -} - - -const char * -keyring_get_resource_name (KEYRING_HANDLE hd) -{ - if (!hd || !hd->resource) - return NULL; - return hd->resource->fname; -} - - -/* - * Lock the keyring with the given handle, or unlok if yes is false. - * We ignore the handle and lock all registered files. - */ -int -keyring_lock (KEYRING_HANDLE hd, int yes) -{ - KR_NAME kr; - int rc = 0; - - if (yes) { - /* first make sure the lock handles are created */ - for (kr=kr_names; kr; kr = kr->next) { - if (!keyring_is_writable(kr)) - continue; - if (!kr->lockhd) { - kr->lockhd = create_dotlock( kr->fname ); - if (!kr->lockhd) { - log_info ("can't allocate lock for `%s'\n", kr->fname ); - rc = GPG_ERR_GENERAL; - } - } - } - if (rc) - return rc; - - /* and now set the locks */ - for (kr=kr_names; kr; kr = kr->next) { - if (!keyring_is_writable(kr)) - continue; - if (kr->is_locked) - ; - else if (make_dotlock (kr->lockhd, -1) ) { - log_info ("can't lock `%s'\n", kr->fname ); - rc = GPG_ERR_GENERAL; - } - else - kr->is_locked = 1; - } - } - - if (rc || !yes) { - for (kr=kr_names; kr; kr = kr->next) { - if (!keyring_is_writable(kr)) - continue; - if (!kr->is_locked) - ; - else if (release_dotlock (kr->lockhd)) - log_info ("can't unlock `%s'\n", kr->fname ); - else - kr->is_locked = 0; - } - } - - return rc; -} - - - -/* - * Return the last found keyring. Caller must free it. - * The returned keyblock has the kbode flag bit 0 set for the node with - * the public key used to locate the keyblock or flag bit 1 set for - * the user ID node. - */ -int -keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) -{ - PACKET *pkt; - int rc; - KBNODE keyblock = NULL, node, lastnode; - iobuf_t a; - int in_cert = 0; - int pk_no = 0; - int uid_no = 0; - int save_mode; - - if (ret_kb) - *ret_kb = NULL; - - if (!hd->found.kr) - return -1; /* no successful search */ - - a = iobuf_open (hd->found.kr->fname); - if (!a) { - log_error ("can't open `%s'\n", hd->found.kr->fname); - return GPG_ERR_KEYRING_OPEN; - } - - if (iobuf_seek (a, hd->found.offset) ) { - log_error ("can't seek `%s'\n", hd->found.kr->fname); - iobuf_close(a); - return GPG_ERR_KEYRING_OPEN; - } - - pkt = xmalloc (sizeof *pkt); - init_packet (pkt); - hd->found.n_packets = 0;; - lastnode = NULL; - save_mode = set_packet_list_mode(0); - while ((rc=parse_packet (a, pkt)) != -1) { - hd->found.n_packets++; - if (gpg_err_code (rc) == GPG_ERR_UNKNOWN_PACKET) { - free_packet (pkt); - init_packet (pkt); - continue; - } - if (rc) { - log_error ("keyring_get_keyblock: read error: %s\n", - gpg_strerror (rc) ); - rc = GPG_ERR_INV_KEYRING; - break; - } - if (pkt->pkttype == PKT_COMPRESSED) { - log_error ("skipped compressed packet in keyring\n"); - free_packet(pkt); - init_packet(pkt); - continue; - } - - if (in_cert && (pkt->pkttype == PKT_PUBLIC_KEY - || pkt->pkttype == PKT_SECRET_KEY)) { - hd->found.n_packets--; /* fix counter */ - break; /* ready */ - } - - in_cert = 1; - if (pkt->pkttype == PKT_RING_TRUST) { - /*(this code is duplicated after the loop)*/ - if ( lastnode - && lastnode->pkt->pkttype == PKT_SIGNATURE - && (pkt->pkt.ring_trust->sigcache & 1) ) { - /* this is a ring trust packet with a checked signature - * status cache following directly a signature paket. - * Set the cache status into that signature packet */ - PKT_signature *sig = lastnode->pkt->pkt.signature; - - sig->flags.checked = 1; - sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2); - } - /* reset lastnode, so that we set the cache status only from - * the ring trust packet immediately folling a signature */ - lastnode = NULL; - } - else { - node = lastnode = new_kbnode (pkt); - if (!keyblock) - keyblock = node; - else - add_kbnode (keyblock, node); - - if ( pkt->pkttype == PKT_PUBLIC_KEY - || pkt->pkttype == PKT_PUBLIC_SUBKEY - || pkt->pkttype == PKT_SECRET_KEY - || pkt->pkttype == PKT_SECRET_SUBKEY) { - if (++pk_no == hd->found.pk_no) - node->flag |= 1; - } - else if ( pkt->pkttype == PKT_USER_ID) { - if (++uid_no == hd->found.uid_no) - node->flag |= 2; - } - } - - pkt = xmalloc (sizeof *pkt); - init_packet(pkt); - } - set_packet_list_mode(save_mode); - - if (rc == -1 && keyblock) - rc = 0; /* got the entire keyblock */ - - if (rc || !ret_kb) - release_kbnode (keyblock); - else { - /*(duplicated form the loop body)*/ - if ( pkt && pkt->pkttype == PKT_RING_TRUST - && lastnode - && lastnode->pkt->pkttype == PKT_SIGNATURE - && (pkt->pkt.ring_trust->sigcache & 1) ) { - PKT_signature *sig = lastnode->pkt->pkt.signature; - sig->flags.checked = 1; - sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2); - } - *ret_kb = keyblock; - } - free_packet (pkt); - xfree (pkt); - iobuf_close(a); - - /* Make sure that future search operations fail immediately when - * we know that we are working on a invalid keyring - */ - if (gpg_err_code (rc) == GPG_ERR_INV_KEYRING) - hd->current.error = rc; - - return rc; -} - -int -keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb) -{ - int rc; - - if (!hd->found.kr) - return -1; /* no successful prior search */ - - if (!hd->found.n_packets) { - /* need to know the number of packets - do a dummy get_keyblock*/ - rc = keyring_get_keyblock (hd, NULL); - if (rc) { - log_error ("re-reading keyblock failed: %s\n", gpg_strerror (rc)); - return rc; - } - if (!hd->found.n_packets) - BUG (); - } - - /* The open iobuf isn't needed anymore and in fact is a problem when - it comes to renaming the keyring files on some operating systems, - so close it here */ - iobuf_close(hd->current.iobuf); - hd->current.iobuf = NULL; - - /* do the update */ - rc = do_copy (3, hd->found.kr->fname, kb, hd->secret, - hd->found.offset, hd->found.n_packets ); - if (!rc) { - if (!hd->secret && kr_offtbl) - { - update_offset_hash_table_from_kb (kr_offtbl, kb, 0); - } - /* better reset the found info */ - hd->found.kr = NULL; - hd->found.offset = 0; - } - return rc; -} - -int -keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb) -{ - int rc; - const char *fname; - - if (!hd) - fname = NULL; - else if (hd->found.kr) - fname = hd->found.kr->fname; - else if (hd->current.kr) - fname = hd->current.kr->fname; - else - fname = hd->resource? hd->resource->fname:NULL; - - if (!fname) - return GPG_ERR_GENERAL; - - /* close this one otherwise we will lose the position for - * a next search. Fixme: it would be better to adjust the position - * after the write opertions. - */ - iobuf_close (hd->current.iobuf); - hd->current.iobuf = NULL; - - /* do the insert */ - rc = do_copy (1, fname, kb, hd->secret, 0, 0 ); - if (!rc && !hd->secret && kr_offtbl) - { - update_offset_hash_table_from_kb (kr_offtbl, kb, 0); - } - - return rc; -} - - -int -keyring_delete_keyblock (KEYRING_HANDLE hd) -{ - int rc; - - if (!hd->found.kr) - return -1; /* no successful prior search */ - - if (!hd->found.n_packets) { - /* need to know the number of packets - do a dummy get_keyblock*/ - rc = keyring_get_keyblock (hd, NULL); - if (rc) { - log_error ("re-reading keyblock failed: %s\n", gpg_strerror (rc)); - return rc; - } - if (!hd->found.n_packets) - BUG (); - } - - /* close this one otherwise we will lose the position for - * a next search. Fixme: it would be better to adjust the position - * after the write opertions. - */ - iobuf_close (hd->current.iobuf); - hd->current.iobuf = NULL; - - /* do the delete */ - rc = do_copy (2, hd->found.kr->fname, NULL, hd->secret, - hd->found.offset, hd->found.n_packets ); - if (!rc) { - /* better reset the found info */ - hd->found.kr = NULL; - hd->found.offset = 0; - /* Delete is a rare operations, so we don't remove the keys - * from the offset table */ - } - return rc; -} - - - -/* - * Start the next search on this handle right at the beginning - */ -int -keyring_search_reset (KEYRING_HANDLE hd) -{ - assert (hd); - - hd->current.kr = NULL; - iobuf_close (hd->current.iobuf); - hd->current.iobuf = NULL; - hd->current.eof = 0; - hd->current.error = 0; - - hd->found.kr = NULL; - hd->found.offset = 0; - return 0; -} - - -static int -prepare_search (KEYRING_HANDLE hd) -{ - if (hd->current.error) - return hd->current.error; /* still in error state */ - - if (hd->current.kr && !hd->current.eof) { - if ( !hd->current.iobuf ) - return GPG_ERR_GENERAL; /* position invalid after a modify */ - return 0; /* okay */ - } - - if (!hd->current.kr && hd->current.eof) - return -1; /* still EOF */ - - if (!hd->current.kr) { /* start search with first keyring */ - hd->current.kr = hd->resource; - if (!hd->current.kr) { - hd->current.eof = 1; - return -1; /* keyring not available */ - } - assert (!hd->current.iobuf); - } - else { /* EOF */ - iobuf_close (hd->current.iobuf); - hd->current.iobuf = NULL; - hd->current.kr = NULL; - hd->current.eof = 1; - return -1; - } - - hd->current.eof = 0; - hd->current.iobuf = iobuf_open (hd->current.kr->fname); - if (!hd->current.iobuf) { - hd->current.error = gpg_error_from_errno (errno); - log_error ("can't open `%s'\n", hd->current.kr->fname ); - return hd->current.error; - } - - return 0; -} - - -/* A map of the all characters valid used for word_match() - * Valid characters are in in this table converted to uppercase. - * because the upper 128 bytes have special meaning, we assume - * that they are all valid. - * Note: We must use numerical values here in case that this program - * will be converted to those little blue HAL9000s with their strange - * EBCDIC character set (user ids are UTF-8). - * wk 2000-04-13: Hmmm, does this really make sense, given the fact that - * we can run gpg now on a S/390 running GNU/Linux, where the code - * translation is done by the device drivers? - */ -static const byte word_match_chars[256] = { - /* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - /* 38 */ 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 40 */ 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - /* 48 */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - /* 50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - /* 58 */ 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 60 */ 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - /* 68 */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - /* 70 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - /* 78 */ 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 80 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - /* 88 */ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - /* 90 */ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - /* 98 */ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - /* a0 */ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - /* a8 */ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - /* b0 */ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - /* b8 */ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - /* c0 */ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - /* c8 */ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - /* d0 */ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - /* d8 */ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - /* e0 */ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - /* e8 */ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - /* f0 */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - /* f8 */ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -/**************** - * Do a word match (original user id starts with a '+'). - * The pattern is already tokenized to a more suitable format: - * There are only the real words in it delimited by one space - * and all converted to uppercase. - * - * Returns: 0 if all words match. - * - * Note: This algorithm is a straightforward one and not very - * fast. It works for UTF-8 strings. The uidlen should - * be removed but due to the fact that old versions of - * pgp don't use UTF-8 we still use the length; this should - * be fixed in parse-packet (and replace \0 by some special - * UTF-8 encoding) - */ -static int -word_match( const byte *uid, size_t uidlen, const byte *pattern ) -{ - size_t wlen, n; - const byte *p; - const byte *s; - - for( s=pattern; *s; ) { - do { - /* skip leading delimiters */ - while( uidlen && !word_match_chars[*uid] ) - uid++, uidlen--; - /* get length of the word */ - n = uidlen; p = uid; - while( n && word_match_chars[*p] ) - p++, n--; - wlen = p - uid; - /* and compare against the current word from pattern */ - for(n=0, p=uid; n < wlen && s[n] != ' ' && s[n] ; n++, p++ ) { - if( word_match_chars[*p] != s[n] ) - break; - } - if( n == wlen && (s[n] == ' ' || !s[n]) ) - break; /* found */ - uid += wlen; - uidlen -= wlen; - } while( uidlen ); - if( !uidlen ) - return -1; /* not found */ - - /* advance to next word in pattern */ - for(; *s != ' ' && *s ; s++ ) - ; - if( *s ) - s++ ; - } - return 0; /* found */ -} - -/**************** - * prepare word word_match; that is parse the name and - * build the pattern. - * caller has to free the returned pattern - */ -static char* -prepare_word_match (const byte *name) -{ - byte *pattern, *p; - int c; - - /* the original length is always enough for the pattern */ - p = pattern = xmalloc (strlen(name)+1); - do { - /* skip leading delimiters */ - while( *name && !word_match_chars[*name] ) - name++; - /* copy as long as we don't have a delimiter and convert - * to uppercase. - * fixme: how can we handle utf8 uppercasing */ - for( ; *name && (c=word_match_chars[*name]); name++ ) - *p++ = c; - *p++ = ' '; /* append pattern delimiter */ - } while( *name ); - p[-1] = 0; /* replace last pattern delimiter by EOS */ - - return pattern; -} - - - - -static int -compare_name (int mode, const char *name, const char *uid, size_t uidlen) -{ - int i; - const char *s, *se; - - if (mode == KEYDB_SEARCH_MODE_EXACT) { - for (i=0; name[i] && uidlen; i++, uidlen--) - if (uid[i] != name[i]) - break; - if (!uidlen && !name[i]) - return 0; /* found */ - } - else if (mode == KEYDB_SEARCH_MODE_SUBSTR) { - if (ascii_memistr( uid, uidlen, name )) - return 0; - } - else if ( mode == KEYDB_SEARCH_MODE_MAIL - || mode == KEYDB_SEARCH_MODE_MAILSUB - || mode == KEYDB_SEARCH_MODE_MAILEND) { - for (i=0, s= uid; i < uidlen && *s != '<'; s++, i++) - ; - if (i < uidlen) { - /* skip opening delim and one char and look for the closing one*/ - s++; i++; - for (se=s+1, i++; i < uidlen && *se != '>'; se++, i++) - ; - if (i < uidlen) { - i = se - s; - if (mode == KEYDB_SEARCH_MODE_MAIL) { - if( strlen(name)-2 == i - && !ascii_memcasecmp( s, name+1, i) ) - return 0; - } - else if (mode == KEYDB_SEARCH_MODE_MAILSUB) { - if( ascii_memistr( s, i, name ) ) - return 0; - } - else { /* email from end */ - /* nyi */ - } - } - } - } - else if (mode == KEYDB_SEARCH_MODE_WORDS) - return word_match (uid, uidlen, name); - else - BUG(); - - return -1; /* not found */ -} - - -/* - * Search through the keyring(s), starting at the current position, - * for a keyblock which contains one of the keys described in the DESC array. - */ -int -keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, - size_t ndesc, size_t *descindex) -{ - int rc; - PACKET pkt; - int save_mode; - off_t offset, main_offset; - size_t n; - int need_uid, need_words, need_keyid, need_fpr, any_skip; - int pk_no, uid_no; - int initial_skip; - int use_offtbl; - PKT_user_id *uid = NULL; - PKT_public_key *pk = NULL; - PKT_secret_key *sk = NULL; - u32 aki[2]; - - /* figure out what information we need */ - need_uid = need_words = need_keyid = need_fpr = any_skip = 0; - for (n=0; n < ndesc; n++) - { - switch (desc[n].mode) - { - case KEYDB_SEARCH_MODE_EXACT: - case KEYDB_SEARCH_MODE_SUBSTR: - case KEYDB_SEARCH_MODE_MAIL: - case KEYDB_SEARCH_MODE_MAILSUB: - case KEYDB_SEARCH_MODE_MAILEND: - need_uid = 1; - break; - case KEYDB_SEARCH_MODE_WORDS: - need_uid = 1; - need_words = 1; - break; - case KEYDB_SEARCH_MODE_SHORT_KID: - case KEYDB_SEARCH_MODE_LONG_KID: - need_keyid = 1; - break; - case KEYDB_SEARCH_MODE_FPR16: - case KEYDB_SEARCH_MODE_FPR20: - case KEYDB_SEARCH_MODE_FPR: - need_fpr = 1; - break; - case KEYDB_SEARCH_MODE_FIRST: - /* always restart the search in this mode */ - keyring_search_reset (hd); - break; - default: break; - } - if (desc[n].skipfnc) - { - any_skip = 1; - need_keyid = 1; - } - } - - rc = prepare_search (hd); - if (rc) - return rc; - - use_offtbl = !hd->secret && kr_offtbl; - if (!use_offtbl) - ; - else if (!kr_offtbl_ready) - need_keyid = 1; - else if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID) - { - struct off_item *oi; - - oi = lookup_offset_hash_table (kr_offtbl, desc[0].u.kid); - if (!oi) - { /* We know that we don't have this key */ - hd->found.kr = NULL; - hd->current.eof = 1; - return -1; - } - /* We could now create a positive search status and return. - * However the problem is that another instance of gpg may - * have changed the keyring so that the offsets are not valid - * anymore - therefore we don't do it - */ - } - - if (need_words) - { - const char *name = NULL; - - log_debug ("word search mode does not yet work\n"); - /* FIXME: here is a long standing bug in our function and in addition we - just use the first search description */ - for (n=0; n < ndesc && !name; n++) - { - if (desc[n].mode == KEYDB_SEARCH_MODE_WORDS) - name = desc[n].u.name; - } - assert (name); - if ( !hd->word_match.name || strcmp (hd->word_match.name, name) ) - { - /* name changed */ - xfree (hd->word_match.name); - xfree (hd->word_match.pattern); - hd->word_match.name = xstrdup (name); - hd->word_match.pattern = prepare_word_match (name); - } - name = hd->word_match.pattern; - } - - init_packet(&pkt); - save_mode = set_packet_list_mode(0); - - hd->found.kr = NULL; - main_offset = 0; - pk_no = uid_no = 0; - initial_skip = 1; /* skip until we see the start of a keyblock */ - while (!(rc=search_packet (hd->current.iobuf, &pkt, &offset, need_uid))) - { - byte afp[MAX_FINGERPRINT_LEN]; - size_t an; - - if (pkt.pkttype == PKT_PUBLIC_KEY || pkt.pkttype == PKT_SECRET_KEY) - { - main_offset = offset; - pk_no = uid_no = 0; - initial_skip = 0; - } - if (initial_skip) - { - free_packet (&pkt); - continue; - } - - pk = NULL; - sk = NULL; - uid = NULL; - if ( pkt.pkttype == PKT_PUBLIC_KEY - || pkt.pkttype == PKT_PUBLIC_SUBKEY) - { - pk = pkt.pkt.public_key; - ++pk_no; - - if (need_fpr) { - fingerprint_from_pk (pk, afp, &an); - while (an < 20) /* fill up to 20 bytes */ - afp[an++] = 0; - } - if (need_keyid) - keyid_from_pk (pk, aki); - - if (use_offtbl && !kr_offtbl_ready) - update_offset_hash_table (kr_offtbl, aki, main_offset); - } - else if (pkt.pkttype == PKT_USER_ID) - { - uid = pkt.pkt.user_id; - ++uid_no; - } - else if ( pkt.pkttype == PKT_SECRET_KEY - || pkt.pkttype == PKT_SECRET_SUBKEY) - { - sk = pkt.pkt.secret_key; - ++pk_no; - - if (need_fpr) { - fingerprint_from_sk (sk, afp, &an); - while (an < 20) /* fill up to 20 bytes */ - afp[an++] = 0; - } - if (need_keyid) - keyid_from_sk (sk, aki); - - } - - for (n=0; n < ndesc; n++) - { - switch (desc[n].mode) { - case KEYDB_SEARCH_MODE_NONE: - BUG (); - break; - case KEYDB_SEARCH_MODE_EXACT: - case KEYDB_SEARCH_MODE_SUBSTR: - case KEYDB_SEARCH_MODE_MAIL: - case KEYDB_SEARCH_MODE_MAILSUB: - case KEYDB_SEARCH_MODE_MAILEND: - case KEYDB_SEARCH_MODE_WORDS: - if ( uid && !compare_name (desc[n].mode, - desc[n].u.name, - uid->name, uid->len)) - goto found; - break; - - case KEYDB_SEARCH_MODE_SHORT_KID: - if ((pk||sk) && desc[n].u.kid[1] == aki[1]) - goto found; - break; - case KEYDB_SEARCH_MODE_LONG_KID: - if ((pk||sk) && desc[n].u.kid[0] == aki[0] - && desc[n].u.kid[1] == aki[1]) - goto found; - break; - case KEYDB_SEARCH_MODE_FPR16: - if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 16)) - goto found; - break; - case KEYDB_SEARCH_MODE_FPR20: - case KEYDB_SEARCH_MODE_FPR: - if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 20)) - goto found; - break; - case KEYDB_SEARCH_MODE_FIRST: - if (pk||sk) - goto found; - break; - case KEYDB_SEARCH_MODE_NEXT: - if (pk||sk) - goto found; - break; - default: - rc = GPG_ERR_INV_ARG; - goto found; - } - } - free_packet (&pkt); - continue; - found: - /* Record which desc we matched on. Note this value is only - meaningful if this function returns with no errors. */ - if(descindex) - *descindex=n; - for (n=any_skip?0:ndesc; n < ndesc; n++) - { - if (desc[n].skipfnc - && desc[n].skipfnc (desc[n].skipfncvalue, aki)) - break; - } - if (n == ndesc) - goto real_found; - free_packet (&pkt); - } - real_found: - if (!rc) - { - hd->found.offset = main_offset; - hd->found.kr = hd->current.kr; - hd->found.pk_no = (pk||sk)? pk_no : 0; - hd->found.uid_no = uid? uid_no : 0; - } - else if (rc == -1) - { - hd->current.eof = 1; - /* if we scanned all keyrings, we are sure that - * all known key IDs are in our offtbl, mark that. */ - if (use_offtbl && !kr_offtbl_ready) - { - KR_NAME kr; - - /* First set the did_full_scan flag for this keyring (ignore - secret keyrings) */ - for (kr=kr_names; kr; kr = kr->next) - { - if (!kr->secret && hd->resource == kr) - { - kr->did_full_scan = 1; - break; - } - } - /* Then check whether all flags are set and if so, mark the - offtbl ready */ - for (kr=kr_names; kr; kr = kr->next) - { - if (!kr->secret && !kr->did_full_scan) - break; - } - if (!kr) - kr_offtbl_ready = 1; - } - } - else - hd->current.error = rc; - - free_packet(&pkt); - set_packet_list_mode(save_mode); - return rc; -} - - -static int -create_tmp_file (const char *template, - char **r_bakfname, char **r_tmpfname, iobuf_t *r_fp) -{ - char *bakfname, *tmpfname; - mode_t oldmask; - - *r_bakfname = NULL; - *r_tmpfname = NULL; - -# ifdef USE_ONLY_8DOT3 - /* Here is another Windoze bug?: - * you cant rename("pubring.gpg.tmp", "pubring.gpg"); - * but rename("pubring.gpg.tmp", "pubring.aaa"); - * works. So we replace .gpg by .bak or .tmp - */ - if (strlen (template) > 4 - && !strcmp (template+strlen(template)-4, EXTSEP_S "gpg") ) - { - bakfname = xmalloc (strlen (template) + 1); - strcpy (bakfname, template); - strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak"); - - tmpfname = xmalloc (strlen( template ) + 1 ); - strcpy (tmpfname,template); - strcpy (tmpfname+strlen(template)-4, EXTSEP_S "tmp"); - } - else - { /* file does not end with gpg; hmmm */ - bakfname = xmalloc (strlen( template ) + 5); - strcpy (stpcpy(bakfname, template), EXTSEP_S "bak"); - - tmpfname = xmalloc (strlen( template ) + 5); - strcpy (stpcpy(tmpfname, template), EXTSEP_S "tmp"); - } -# else /* Posix file names */ - bakfname = xmalloc (strlen( template ) + 2); - strcpy (stpcpy (bakfname,template),"~"); - - tmpfname = xmalloc (strlen( template ) + 5); - strcpy (stpcpy(tmpfname,template), EXTSEP_S "tmp"); -# endif /* Posix filename */ - - /* Create the temp file with limited access */ - oldmask=umask(077); - *r_fp = iobuf_create (tmpfname); - umask(oldmask); - if (!*r_fp) { - int tmperr = gpg_error_from_errno (errno); - log_error ("can't create `%s': %s\n", tmpfname, strerror(errno) ); - xfree (tmpfname); - xfree (bakfname); - return tmperr; - } - - *r_bakfname = bakfname; - *r_tmpfname = tmpfname; - return 0; -} - - -static int -rename_tmp_file (const char *bakfname, const char *tmpfname, - const char *fname, int secret ) -{ - int rc=0; - - /* invalidate close caches*/ - iobuf_ioctl (NULL, 2, 0, (char*)tmpfname ); - iobuf_ioctl (NULL, 2, 0, (char*)bakfname ); - iobuf_ioctl (NULL, 2, 0, (char*)fname ); - - /* first make a backup file except for secret keyrings */ - if (!secret) - { -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove (bakfname); -#endif - if (rename (fname, bakfname) ) - { - int tmperr = gpg_error_from_errno (errno); - log_error ("renaming `%s' to `%s' failed: %s\n", - fname, bakfname, strerror(errno) ); - return tmperr; - } - } - - /* then rename the file */ -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove( fname ); -#endif - if (rename (tmpfname, fname) ) - { - rc = gpg_error_from_errno (errno); - log_error ("renaming `%s' to `%s' failed: %s\n", - tmpfname, fname, strerror(errno) ); - if (secret) - { - log_info(_("WARNING: 2 files with confidential" - " information exists.\n")); - log_info(_("%s is the unchanged one\n"), fname ); - log_info(_("%s is the new one\n"), tmpfname ); - log_info(_("Please fix this possible security flaw\n")); - } - return rc; - } - - /* Now make sure the file has the same permissions as the original */ - -#ifndef HAVE_DOSISH_SYSTEM - { - struct stat statbuf; - - statbuf.st_mode=S_IRUSR | S_IWUSR; - - if(((secret && !opt.preserve_permissions) || - (stat(bakfname,&statbuf)==0)) && - (chmod(fname,statbuf.st_mode)==0)) - ; - else - log_error("WARNING: unable to restore permissions to `%s': %s", - fname,strerror(errno)); - } -#endif - - return 0; -} - - -static int -write_keyblock (iobuf_t fp, KBNODE keyblock) -{ - KBNODE kbctx = NULL, node; - int rc; - - while ( (node = walk_kbnode (keyblock, &kbctx, 0)) ) - { - if (node->pkt->pkttype == PKT_RING_TRUST) - continue; /* we write it later on our own */ - - if ( (rc = build_packet (fp, node->pkt) )) - { - log_error ("build_packet(%d) failed: %s\n", - node->pkt->pkttype, gpg_strerror (rc) ); - return rc; - } - if (node->pkt->pkttype == PKT_SIGNATURE) - { /* always write a signature cache packet */ - PKT_signature *sig = node->pkt->pkt.signature; - unsigned int cacheval = 0; - - if (sig->flags.checked) - { - cacheval |= 1; - if (sig->flags.valid) - cacheval |= 2; - } - iobuf_put (fp, 0xb0); /* old style packet 12, 1 byte len*/ - iobuf_put (fp, 2); /* 2 bytes */ - iobuf_put (fp, 0); /* unused */ - if (iobuf_put (fp, cacheval)) { - int tmperr = gpg_error_from_errno (errno); - log_error ("writing sigcache packet failed\n"); - return tmperr; - } - } - } - return 0; -} - -/* - * Walk over all public keyrings, check the signatures and replace the - * keyring with a new one where the signature cache is then updated. - * This is only done for the public keyrings. - */ -int -keyring_rebuild_cache (void *token) -{ - KEYRING_HANDLE hd; - KEYDB_SEARCH_DESC desc; - KBNODE keyblock = NULL, node; - const char *lastresname = NULL, *resname; - iobuf_t tmpfp = NULL; - char *tmpfilename = NULL; - char *bakfilename = NULL; - int rc; - ulong count = 0, sigcount = 0; - - hd = keyring_new (token, 0); - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FIRST; - - rc=keyring_lock (hd, 1); - if(rc) - goto leave; - - while ( !(rc = keyring_search (hd, &desc, 1, NULL)) ) - { - desc.mode = KEYDB_SEARCH_MODE_NEXT; - resname = keyring_get_resource_name (hd); - if (lastresname != resname ) - { /* we have switched to a new keyring - commit changes */ - if (tmpfp) - { - if (iobuf_close (tmpfp)) - { - rc = gpg_error_from_errno (errno); - log_error ("error closing `%s': %s\n", - tmpfilename, strerror (errno)); - goto leave; - } - /* because we have switched resources, we can be sure that - * the original file is closed */ - tmpfp = NULL; - } - rc = lastresname? rename_tmp_file (bakfilename, tmpfilename, - lastresname, 0) : 0; - xfree (tmpfilename); tmpfilename = NULL; - xfree (bakfilename); bakfilename = NULL; - if (rc) - goto leave; - lastresname = resname; - if (!opt.quiet) - log_info (_("checking keyring `%s'\n"), resname); - rc = create_tmp_file (resname, &bakfilename, &tmpfilename, &tmpfp); - if (rc) - goto leave; - } - - release_kbnode (keyblock); - rc = keyring_get_keyblock (hd, &keyblock); - if (rc) - { - log_error ("keyring_get_keyblock failed: %s\n", gpg_strerror (rc)); - goto leave; - } - assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY); - - /* check all signature to set the signature's cache flags */ - for (node=keyblock; node; node=node->next) - { - if (node->pkt->pkttype == PKT_SIGNATURE) - { - /* Note that this doesn't cache the result of a - revocation issued by a designated revoker. This is - because the pk in question does not carry the revkeys - as we haven't merged the key and selfsigs. It is - questionable whether this matters very much since - there are very very few designated revoker revocation - packets out there. */ - check_key_signature (keyblock, node, NULL); - sigcount++; - } - } - - /* write the keyblock to the temporary file */ - rc = write_keyblock (tmpfp, keyblock); - if (rc) - goto leave; - - if ( !(++count % 50) && !opt.quiet) - log_info(_("%lu keys checked so far (%lu signatures)\n"), - count, sigcount ); - - } /* end main loop */ - if (rc == -1) - rc = 0; - if (rc) - { - log_error ("keyring_search failed: %s\n", gpg_strerror (rc)); - goto leave; - } - log_info(_("%lu keys checked (%lu signatures)\n"), count, sigcount ); - if (tmpfp) - { - if (iobuf_close (tmpfp)) - { - rc = gpg_error_from_errno (errno); - log_error ("error closing `%s': %s\n", - tmpfilename, strerror (errno)); - goto leave; - } - /* because we have switched resources, we can be sure that - * the original file is closed */ - tmpfp = NULL; - } - rc = lastresname? rename_tmp_file (bakfilename, tmpfilename, - lastresname, 0) : 0; - xfree (tmpfilename); tmpfilename = NULL; - xfree (bakfilename); bakfilename = NULL; - - leave: - if (tmpfp) - iobuf_cancel (tmpfp); - xfree (tmpfilename); - xfree (bakfilename); - release_kbnode (keyblock); - keyring_lock (hd, 0); - keyring_release (hd); - return rc; -} - - -/**************** - * Perform insert/delete/update operation. - * mode 1 = insert - * 2 = delete - * 3 = update - */ -static int -do_copy (int mode, const char *fname, KBNODE root, int secret, - off_t start_offset, unsigned int n_packets ) -{ - iobuf_t fp, newfp; - int rc=0; - char *bakfname = NULL; - char *tmpfname = NULL; - - /* Open the source file. Because we do a rname, we have to check the - permissions of the file */ - if (access (fname, W_OK)) - return gpg_error_from_errno (errno); - - - fp = iobuf_open (fname); - if (mode == 1 && !fp && errno == ENOENT) { - /* insert mode but file does not exist: create a new file */ - KBNODE kbctx, node; - mode_t oldmask; - - oldmask=umask(077); - newfp = iobuf_create (fname); - umask(oldmask); - if( !newfp ) { - int tmperr = gpg_error_from_errno (errno); - log_error (_("%s: can't create: %s\n"), - fname, strerror(errno)); - return tmperr; - } - if( !opt.quiet ) - log_info(_("%s: keyring created\n"), fname ); - - kbctx=NULL; - while ( (node = walk_kbnode( root, &kbctx, 0 )) ) { - if( (rc = build_packet( newfp, node->pkt )) ) { - log_error("build_packet(%d) failed: %s\n", - node->pkt->pkttype, gpg_strerror (rc) ); - iobuf_cancel(newfp); - return rc; - } - } - if (iobuf_close(newfp)) { - int tmperr = gpg_error_from_errno (errno); - log_error ("%s: close failed: %s\n", fname, strerror(errno)); - return tmperr; - } - return 0; /* ready */ - } - - if( !fp ) { - rc = gpg_error_from_errno (errno); - log_error ("%s: can't open: %s\n", fname, strerror(errno) ); - goto leave; - } - - /* create the new file */ - rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); - if (rc) { - iobuf_close(fp); - goto leave; - } - if( mode == 1 ) { /* insert */ - /* copy everything to the new file */ - rc = copy_all_packets (fp, newfp); - if( rc != -1 ) { - log_error("%s: copy to `%s' failed: %s\n", - fname, tmpfname, gpg_strerror (rc) ); - iobuf_close(fp); - iobuf_cancel(newfp); - goto leave; - } - rc = 0; - } - - if( mode == 2 || mode == 3 ) { /* delete or update */ - /* copy first part to the new file */ - rc = copy_some_packets( fp, newfp, start_offset ); - if( rc ) { /* should never get EOF here */ - log_error ("%s: copy to `%s' failed: %s\n", - fname, tmpfname, gpg_strerror (rc) ); - iobuf_close(fp); - iobuf_cancel(newfp); - goto leave; - } - /* skip this keyblock */ - assert( n_packets ); - rc = skip_some_packets( fp, n_packets ); - if( rc ) { - log_error("%s: skipping %u packets failed: %s\n", - fname, n_packets, gpg_strerror (rc)); - iobuf_close(fp); - iobuf_cancel(newfp); - goto leave; - } - } - - if( mode == 1 || mode == 3 ) { /* insert or update */ - rc = write_keyblock (newfp, root); - if (rc) { - iobuf_close(fp); - iobuf_cancel(newfp); - goto leave; - } - } - - if( mode == 2 || mode == 3 ) { /* delete or update */ - /* copy the rest */ - rc = copy_all_packets( fp, newfp ); - if( rc != -1 ) { - log_error("%s: copy to `%s' failed: %s\n", - fname, tmpfname, gpg_strerror (rc) ); - iobuf_close(fp); - iobuf_cancel(newfp); - goto leave; - } - rc = 0; - } - - /* close both files */ - if( iobuf_close(fp) ) { - rc = gpg_error_from_errno (errno); - log_error("%s: close failed: %s\n", fname, strerror(errno) ); - goto leave; - } - if( iobuf_close(newfp) ) { - rc = gpg_error_from_errno (errno); - log_error("%s: close failed: %s\n", tmpfname, strerror(errno) ); - goto leave; - } - - rc = rename_tmp_file (bakfname, tmpfname, fname, secret); - - leave: - xfree (bakfname); - xfree (tmpfname); - return rc; -} diff --git a/g10/keyring.h b/g10/keyring.h deleted file mode 100644 index 528557a70..000000000 --- a/g10/keyring.h +++ /dev/null @@ -1,46 +0,0 @@ -/* keyring.h - Keyring operations - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GPG_KEYRING_H -#define GPG_KEYRING_H 1 - -#include "global.h" - - -typedef struct keyring_handle *KEYRING_HANDLE; - -int keyring_register_filename (const char *fname, int secret, void **ptr); -int keyring_is_writable (void *token); - -KEYRING_HANDLE keyring_new (void *token, int secret); -void keyring_release (KEYRING_HANDLE hd); -const char *keyring_get_resource_name (KEYRING_HANDLE hd); -int keyring_lock (KEYRING_HANDLE hd, int yes); -int keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb); -int keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb); -int keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb); -int keyring_locate_writable (KEYRING_HANDLE hd); -int keyring_delete_keyblock (KEYRING_HANDLE hd); -int keyring_search_reset (KEYRING_HANDLE hd); -int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, - size_t ndesc, size_t *descindex); -int keyring_rebuild_cache (void *); - -#endif /*GPG_KEYRING_H*/ diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h deleted file mode 100644 index 314d7898e..000000000 --- a/g10/keyserver-internal.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Keyserver internals */ - -#ifndef _KEYSERVER_INTERNAL_H_ -#define _KEYSERVER_INTERNAL_H_ - -#include <time.h> -#include "keyserver.h" -#include "../common/iobuf.h" -#include "types.h" - -void parse_keyserver_options(char *options); -int parse_keyserver_uri(char *uri, - const char *configname,unsigned int configlineno); -int keyserver_export(STRLIST users); -int keyserver_import(STRLIST users); -int keyserver_import_fprint(const byte *fprint,size_t fprint_len); -int keyserver_import_keyid(u32 *keyid); -int keyserver_refresh(STRLIST users); -int keyserver_search(STRLIST tokens); - -#endif /* !_KEYSERVER_INTERNAL_H_ */ diff --git a/g10/keyserver.c b/g10/keyserver.c deleted file mode 100644 index 445c07620..000000000 --- a/g10/keyserver.c +++ /dev/null @@ -1,1381 +0,0 @@ -/* keyserver.c - generic keyserver code - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <assert.h> - -#include "gpg.h" -#include "filter.h" -#include "keydb.h" -#include "status.h" -#include "exec.h" -#include "main.h" -#include "i18n.h" -#include "iobuf.h" -#include "memory.h" -#include "ttyio.h" -#include "options.h" -#include "packet.h" -#include "keyserver-internal.h" -#include "util.h" - -#define GET 0 -#define SEND 1 -#define SEARCH 2 - -struct keyrec -{ - KEYDB_SEARCH_DESC desc; - time_t createtime,expiretime; - int size,flags; - byte type; - iobuf_t uidbuf; - int lines; -}; - -struct kopts -{ - char *name; - int tell; /* tell remote process about this one */ - int *flag; -} keyserver_opts[]= -{ - {"include-revoked",1,&opt.keyserver_options.include_revoked}, - {"include-disabled",1,&opt.keyserver_options.include_disabled}, - {"include-subkeys",1,&opt.keyserver_options.include_subkeys}, - {"keep-temp-files",0,&opt.keyserver_options.keep_temp_files}, - {"honor-http-proxy",1,&opt.keyserver_options.honor_http_proxy}, - {"broken-http-proxy",1,&opt.keyserver_options.broken_http_proxy}, - {"refresh-add-fake-v3-keyids",0,&opt.keyserver_options.fake_v3_keyids}, - {"auto-key-retrieve",0,&opt.keyserver_options.auto_key_retrieve}, - {"try-dns-srv",1,&opt.keyserver_options.try_dns_srv}, - {NULL} -}; - -static int keyserver_work(int action,STRLIST list, - KEYDB_SEARCH_DESC *desc,int count); - -void -parse_keyserver_options(char *options) -{ - char *tok; - - while((tok=strsep(&options," ,"))) - { - int i,hit=0; - - if(tok[0]=='\0') - continue; - - for(i=0;keyserver_opts[i].name;i++) - { - if(ascii_strcasecmp(tok,keyserver_opts[i].name)==0) - { - *(keyserver_opts[i].flag)=1; - hit=1; - break; - } - else if(ascii_strncasecmp("no-",tok,3)==0 && - ascii_strcasecmp(&tok[3],keyserver_opts[i].name)==0) - { - *(keyserver_opts[i].flag)=0; - hit=1; - break; - } - } - - /* These options need more than just a flag */ - if(!hit) - { - if(ascii_strcasecmp(tok,"verbose")==0) - opt.keyserver_options.verbose++; - else if(ascii_strcasecmp(tok,"no-verbose")==0) - opt.keyserver_options.verbose--; -#ifdef EXEC_TEMPFILE_ONLY - else if(ascii_strcasecmp(tok,"use-temp-files")==0 || - ascii_strcasecmp(tok,"no-use-temp-files")==0) - log_info(_("WARNING: keyserver option \"%s\" is not used " - "on this platform\n"),tok); -#else - else if(ascii_strcasecmp(tok,"use-temp-files")==0) - opt.keyserver_options.use_temp_files=1; - else if(ascii_strcasecmp(tok,"no-use-temp-files")==0) - opt.keyserver_options.use_temp_files=0; -#endif - else - if(!parse_import_options(tok, - &opt.keyserver_options.import_options) && - !parse_export_options(tok, - &opt.keyserver_options.export_options)) - add_to_strlist(&opt.keyserver_options.other,tok); - } - } -} - -int -parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno) -{ - int assume_hkp=0; - - assert(uri!=NULL); - - opt.keyserver_host=NULL; - opt.keyserver_port=NULL; - opt.keyserver_opaque=NULL; - - /* Get the scheme */ - - opt.keyserver_scheme=strsep(&uri,":"); - if(uri==NULL) - { - /* Assume HKP if there is no scheme */ - assume_hkp=1; - uri=opt.keyserver_scheme; - opt.keyserver_scheme="hkp"; - } - else - { - /* Force to lowercase */ - char *i; - - for(i=opt.keyserver_scheme;*i!='\0';i++) - *i=ascii_tolower(*i); - } - - if(ascii_strcasecmp(opt.keyserver_scheme,"x-broken-hkp")==0) - { - deprecated_warning(configname,configlineno,"x-broken-hkp", - "--keyserver-options ","broken-http-proxy"); - opt.keyserver_scheme="hkp"; - opt.keyserver_options.broken_http_proxy=1; - } - else if(ascii_strcasecmp(opt.keyserver_scheme,"x-hkp")==0 - || ascii_strcasecmp(opt.keyserver_scheme,"http")==0) - { - /* Canonicalize this to "hkp" so it works with both the internal - and external keyserver interface. */ - opt.keyserver_scheme="hkp"; - } - - if(assume_hkp || (uri[0]=='/' && uri[1]=='/')) - { - /* Two slashes means network path. */ - - /* Skip over the "//", if any */ - if(!assume_hkp) - uri+=2; - - /* Get the host */ - opt.keyserver_host=strsep(&uri,":/"); - if(opt.keyserver_host[0]=='\0') - return GPG_ERR_BAD_URI; - - if(uri==NULL || uri[0]=='\0') - opt.keyserver_port=NULL; - else - { - char *ch; - - /* Get the port */ - opt.keyserver_port=strsep(&uri,"/"); - - /* Ports are digits only */ - ch=opt.keyserver_port; - while(*ch!='\0') - { - if(!digitp(ch)) - return GPG_ERR_BAD_URI; - - ch++; - } - - /* It would seem to be reasonable to limit the range of the - ports to values between 1-65535, but RFC 1738 and 1808 - imply there is no limit. Of course, the real world has - limits. */ - } - - /* (any path part of the URI is discarded for now as no keyserver - uses it yet) */ - } - else if(uri[0]!='/') - { - /* No slash means opaque. Just record the opaque blob and get - out. */ - opt.keyserver_opaque=uri; - return 0; - } - else - { - /* One slash means absolute path. We don't need to support that - yet. */ - return GPG_ERR_BAD_URI; - } - - if(opt.keyserver_scheme[0]=='\0') - return GPG_ERR_BAD_URI; - - return 0; -} - -static void -print_keyrec(int number,struct keyrec *keyrec) -{ - int i; - - iobuf_writebyte(keyrec->uidbuf,0); - iobuf_flush_temp(keyrec->uidbuf); - printf("(%d)\t%s ",number,iobuf_get_temp_buffer(keyrec->uidbuf)); - - if(keyrec->size>0) - printf("%d bit ",keyrec->size); - - if(keyrec->type) - { - const char *str = gcry_pk_algo_name (keyrec->type); - - if(str) - printf("%s ",str); - else - printf("unknown "); - } - - switch(keyrec->desc.mode) - { - case KEYDB_SEARCH_MODE_SHORT_KID: - printf("key %08lX",(ulong)keyrec->desc.u.kid[1]); - break; - - case KEYDB_SEARCH_MODE_LONG_KID: - printf("key %08lX%08lX",(ulong)keyrec->desc.u.kid[0], - (ulong)keyrec->desc.u.kid[1]); - break; - - case KEYDB_SEARCH_MODE_FPR16: - printf("key "); - for(i=0;i<16;i++) - printf("%02X",(unsigned char)keyrec->desc.u.fpr[i]); - break; - - case KEYDB_SEARCH_MODE_FPR20: - printf("key "); - for(i=0;i<20;i++) - printf("%02X",(unsigned char)keyrec->desc.u.fpr[i]); - break; - - default: - BUG(); - break; - } - - if(keyrec->createtime>0) - printf(", created %s",strtimestamp(keyrec->createtime)); - - if(keyrec->expiretime>0) - printf(", expires %s",strtimestamp(keyrec->expiretime)); - - if(keyrec->flags&1) - printf(" (%s)",("revoked")); - if(keyrec->flags&2) - printf(" (%s)",("disabled")); - if(keyrec->flags&4) - printf(" (%s)",("expired")); - - printf("\n"); -} - -/* Returns a keyrec (which must be freed) once a key is complete, and - NULL otherwise. Call with a NULL keystring once key parsing is - complete to return any unfinished keys. */ -static struct keyrec * -parse_keyrec(char *keystring) -{ - static struct keyrec *work=NULL; - struct keyrec *ret=NULL; - char *record; - int i; - - if(keystring==NULL) - { - if(work==NULL) - return NULL; - else if(work->desc.mode==KEYDB_SEARCH_MODE_NONE) - { - xfree (work); - return NULL; - } - else - { - ret=work; - work=NULL; - return ret; - } - } - - if(work==NULL) - { - work=xcalloc (1,sizeof(struct keyrec)); - work->uidbuf=iobuf_temp(); - } - - /* Remove trailing whitespace */ - for(i=strlen(keystring);i>0;i--) - if(ascii_isspace(keystring[i-1])) - keystring[i-1]='\0'; - else - break; - - if((record=strsep(&keystring,":"))==NULL) - return ret; - - if(ascii_strcasecmp("pub",record)==0) - { - char *tok; - - if(work->desc.mode) - { - ret=work; - work=xcalloc (1,sizeof(struct keyrec)); - work->uidbuf=iobuf_temp(); - } - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - classify_user_id(tok,&work->desc); - if(work->desc.mode!=KEYDB_SEARCH_MODE_SHORT_KID - && work->desc.mode!=KEYDB_SEARCH_MODE_LONG_KID - && work->desc.mode!=KEYDB_SEARCH_MODE_FPR16 - && work->desc.mode!=KEYDB_SEARCH_MODE_FPR20) - { - work->desc.mode=KEYDB_SEARCH_MODE_NONE; - return ret; - } - - /* Note all items after this are optional. This allows us to - have a pub line as simple as pub:keyid and nothing else. */ - - work->lines++; - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - work->type=atoi(tok); - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - work->size=atoi(tok); - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - work->createtime=atoi(tok); - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - work->expiretime=atoi(tok); - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - while(*tok) - switch(*tok++) - { - case 'r': - case 'R': - work->flags|=1; - break; - - case 'd': - case 'D': - work->flags|=2; - break; - - case 'e': - case 'E': - work->flags|=4; - break; - } - - if(work->expiretime && work->expiretime<=make_timestamp()) - work->flags|=4; - } - else if(ascii_strcasecmp("uid",record)==0 && work->desc.mode) - { - char *userid,*tok,*decoded; - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - if(strlen(tok)==0) - return ret; - - userid=tok; - - /* By definition, de-%-encoding is always smaller than the - original string so we can decode in place. */ - - i=0; - - while(*tok) - if(tok[0]=='%' && tok[1] && tok[2]) - { - if((userid[i]=hextobyte(&tok[1]))==-1) - userid[i]='?'; - - i++; - tok+=3; - } - else - userid[i++]=*tok++; - - /* We don't care about the other info provided in the uid: line - since no keyserver supports marking userids with timestamps - or revoked/expired/disabled yet. */ - - /* No need to check for control characters, as utf8_to_native - does this for us. */ - - decoded=utf8_to_native(userid,i,0); - iobuf_writestr(work->uidbuf,decoded); - xfree (decoded); - iobuf_writestr(work->uidbuf,"\n\t"); - work->lines++; - } - - /* Ignore any records other than "pri" and "uid" for easy future - growth. */ - - return ret; -} - -/* TODO: do this as a list sent to keyserver_work rather than calling - it once for each key to get the correct counts after the import - (cosmetics, really) and to better take advantage of the keyservers - that can do multiple fetches in one go (LDAP). */ -static int -show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search) -{ - char *answer; - - if(count && opt.command_fd==-1) - { - static int from=1; - tty_printf("Keys %d-%d of %d for \"%s\". ",from,numdesc,count,search); - from=numdesc+1; - } - - answer=cpr_get_no_help("keysearch.prompt", - _("Enter number(s), N)ext, or Q)uit > ")); - /* control-d */ - if(answer[0]=='\x04') - { - printf("Q\n"); - answer[0]='q'; - } - - if(answer[0]=='q' || answer[0]=='Q') - { - xfree (answer); - return 1; - } - else if(atoi(answer)>=1 && atoi(answer)<=numdesc) - { - char *split=answer,*num; - - while((num=strsep(&split," ,"))!=NULL) - if(atoi(num)>=1 && atoi(num)<=numdesc) - keyserver_work(GET,NULL,&desc[atoi(num)-1],1); - - xfree (answer); - return 1; - } - - return 0; -} - -/* Count and searchstr are just for cosmetics. If the count is too - small, it will grow safely. If negative it disables the "Key x-y - of z" messages. */ -static void -keyserver_search_prompt(iobuf_t buffer,const char *searchstr) -{ - int i=0,validcount=0,started=0,header=0,count=1; - unsigned int maxlen,buflen; - KEYDB_SEARCH_DESC *desc; - byte *line=NULL; - /* TODO: Something other than 23? That's 24-1 (the prompt). */ - int maxlines=23,numlines=0; - - desc=xmalloc (count*sizeof(KEYDB_SEARCH_DESC)); - - for(;;) - { - struct keyrec *keyrec; - int rl; - - maxlen=1024; - rl=iobuf_read_line(buffer,&line,&buflen,&maxlen); - - if(opt.with_colons) - { - if(!header && ascii_strncasecmp("SEARCH ",line,7)==0 - && ascii_strncasecmp(" BEGIN",&line[strlen(line)-7],6)==0) - { - header=1; - continue; - } - else if(ascii_strncasecmp("SEARCH ",line,7)==0 - && ascii_strncasecmp(" END",&line[strlen(line)-5],4)==0) - continue; - - printf("%s",line); - } - - /* Look for an info: line. The only current info: values - defined are the version and key count. */ - if(!started && rl>0 && ascii_strncasecmp("info:",line,5)==0) - { - char *tok,*str=&line[5]; - - if((tok=strsep(&str,":"))!=NULL) - { - int version; - - if(sscanf(tok,"%d",&version)!=1) - version=1; - - if(version!=1) - { - log_error(_("invalid keyserver protocol " - "(us %d!=handler %d)\n"),1,version); - break; - } - } - - if((tok=strsep(&str,":"))!=NULL && sscanf(tok,"%d",&count)==1) - { - if(count==0) - goto notfound; - else if(count<0) - count=10; - else - validcount=1; - - desc=xrealloc(desc,count*sizeof(KEYDB_SEARCH_DESC)); - } - - started=1; - continue; - } - - if(rl==0) - { - keyrec=parse_keyrec(NULL); - - if(keyrec==NULL) - { - if(i==0) - { - count=0; - break; - } - - if(i!=count) - validcount=0; - - for(;;) - { - if(show_prompt(desc,i,validcount?count:0,searchstr)) - break; - validcount=0; - } - - break; - } - } - else - keyrec=parse_keyrec(line); - - if(i==count) - { - /* keyserver helper sent more keys than they claimed in the - info: line. */ - count+=10; - desc=xrealloc(desc,count*sizeof(KEYDB_SEARCH_DESC)); - validcount=0; - } - - if(keyrec) - { - desc[i]=keyrec->desc; - - if(!opt.with_colons) - { - if(numlines+keyrec->lines>maxlines) - { - if(show_prompt(desc,i,validcount?count:0,searchstr)) - break; - else - numlines=0; - } - - print_keyrec(i+1,keyrec); - } - - numlines+=keyrec->lines; - iobuf_close(keyrec->uidbuf); - xfree (keyrec); - - started=1; - i++; - } - } - - xfree (desc); - xfree (line); - - notfound: - if(count==0) - { - if(searchstr) - log_info(_("key \"%s\" not found on keyserver\n"),searchstr); - else - log_info(_("key not found on keyserver\n")); - return; - } -} - -#define KEYSERVER_ARGS_KEEP " -o \"%O\" \"%I\"" -#define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\"" - -static int -keyserver_spawn(int action,STRLIST list, - KEYDB_SEARCH_DESC *desc,int count,int *prog) -{ - int ret=0,i,gotversion=0,outofband=0; - STRLIST temp; - unsigned int maxlen,buflen; - char *command=NULL,*searchstr=NULL; - byte *line=NULL; - struct kopts *kopts; - struct exec_info *spawn; - -#ifdef EXEC_TEMPFILE_ONLY - opt.keyserver_options.use_temp_files=1; -#endif - - /* Push the libexecdir into path. If DISABLE_KEYSERVER_PATH is set, - use the 0 arg to replace the path. */ -#ifdef DISABLE_KEYSERVER_PATH - set_exec_path(GNUPG_LIBEXECDIR,0); -#else - set_exec_path(GNUPG_LIBEXECDIR,opt.exec_path_set); -#endif - - /* Build the filename for the helper to execute */ - command=xmalloc (strlen("gpgkeys_")+strlen(opt.keyserver_scheme)+1); - strcpy(command,"gpgkeys_"); - strcat(command,opt.keyserver_scheme); - - if(opt.keyserver_options.use_temp_files) - { - if(opt.keyserver_options.keep_temp_files) - { - command=xrealloc(command,strlen(command)+ - strlen(KEYSERVER_ARGS_KEEP)+1); - strcat(command,KEYSERVER_ARGS_KEEP); - } - else - { - command=xrealloc(command,strlen(command)+ - strlen(KEYSERVER_ARGS_NOKEEP)+1); - strcat(command,KEYSERVER_ARGS_NOKEEP); - } - - ret=exec_write(&spawn,NULL,command,NULL,0,0); - } - else - ret=exec_write(&spawn,command,NULL,NULL,0,0); - - if(ret) - return ret; - - fprintf(spawn->tochild,"# This is a gpg keyserver communications file\n"); - fprintf(spawn->tochild,"VERSION %d\n",KEYSERVER_PROTO_VERSION); - fprintf(spawn->tochild,"PROGRAM %s\n",VERSION); - - if(opt.keyserver_opaque) - fprintf(spawn->tochild,"OPAQUE %s\n",opt.keyserver_opaque); - else - { - if(opt.keyserver_host) - fprintf(spawn->tochild,"HOST %s\n",opt.keyserver_host); - - if(opt.keyserver_port) - fprintf(spawn->tochild,"PORT %s\n",opt.keyserver_port); - } - - /* Write options */ - - for(i=0,kopts=keyserver_opts;kopts[i].name;i++) - if(*(kopts[i].flag) && kopts[i].tell) - fprintf(spawn->tochild,"OPTION %s\n",kopts[i].name); - - for(i=0;i<opt.keyserver_options.verbose;i++) - fprintf(spawn->tochild,"OPTION verbose\n"); - - temp=opt.keyserver_options.other; - - for(;temp;temp=temp->next) - fprintf(spawn->tochild,"OPTION %s\n",temp->d); - - switch(action) - { - case GET: - { - fprintf(spawn->tochild,"COMMAND GET\n\n"); - - /* Which keys do we want? */ - - for(i=0;i<count;i++) - { - if(desc[i].mode==KEYDB_SEARCH_MODE_FPR20) - { - int f; - - fprintf(spawn->tochild,"0x"); - - for(f=0;f<MAX_FINGERPRINT_LEN;f++) - fprintf(spawn->tochild,"%02X",(byte)desc[i].u.fpr[f]); - - fprintf(spawn->tochild,"\n"); - } - else if(desc[i].mode==KEYDB_SEARCH_MODE_FPR16) - { - int f; - - fprintf(spawn->tochild,"0x"); - - for(f=0;f<16;f++) - fprintf(spawn->tochild,"%02X",(byte)desc[i].u.fpr[f]); - - fprintf(spawn->tochild,"\n"); - } - else if(desc[i].mode==KEYDB_SEARCH_MODE_LONG_KID) - fprintf(spawn->tochild,"0x%08lX%08lX\n", - (ulong)desc[i].u.kid[0], - (ulong)desc[i].u.kid[1]); - else - fprintf(spawn->tochild,"0x%08lX\n", - (ulong)desc[i].u.kid[1]); - } - - fprintf(spawn->tochild,"\n"); - - break; - } - - case SEND: - { - STRLIST key; - - /* Note the extra \n here to send an empty keylist block */ - fprintf(spawn->tochild,"COMMAND SEND\n\n\n"); - - for(key=list;key!=NULL;key=key->next) - { - armor_filter_context_t afx; - iobuf_t buffer=iobuf_temp(); - KBNODE block; - - temp=NULL; - add_to_strlist(&temp,key->d); - - memset(&afx,0,sizeof(afx)); - afx.what=1; - iobuf_push_filter(buffer,armor_filter,&afx); - - /* TODO: Don't use the keyblock hack here - instead, - output each key as a different ascii armored blob with - its own INFO section. */ - - if(export_pubkeys_stream(buffer,temp,&block, - opt.keyserver_options.export_options)==-1) - iobuf_close(buffer); - else - { - KBNODE node; - - iobuf_flush_temp(buffer); - - merge_keys_and_selfsig(block); - - fprintf(spawn->tochild,"INFO %s BEGIN\n",key->d); - - for(node=block;node;node=node->next) - { - switch(node->pkt->pkttype) - { - default: - continue; - - case PKT_PUBLIC_KEY: - case PKT_PUBLIC_SUBKEY: - { - PKT_public_key *pk=node->pkt->pkt.public_key; - - keyid_from_pk(pk,NULL); - - fprintf(spawn->tochild,"%sb:%08lX%08lX:%u:%u:%u:%u:", - node->pkt->pkttype==PKT_PUBLIC_KEY?"pu":"su", - (ulong)pk->keyid[0],(ulong)pk->keyid[1], - pk->pubkey_algo, - nbits_from_pk(pk), - pk->timestamp, - pk->expiredate); - - if(pk->is_revoked) - fprintf(spawn->tochild,"r"); - if(pk->has_expired) - fprintf(spawn->tochild,"e"); - - fprintf(spawn->tochild,"\n"); - - break; - } - - case PKT_USER_ID: - { - PKT_user_id *uid=node->pkt->pkt.user_id; - int r; - - if(uid->attrib_data) - continue; - - fprintf(spawn->tochild,"uid:"); - - /* Quote ':', '%', and any 8-bit - characters */ - for(r=0;r<uid->len;r++) - { - if(uid->name[r]==':' || uid->name[r]=='%' - || uid->name[r]&0x80) - fprintf(spawn->tochild,"%%%02X",uid->name[r]); - else - fprintf(spawn->tochild,"%c",uid->name[r]); - } - - fprintf(spawn->tochild,":%u:%u:", - uid->created,uid->expiredate); - - if(uid->is_revoked) - fprintf(spawn->tochild,"r"); - if(uid->is_expired) - fprintf(spawn->tochild,"e"); - - fprintf(spawn->tochild,"\n"); - } - } - } - - fprintf(spawn->tochild,"INFO %s END\n",key->d); - - fprintf(spawn->tochild,"KEY %s BEGIN\n",key->d); - fwrite(iobuf_get_temp_buffer(buffer), - iobuf_get_temp_length(buffer),1,spawn->tochild); - fprintf(spawn->tochild,"KEY %s END\n",key->d); - - iobuf_close(buffer); - release_kbnode(block); - } - - free_strlist(temp); - } - - break; - } - - case SEARCH: - { - STRLIST key; - - fprintf(spawn->tochild,"COMMAND SEARCH\n\n"); - - /* Which keys do we want? Remember that the gpgkeys_ program - is going to lump these together into a search string. */ - - for(key=list;key!=NULL;key=key->next) - { - fprintf(spawn->tochild,"%s\n",key->d); - if(key!=list) - { - searchstr=xrealloc(searchstr, - strlen(searchstr)+strlen(key->d)+2); - strcat(searchstr," "); - } - else - { - searchstr=xmalloc (strlen(key->d)+1); - searchstr[0]='\0'; - } - - strcat(searchstr,key->d); - } - - fprintf(spawn->tochild,"\n"); - - break; - } - - default: - log_fatal(_("no keyserver action!\n")); - break; - } - - /* Done sending, so start reading. */ - ret=exec_read(spawn); - if(ret) - goto fail; - - /* Now handle the response */ - - for(;;) - { - int plen; - char *ptr; - - maxlen=1024; - if(iobuf_read_line(spawn->fromchild,&line,&buflen,&maxlen)==0) - { - ret = iobuf_error (spawn->fromchild); - goto fail; /* i.e. EOF */ - } - - ptr=line; - - /* remove trailing whitespace */ - plen=strlen(ptr); - while(plen>0 && ascii_isspace(ptr[plen-1])) - plen--; - plen[ptr]='\0'; - - if(*ptr=='\0') - break; - - if(ascii_strncasecmp(ptr,"VERSION ",8)==0) - { - gotversion=1; - - if(atoi(&ptr[8])!=KEYSERVER_PROTO_VERSION) - { - log_error(_("invalid keyserver protocol (us %d!=handler %d)\n"), - KEYSERVER_PROTO_VERSION,atoi(&ptr[8])); - goto fail; - } - } - else if(ascii_strncasecmp(ptr,"PROGRAM ",8)==0) - { - if(ascii_strncasecmp(&ptr[8],VERSION,strlen(VERSION))!=0) - log_info(_("WARNING: keyserver handler from a different " - "version of GnuPG (%s)\n"),&ptr[8]); - } - else if(ascii_strncasecmp(ptr,"OPTION OUTOFBAND",16)==0) - outofband=1; /* Currently the only OPTION */ - } - - if(!gotversion) - { - log_error(_("keyserver did not send VERSION\n")); - goto fail; - } - - if(!outofband) - switch(action) - { - case GET: - { - void *stats_handle; - - stats_handle=import_new_stats_handle(); - - /* Slurp up all the key data. In the future, it might be - nice to look for KEY foo OUTOFBAND and FAILED indicators. - It's harmless to ignore them, but ignoring them does make - gpg complain about "no valid OpenPGP data found". One - way to do this could be to continue parsing this - line-by-line and make a temp iobuf for each key. */ - - import_keys_stream(spawn->fromchild,stats_handle, - opt.keyserver_options.import_options); - - import_print_stats(stats_handle); - import_release_stats_handle(stats_handle); - - break; - } - - /* Nothing to do here */ - case SEND: - break; - - case SEARCH: - { - keyserver_search_prompt(spawn->fromchild,searchstr); - - break; - } - - default: - log_fatal(_("no keyserver action!\n")); - break; - } - - fail: - xfree (line); - - *prog=exec_finish(spawn); - - return ret; -} - -static int -keyserver_work(int action,STRLIST list,KEYDB_SEARCH_DESC *desc,int count) -{ - int rc=0,ret=0; - - if(opt.keyserver_scheme==NULL) - { - log_error(_("no keyserver known (use option --keyserver)\n")); - return GPG_ERR_BAD_URI; - } - -#ifdef DISABLE_KEYSERVER_HELPERS - - log_error(_("external keyserver calls are not supported in this build\n")); - return GPG_ERR_KEYSERVER; - -#else - /* Spawn a handler */ - - rc=keyserver_spawn(action,list,desc,count,&ret); - if(ret) - { - switch(ret) - { - case KEYSERVER_SCHEME_NOT_FOUND: - log_error(_("no handler for keyserver scheme \"%s\"\n"), - opt.keyserver_scheme); - break; - - case KEYSERVER_NOT_SUPPORTED: - log_error(_("action \"%s\" not supported with keyserver " - "scheme \"%s\"\n"), - action==GET?"get":action==SEND?"send": - action==SEARCH?"search":"unknown", - opt.keyserver_scheme); - break; - - case KEYSERVER_VERSION_ERROR: - log_error(_("gpgkeys_%s does not support handler version %d\n"), - opt.keyserver_scheme,KEYSERVER_PROTO_VERSION); - break; - - case KEYSERVER_INTERNAL_ERROR: - default: - log_error(_("keyserver internal error\n")); - break; - } - - return GPG_ERR_KEYSERVER; - } - - if(rc) - { - log_error(_("keyserver communications error: %s\n"),gpg_strerror (rc)); - - return rc; - } - - return 0; -#endif /* ! DISABLE_KEYSERVER_HELPERS*/ -} - -int -keyserver_export(STRLIST users) -{ - /* We better ask for confirmation when the user entered --send-keys - without arguments. Sending all keys might not be the thing he - intended to do */ - if (users || opt.batch || opt.answer_yes) - ; - else if ( !cpr_get_answer_is_yes - ("keyserver_export.send_all", - _("Do you really want to send all your " - "public keys to the keyserver? (y/N) "))) - return -1; - - return keyserver_work(SEND,users,NULL,0); -} - -int -keyserver_import(STRLIST users) -{ - KEYDB_SEARCH_DESC *desc; - int num=100,count=0; - int rc=0; - - /* Build a list of key ids */ - desc=xmalloc (sizeof(KEYDB_SEARCH_DESC)*num); - - for(;users;users=users->next) - { - classify_user_id (users->d, &desc[count]); - if(desc[count].mode!=KEYDB_SEARCH_MODE_SHORT_KID && - desc[count].mode!=KEYDB_SEARCH_MODE_LONG_KID && - desc[count].mode!=KEYDB_SEARCH_MODE_FPR16 && - desc[count].mode!=KEYDB_SEARCH_MODE_FPR20) - { - log_error(_("skipping invalid key ID \"%s\"\n"),users->d); - continue; - } - - count++; - if(count==num) - { - num+=100; - desc=xrealloc(desc,sizeof(KEYDB_SEARCH_DESC)*num); - } - } - - if(count>0) - rc=keyserver_work(GET,NULL,desc,count); - - xfree (desc); - - return rc; -} - -int -keyserver_import_fprint(const byte *fprint,size_t fprint_len) -{ - KEYDB_SEARCH_DESC desc; - - memset(&desc,0,sizeof(desc)); - - if(fprint_len==16) - desc.mode=KEYDB_SEARCH_MODE_FPR16; - else if(fprint_len==20) - desc.mode=KEYDB_SEARCH_MODE_FPR20; - else - return -1; - - memcpy(desc.u.fpr,fprint,fprint_len); - - return keyserver_work(GET,NULL,&desc,1); -} - -int -keyserver_import_keyid(u32 *keyid) -{ - KEYDB_SEARCH_DESC desc; - - memset(&desc,0,sizeof(desc)); - - desc.mode=KEYDB_SEARCH_MODE_LONG_KID; - desc.u.kid[0]=keyid[0]; - desc.u.kid[1]=keyid[1]; - - return keyserver_work(GET,NULL,&desc,1); -} - -/* code mostly stolen from do_export_stream */ -static int -keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) -{ - int rc=0,ndesc,num=100; - KBNODE keyblock=NULL,node; - KEYDB_HANDLE kdbhd; - KEYDB_SEARCH_DESC *desc; - STRLIST sl; - - *count=0; - - *klist=xmalloc (sizeof(KEYDB_SEARCH_DESC)*num); - - kdbhd=keydb_new(0); - - if(!users) - { - ndesc = 1; - desc = xcalloc (1, ndesc * sizeof *desc); - desc[0].mode = KEYDB_SEARCH_MODE_FIRST; - } - else - { - for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) - ; - desc = xmalloc ( ndesc * sizeof *desc); - - for (ndesc=0, sl=users; sl; sl = sl->next) - { - if(classify_user_id (sl->d, desc+ndesc)) - ndesc++; - else - log_error (_("key `%s' not found: %s\n"), - sl->d, gpg_strerror (GPG_ERR_INV_USER_ID)); - } - } - - while (!(rc = keydb_search (kdbhd, desc, ndesc))) - { - if (!users) - desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - - /* read the keyblock */ - rc = keydb_get_keyblock (kdbhd, &keyblock ); - if( rc ) - { - log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - if((node=find_kbnode(keyblock,PKT_PUBLIC_KEY))) - { - /* This is to work around a bug in some keyservers (pksd and - OKS) that calculate v4 RSA keyids as if they were v3 RSA. - The answer is to refresh both the correct v4 keyid - (e.g. 99242560) and the fake v3 keyid (e.g. 68FDDBC7). - This only happens for key refresh using the HKP scheme - and if the refresh-add-fake-v3-keyids keyserver option is - set. */ - if(fakev3 && is_RSA(node->pkt->pkt.public_key->pubkey_algo) && - node->pkt->pkt.public_key->version>=4) - { - (*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID; - v3_keyid (node->pkt->pkt.public_key->pkey[0], - (*klist)[*count].u.kid); - (*count)++; - - if(*count==num) - { - num+=100; - *klist=xrealloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num); - } - } - - /* v4 keys get full fingerprints. v3 keys get long keyids. - This is because it's easy to calculate any sort of key id - from a v4 fingerprint, but not a v3 fingerprint. */ - - if(node->pkt->pkt.public_key->version<4) - { - (*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID; - keyid_from_pk(node->pkt->pkt.public_key, - (*klist)[*count].u.kid); - } - else - { - size_t dummy; - - (*klist)[*count].mode=KEYDB_SEARCH_MODE_FPR20; - fingerprint_from_pk(node->pkt->pkt.public_key, - (*klist)[*count].u.fpr,&dummy); - } - - (*count)++; - - if(*count==num) - { - num+=100; - *klist=xrealloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num); - } - } - } - - if(rc==-1) - rc=0; - - leave: - xfree (desc); - keydb_release(kdbhd); - release_kbnode(keyblock); - - return rc; -} - -/* Note this is different than the original HKP refresh. It allows - usernames to refresh only part of the keyring. */ - -int -keyserver_refresh(STRLIST users) -{ - int rc,count,fakev3=0; - KEYDB_SEARCH_DESC *desc; - - /* We switch merge_only on during a refresh, as 'refresh' should - never import new keys, even if their keyids match. Is it worth - preserving the old merge_only value here? */ - opt.merge_only=1; - - /* If refresh_add_fake_v3_keyids is on and it's a HKP or MAILTO - scheme, then enable fake v3 keyid generation. */ - if(opt.keyserver_options.fake_v3_keyids && opt.keyserver_scheme && - (ascii_strcasecmp(opt.keyserver_scheme,"hkp")==0 || - ascii_strcasecmp(opt.keyserver_scheme,"mailto")==0)) - fakev3=1; - - rc=keyidlist(users,&desc,&count,fakev3); - if(rc) - return rc; - - if(count>0) - { - if(opt.keyserver_uri) - { - if(count==1) - log_info(_("refreshing 1 key from %s\n"),opt.keyserver_uri); - else - log_info(_("refreshing %d keys from %s\n"), - count,opt.keyserver_uri); - } - - rc=keyserver_work(GET,NULL,desc,count); - } - - xfree (desc); - - return rc; -} - -int -keyserver_search(STRLIST tokens) -{ - if(tokens) - return keyserver_work(SEARCH,tokens,NULL,0); - else - return 0; -} diff --git a/g10/main.h b/g10/main.h deleted file mode 100644 index 52bfa7659..000000000 --- a/g10/main.h +++ /dev/null @@ -1,272 +0,0 @@ -/* main.h - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_MAIN_H -#define G10_MAIN_H -#include "types.h" -#include "gpg.h" -#include "../common/iobuf.h" -#include "mpi.h" -#include "cipher.h" -#include "keydb.h" - -/* It could be argued that the default cipher should be 3DES rather - than CAST5, and the default compression should be 0 - (i.e. uncompressed) rather than 1 (zip). */ -#define DEFAULT_CIPHER_ALGO CIPHER_ALGO_CAST5 -#define DEFAULT_DIGEST_ALGO DIGEST_ALGO_SHA1 -#define DEFAULT_COMPRESS_ALGO 1 - -typedef struct { - int header_okay; - PK_LIST pk_list; - cipher_filter_context_t cfx; -} encrypt_filter_context_t; - -struct groupitem -{ - char *name; - STRLIST values; - struct groupitem *next; -}; - -/*-- g10.c --*/ -extern int g10_errors_seen; - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) - void g10_exit(int rc) __attribute__ ((noreturn)); -#else - void g10_exit(int rc); -#endif -void print_pubkey_algo_note( int algo ); -void print_cipher_algo_note( int algo ); -void print_digest_algo_note( int algo ); - -/*-- armor.c --*/ -char *make_radix64_string( const byte *data, size_t len ); - -/*-- misc.c --*/ -void trap_unaligned(void); -int disable_core_dumps(void); -u16 checksum_u16( unsigned n ); -u16 checksum( byte *p, unsigned n ); -u16 checksum_mpi( gcry_mpi_t a ); -u32 buffer_to_u32( const byte *buffer ); -const byte *get_session_marker( size_t *rlen ); -int openpgp_cipher_test_algo( int algo ); -int openpgp_pk_test_algo( int algo, unsigned int usage_flags ); -int openpgp_pk_algo_usage ( int algo ); -int openpgp_md_test_algo( int algo ); -int openpgp_md_map_name (const char *string); -int openpgp_cipher_map_name (const char *string); -int openpgp_pk_map_name (const char *string); - -#ifdef USE_IDEA -void idea_cipher_warn( int show ); -#else -#define idea_cipher_warn(a) -#endif - -struct expando_args -{ - PKT_public_key *pk; - PKT_secret_key *sk; - byte imagetype; -}; - -char *pct_expando(const char *string,struct expando_args *args); -int hextobyte( const char *s ); -void deprecated_warning(const char *configname,unsigned int configlineno, - const char *option,const char *repl1,const char *repl2); -const char *compress_algo_to_string(int algo); -int string_to_compress_algo(const char *string); -int check_compress_algo(int algo); -int default_cipher_algo(void); -int default_compress_algo(void); -const char *compliance_option_string(void); -void compliance_failure(void); - -struct parse_options -{ - char *name; - unsigned int bit; -}; - -int parse_options(char *str,unsigned int *options,struct parse_options *opts); - - -/* Temporary helpers. */ -int pubkey_get_npkey( int algo ); -int pubkey_get_nskey( int algo ); -int pubkey_get_nsig( int algo ); -int pubkey_get_nenc( int algo ); -unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey ); - -/* MPI helpers. */ -int mpi_write( iobuf_t out, gcry_mpi_t a ); -int mpi_write_opaque( iobuf_t out, gcry_mpi_t a ); -gcry_mpi_t mpi_read(iobuf_t inp, unsigned int *ret_nread, int secure ); -gcry_mpi_t mpi_read_opaque(iobuf_t inp, unsigned int *ret_nread ); -int mpi_print( FILE *fp, gcry_mpi_t a, int mode ); - - - - -/*-- helptext.c --*/ -void display_online_help( const char *keyword ); - -/*-- encode.c --*/ -int encode_symmetric( const char *filename ); -int encode_store( const char *filename ); -int encode_crypt( const char *filename, STRLIST remusr ); -void encode_crypt_files(int nfiles, char **files, STRLIST remusr); -int encrypt_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len); - - -/*-- sign.c --*/ -int complete_sig( PKT_signature *sig, PKT_secret_key *sk, MD_HANDLE md ); -int sign_file( STRLIST filenames, int detached, STRLIST locusr, - int do_encrypt, STRLIST remusr, const char *outfile ); -int clearsign_file( const char *fname, STRLIST locusr, const char *outfile ); -int sign_symencrypt_file (const char *fname, STRLIST locusr); - -/*-- sig-check.c --*/ -int check_revocation_keys (PKT_public_key *pk, PKT_signature *sig); -int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig ); -int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk, - PKT_public_key *ret_pk, int *is_selfsig, - u32 *r_expiredate, int *r_expired ); - -/*-- delkey.c --*/ -int delete_keys( STRLIST names, int secret, int allow_both ); - -/*-- keyedit.c --*/ -void keyedit_menu( const char *username, STRLIST locusr, STRLIST cmds, - int sign_mode ); -void show_basic_key_info (KBNODE keyblock); - -/*-- keygen.c --*/ -u32 ask_expire_interval(int object); -u32 ask_expiredate(void); -void generate_keypair( const char *fname, const char *card_serialno ); -int keygen_set_std_prefs (const char *string,int personal); -PKT_user_id *keygen_get_std_prefs (void); -int keygen_add_key_expire( PKT_signature *sig, void *opaque ); -int keygen_add_std_prefs( PKT_signature *sig, void *opaque ); -int keygen_upd_std_prefs( PKT_signature *sig, void *opaque ); -int keygen_add_keyserver_url(PKT_signature *sig, void *opaque); -int keygen_add_revkey(PKT_signature *sig, void *opaque); -int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ); - -/*-- openfile.c --*/ -int overwrite_filep( const char *fname ); -char *make_outfile_name( const char *iname ); -char *ask_outfile_name( const char *name, size_t namelen ); -int open_outfile( const char *iname, int mode, iobuf_t *a ); -iobuf_t open_sigfile( const char *iname, progress_filter_context_t *pfx ); -void try_make_homedir( const char *fname ); - -/*-- seskey.c --*/ -void make_session_key( DEK *dek ); -gcry_mpi_t encode_session_key( DEK *dek, unsigned int nbits); -gcry_mpi_t encode_md_value( int pubkey_algo, MD_HANDLE md, - int hash_algo, unsigned nbits, int v3compathack ); - -/*-- comment.c --*/ -KBNODE make_comment_node_from_buffer (const char *s, size_t n); -KBNODE make_comment_node( const char *s ); -KBNODE make_mpi_comment_node( const char *s, gcry_mpi_t a ); - -/*-- import.c --*/ -int parse_import_options(char *str,unsigned int *options); -void import_keys( char **fnames, int nnames, - void *stats_hd, unsigned int options ); -int import_keys_stream( iobuf_t inp, - void *stats_hd, unsigned int options ); -void *import_new_stats_handle (void); -void import_release_stats_handle (void *p); -void import_print_stats (void *hd); - -int collapse_uids( KBNODE *keyblock ); - -/*-- export.c --*/ -int parse_export_options(char *str,unsigned int *options); -int export_pubkeys( STRLIST users, unsigned int options ); -int export_pubkeys_stream( iobuf_t out, STRLIST users, - KBNODE *keyblock_out, unsigned int options ); -int export_seckeys( STRLIST users ); -int export_secsubkeys( STRLIST users ); - -/* dearmor.c --*/ -int dearmor_file( const char *fname ); -int enarmor_file( const char *fname ); - -/*-- revoke.c --*/ -struct revocation_reason_info; -int gen_revoke( const char *uname ); -int gen_desig_revoke( const char *uname ); -int revocation_reason_build_cb( PKT_signature *sig, void *opaque ); -struct revocation_reason_info * - ask_revocation_reason( int key_rev, int cert_rev, int hint ); -void release_revocation_reason_info( struct revocation_reason_info *reason ); - -/*-- keylist.c --*/ -void public_key_list( STRLIST list ); -void secret_key_list( STRLIST list ); -void reorder_keyblock (KBNODE keyblock); -void list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque ); -void print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode); -void show_policy_url(PKT_signature *sig,int indent,int mode); -void show_keyserver_url(PKT_signature *sig,int indent,int mode); -void show_notation(PKT_signature *sig,int indent,int mode); -void dump_attribs(const PKT_user_id *uid, - PKT_public_key *pk,PKT_secret_key *sk); -void set_attrib_fd(int fd); -void print_seckey_info (PKT_secret_key *sk); -void print_pubkey_info (FILE *fp, PKT_public_key *pk); - -/*-- verify.c --*/ -void print_file_status( int status, const char *name, int what ); -int verify_signatures( int nfiles, char **files ); -int verify_files( int nfiles, char **files ); - -/*-- decrypt.c --*/ -int decrypt_message( const char *filename ); -void decrypt_messages(int nfiles, char **files); - -/*-- plaintext.c --*/ -int hash_datafiles( MD_HANDLE md, MD_HANDLE md2, - STRLIST files, const char *sigfilename, int textmode ); - -/*-- pipemode.c --*/ -void run_in_pipemode (void); - -/*-- card-util.c --*/ -void change_pin (int no); -void card_status (FILE *fp, char *serialnobuf, size_t serialnobuflen); -void card_edit (STRLIST commands); - -/*-- signal.c --*/ -void init_signals(void); -void pause_on_sigusr( int which ); -void block_all_signals(void); -void unblock_all_signals(void); - -#endif /*G10_MAIN_H*/ diff --git a/g10/mainproc.c b/g10/mainproc.c deleted file mode 100644 index 40b9bd20a..000000000 --- a/g10/mainproc.c +++ /dev/null @@ -1,1758 +0,0 @@ -/* mainproc.c - handle packets - * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <time.h> - -#include "packet.h" -#include "iobuf.h" -#include "memory.h" -#include "options.h" -#include "util.h" -#include "cipher.h" -#include "keydb.h" -#include "filter.h" -#include "main.h" -#include "status.h" -#include "i18n.h" -#include "trustdb.h" -#include "keyserver-internal.h" -#include "photoid.h" - - -struct kidlist_item { - struct kidlist_item *next; - u32 kid[2]; - int pubkey_algo; - int reason; -}; - - - -/**************** - * Structure to hold the context - */ -typedef struct mainproc_context *CTX; -struct mainproc_context { - struct mainproc_context *anchor; /* may be useful in the future */ - PKT_public_key *last_pubkey; - PKT_secret_key *last_seckey; - PKT_user_id *last_user_id; - md_filter_context_t mfx; - int sigs_only; /* process only signatures and reject all other stuff */ - int encrypt_only; /* process only encrytion messages */ - STRLIST signed_data; - const char *sigfilename; - DEK *dek; - int last_was_session_key; - KBNODE list; /* the current list of packets */ - int have_data; - iobuf_t iobuf; /* used to get the filename etc. */ - int trustletter; /* temp usage in list_node */ - ulong local_id; /* ditto */ - struct kidlist_item *pkenc_list; /* list of encryption packets */ - struct { - int op; - int stop_now; - } pipemode; -}; - - -static int do_proc_packets( CTX c, iobuf_t a ); - -static void list_node( CTX c, KBNODE node ); -static void proc_tree( CTX c, KBNODE node ); - - -static void -release_list( CTX c ) -{ - if( !c->list ) - return; - proc_tree(c, c->list ); - release_kbnode( c->list ); - while( c->pkenc_list ) { - struct kidlist_item *tmp = c->pkenc_list->next; - xfree ( c->pkenc_list ); - c->pkenc_list = tmp; - } - c->pkenc_list = NULL; - c->list = NULL; - c->have_data = 0; - c->last_was_session_key = 0; - c->pipemode.op = 0; - c->pipemode.stop_now = 0; - xfree (c->dek); c->dek = NULL; -} - - -static int -add_onepass_sig( CTX c, PACKET *pkt ) -{ - KBNODE node; - - if( c->list ) { /* add another packet */ - /* We can only append another onepass packet if the list - * does contain only onepass packets */ - for( node=c->list; node && node->pkt->pkttype == PKT_ONEPASS_SIG; - node = node->next ) - ; - if( node ) { - /* this is not the case, so we flush the current thing and - * allow this packet to start a new verification thing */ - release_list( c ); - c->list = new_kbnode( pkt ); - } - else - add_kbnode( c->list, new_kbnode( pkt )); - } - else /* insert the first one */ - c->list = node = new_kbnode( pkt ); - - return 1; -} - - -static int -add_gpg_control( CTX c, PACKET *pkt ) -{ - if ( pkt->pkt.gpg_control->control == CTRLPKT_CLEARSIGN_START ) { - /* New clear text signature. - * Process the last one and reset everything */ - release_list(c); - } - else if ( pkt->pkt.gpg_control->control == CTRLPKT_PIPEMODE ) { - /* Pipemode control packet */ - if ( pkt->pkt.gpg_control->datalen < 2 ) - log_fatal ("invalid pipemode control packet length\n"); - if (pkt->pkt.gpg_control->data[0] == 1) { - /* start the whole thing */ - assert ( !c->list ); /* we should be in a pretty virgin state */ - assert ( !c->pipemode.op ); - c->pipemode.op = pkt->pkt.gpg_control->data[1]; - } - else if (pkt->pkt.gpg_control->data[0] == 2) { - /* the signed material follows in a plaintext packet */ - assert ( c->pipemode.op == 'B' ); - } - else if (pkt->pkt.gpg_control->data[0] == 3) { - assert ( c->pipemode.op == 'B' ); - release_list (c); - /* and tell the outer loop to terminate */ - c->pipemode.stop_now = 1; - } - else - log_fatal ("invalid pipemode control packet code\n"); - return 0; /* no need to store the packet */ - } - - if( c->list ) /* add another packet */ - add_kbnode( c->list, new_kbnode( pkt )); - else /* insert the first one */ - c->list = new_kbnode( pkt ); - - return 1; -} - - - -static int -add_user_id( CTX c, PACKET *pkt ) -{ - if( !c->list ) { - log_error("orphaned user ID\n" ); - return 0; - } - add_kbnode( c->list, new_kbnode( pkt ) ); - return 1; -} - -static int -add_subkey( CTX c, PACKET *pkt ) -{ - if( !c->list ) { - log_error("subkey w/o mainkey\n" ); - return 0; - } - add_kbnode( c->list, new_kbnode( pkt ) ); - return 1; -} - -static int -add_ring_trust( CTX c, PACKET *pkt ) -{ - if( !c->list ) { - log_error("ring trust w/o key\n" ); - return 0; - } - add_kbnode( c->list, new_kbnode( pkt ) ); - return 1; -} - - -static int -add_signature( CTX c, PACKET *pkt ) -{ - KBNODE node; - - if( pkt->pkttype == PKT_SIGNATURE && !c->list ) { - /* This is the first signature for the following datafile. - * GPG does not write such packets; instead it always uses - * onepass-sig packets. The drawback of PGP's method - * of prepending the signature to the data is - * that it is not possible to make a signature from data read - * from stdin. (GPG is able to read PGP stuff anyway.) */ - node = new_kbnode( pkt ); - c->list = node; - return 1; - } - else if( !c->list ) - return 0; /* oops (invalid packet sequence)*/ - else if( !c->list->pkt ) - BUG(); /* so nicht */ - - /* add a new signature node id at the end */ - node = new_kbnode( pkt ); - add_kbnode( c->list, node ); - return 1; -} - -static void -symkey_decrypt_sesskey (DEK * dek, byte *sesskey, size_t slen) -{ - CIPHER_HANDLE hd; - int n; - - if (slen < 17 || slen > 33) - { - log_error ( _("weird size for an encrypted session key (%d)\n"), - (int)slen); - return; - } - /* we checked the DEK values before, so consider all errors as fatal */ - if (gcry_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1)) - BUG(); - if (gcry_cipher_setkey (hd, dek->key, dek->keylen)) - BUG(); - gcry_cipher_setiv (hd, NULL, 0); - gcry_cipher_decrypt (hd, sesskey, slen, NULL, 0); - gcry_cipher_close (hd); - /* check first byte (the cipher algo) */ - if (openpgp_cipher_test_algo (sesskey[0])) - { - log_error (_("invalid symkey algorithm detected (%d)\n"), - sesskey[0]); - return; - } - n = gcry_cipher_get_algo_keylen (sesskey[0]); - if (n > DIM(dek->key)) - BUG (); - /* now we replace the dek components with the real session key - to decrypt the contents of the sequencing packet. */ - dek->keylen = n; - dek->algo = sesskey[0]; - memcpy (dek->key, sesskey + 1, dek->keylen); - /*log_hexdump ("thekey", dek->key, dek->keylen);*/ -} - -static void -proc_symkey_enc( CTX c, PACKET *pkt ) -{ - PKT_symkey_enc *enc; - - enc = pkt->pkt.symkey_enc; - if (!enc) - log_error ("invalid symkey encrypted packet\n"); - else { - int algo = enc->cipher_algo; - const char *s; - - s = gcry_cipher_algo_name (algo); - if (s && *s) - log_info(_("%s encrypted data\n"), s ); - else - log_info(_("encrypted with unknown algorithm %d\n"), algo ); - - c->last_was_session_key = 2; - if ( opt.list_only ) - goto leave; - c->dek = passphrase_to_dek( NULL, 0, algo, &enc->s2k, 0, NULL, NULL ); - if (c->dek) - c->dek->algo_info_printed = 1; - if ( c->dek && enc->seskeylen ) - symkey_decrypt_sesskey( c->dek, enc->seskey, enc->seskeylen ); - } -leave: - free_packet(pkt); -} - -static void -proc_pubkey_enc( CTX c, PACKET *pkt ) -{ - PKT_pubkey_enc *enc; - int result = 0; - - /* check whether the secret key is available and store in this case */ - c->last_was_session_key = 1; - enc = pkt->pkt.pubkey_enc; - /*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/ - /* Hmmm: why do I have this algo check here - anyway there is - * function to check it. */ - if( opt.verbose ) - log_info(_("public key is %08lX\n"), (ulong)enc->keyid[1] ); - - if( is_status_enabled() ) { - char buf[50]; - sprintf(buf, "%08lX%08lX %d 0", - (ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo ); - write_status_text( STATUS_ENC_TO, buf ); - } - - if( !opt.list_only && opt.override_session_key ) { - /* It does not make much sense to store the session key in - * secure memory because it has already been passed on the - * command line and the GCHQ knows about it */ - c->dek = xcalloc (1, sizeof *c->dek ); - result = get_override_session_key ( c->dek, opt.override_session_key ); - if ( result ) { - xfree (c->dek); c->dek = NULL; - } - } - else if( is_ELGAMAL(enc->pubkey_algo) - || enc->pubkey_algo == PUBKEY_ALGO_DSA - || is_RSA(enc->pubkey_algo) ) { - if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1]) - || opt.try_all_secrets - || !seckey_available( enc->keyid )) ) { - if( opt.list_only ) - result = -1; - else { - c->dek = xcalloc_secure (1, sizeof *c->dek); - if( (result = get_session_key( enc, c->dek )) ) { - /* error: delete the DEK */ - xfree (c->dek); c->dek = NULL; - } - } - } - else - result = GPG_ERR_NO_SECKEY; - } - else - result = GPG_ERR_PUBKEY_ALGO; - - if( result == -1 ) - ; - else { - if( !result ) { - if( opt.verbose > 1 ) - log_info( _("public key encrypted data: good DEK\n") ); - if ( opt.show_session_key ) { - int i; - char *buf = xmalloc ( c->dek->keylen*2 + 20 ); - sprintf ( buf, "%d:", c->dek->algo ); - for(i=0; i < c->dek->keylen; i++ ) - sprintf(buf+strlen(buf), "%02X", c->dek->key[i] ); - log_info( "session key: \"%s\"\n", buf ); - write_status_text ( STATUS_SESSION_KEY, buf ); - } - } - /* store it for later display */ - { - struct kidlist_item *x = xmalloc ( sizeof *x ); - x->kid[0] = enc->keyid[0]; - x->kid[1] = enc->keyid[1]; - x->pubkey_algo = enc->pubkey_algo; - x->reason = result; - x->next = c->pkenc_list; - c->pkenc_list = x; - } - } - free_packet(pkt); -} - - - -/**************** - * Print the list of public key encrypted packets which we could - * not decrypt. - */ -static void -print_pkenc_list( struct kidlist_item *list, int failed ) -{ - for( ; list; list = list->next ) { - PKT_public_key *pk; - const char *algstr; - - if ( failed && !list->reason ) - continue; - if ( !failed && list->reason ) - continue; - - algstr = gcry_pk_algo_name (list->pubkey_algo); - pk = xcalloc (1, sizeof *pk ); - - if (!algstr || !*algstr) - algstr = "[?]"; - pk->pubkey_algo = list->pubkey_algo; - if( !get_pubkey( pk, list->kid ) ) { - size_t n; - char *p; - log_info( _("encrypted with %u-bit %s key, ID %08lX, created %s\n"), - nbits_from_pk( pk ), algstr, (ulong)list->kid[1], - strtimestamp(pk->timestamp) ); - fputs(" \"", log_get_stream() ); - p = get_user_id( list->kid, &n ); - print_utf8_string2 ( log_get_stream(), p, n, '"' ); - xfree (p); - fputs("\"\n", log_get_stream() ); - } - else { - log_info(_("encrypted with %s key, ID %08lX\n"), - algstr, (ulong) list->kid[1] ); - } - free_public_key( pk ); - - if( gpg_err_code (list->reason) == GPG_ERR_NO_SECKEY ) { - if( is_status_enabled() ) { - char buf[20]; - sprintf(buf,"%08lX%08lX", (ulong)list->kid[0], - (ulong)list->kid[1] ); - write_status_text( STATUS_NO_SECKEY, buf ); - } - } - else if (list->reason) - log_info(_("public key decryption failed: %s\n"), - gpg_strerror (list->reason)); - } -} - - -static void -proc_encrypted( CTX c, PACKET *pkt ) -{ - int result = 0; - - if (!opt.quiet) { - print_pkenc_list ( c->pkenc_list, 1 ); - print_pkenc_list ( c->pkenc_list, 0 ); - } - - write_status( STATUS_BEGIN_DECRYPTION ); - - /*log_debug("dat: %sencrypted data\n", c->dek?"":"conventional ");*/ - if( opt.list_only ) - result = -1; - else if( !c->dek && !c->last_was_session_key ) { - int algo; - STRING2KEY s2kbuf, *s2k = NULL; - - /* assume this is old style conventional encrypted data */ - if ( (algo = opt.def_cipher_algo)) - log_info (_("assuming %s encrypted data\n"), - gcry_cipher_algo_name (algo)); - else if ( gcry_cipher_test_algo(CIPHER_ALGO_IDEA) ) { - algo = opt.def_cipher_algo; - if (!algo) - algo = opt.s2k_cipher_algo; - idea_cipher_warn(1); - log_info (_("IDEA cipher unavailable, " - "optimistically attempting to use %s instead\n"), - gcry_cipher_algo_name (algo)); - } - else { - algo = CIPHER_ALGO_IDEA; - if (!opt.s2k_digest_algo) { - /* If no digest is given we assume MD5 */ - s2kbuf.mode = 0; - s2kbuf.hash_algo = GCRY_MD_MD5; - s2k = &s2kbuf; - } - log_info (_("assuming %s encrypted data\n"), "IDEA"); - } - - c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 0, NULL, NULL ); - if (c->dek) - c->dek->algo_info_printed = 1; - } - else if( !c->dek ) - result = GPG_ERR_NO_SECKEY; - if( !result ) - result = decrypt_data( c, pkt->pkt.encrypted, c->dek ); - - xfree (c->dek); c->dek = NULL; - if( result == -1 ) - ; - else if( !result || (gpg_err_code (result)==GPG_ERR_BAD_SIGNATURE - && opt.ignore_mdc_error)) { - write_status( STATUS_DECRYPTION_OKAY ); - if( opt.verbose > 1 ) - log_info(_("decryption okay\n")); - if( pkt->pkt.encrypted->mdc_method && !result ) - write_status( STATUS_GOODMDC ); - else if(!opt.no_mdc_warn) - log_info (_("WARNING: message was not integrity protected\n")); - } - else if( gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE ) { - log_error(_("WARNING: encrypted message has been manipulated!\n")); - write_status( STATUS_BADMDC ); - write_status( STATUS_DECRYPTION_FAILED ); - } - else { - write_status( STATUS_DECRYPTION_FAILED ); - log_error(_("decryption failed: %s\n"), gpg_strerror (result)); - /* Hmmm: does this work when we have encrypted using multiple - * ways to specify the session key (symmmetric and PK)*/ - } - free_packet(pkt); - c->last_was_session_key = 0; - write_status( STATUS_END_DECRYPTION ); -} - - - -static void -proc_plaintext( CTX c, PACKET *pkt ) -{ - PKT_plaintext *pt = pkt->pkt.plaintext; - int any, clearsig, only_md5, rc; - KBNODE n; - - if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) ) - log_info(_("NOTE: sender requested \"for-your-eyes-only\"\n")); - else if( opt.verbose ) - log_info(_("original file name='%.*s'\n"), pt->namelen, pt->name); - free_md_filter_context( &c->mfx ); - gcry_md_open (&c->mfx.md, 0, 0); - /* fixme: we may need to push the textfilter if we have sigclass 1 - * and no armoring - Not yet tested - * Hmmm, why don't we need it at all if we have sigclass 1 - * Should we assume that plaintext in mode 't' has always sigclass 1?? - * See: Russ Allbery's mail 1999-02-09 - */ - any = clearsig = only_md5 = 0; - for(n=c->list; n; n = n->next ) { - if( n->pkt->pkttype == PKT_ONEPASS_SIG ) { - if( n->pkt->pkt.onepass_sig->digest_algo ) { - gcry_md_enable ( c->mfx.md, n->pkt->pkt.onepass_sig->digest_algo ); - if( !any && n->pkt->pkt.onepass_sig->digest_algo - == DIGEST_ALGO_MD5 ) - only_md5 = 1; - else - only_md5 = 0; - any = 1; - } - if( n->pkt->pkt.onepass_sig->sig_class != 0x01 ) - only_md5 = 0; - } - else if( n->pkt->pkttype == PKT_GPG_CONTROL - && n->pkt->pkt.gpg_control->control - == CTRLPKT_CLEARSIGN_START ) { - size_t datalen = n->pkt->pkt.gpg_control->datalen; - const byte *data = n->pkt->pkt.gpg_control->data; - - /* check that we have at least the sigclass and one hash */ - if ( datalen < 2 ) - log_fatal("invalid control packet CTRLPKT_CLEARSIGN_START\n"); - /* Note that we don't set the clearsig flag for not-dash-escaped - * documents */ - clearsig = (*data == 0x01); - for( data++, datalen--; datalen; datalen--, data++ ) - gcry_md_enable ( c->mfx.md, *data ); - any = 1; - break; /* no pass signature pakets are expected */ - } - } - - if( !any && !opt.skip_verify ) { - /* no onepass sig packet: enable all standard algos */ - gcry_md_enable ( c->mfx.md, DIGEST_ALGO_RMD160 ); - gcry_md_enable ( c->mfx.md, DIGEST_ALGO_SHA1 ); - gcry_md_enable ( c->mfx.md, DIGEST_ALGO_MD5 ); - } - if( opt.pgp2_workarounds && only_md5 && !opt.skip_verify ) { - /* This is a kludge to work around a bug in pgp2. It does only - * catch those mails which are armored. To catch the non-armored - * pgp mails we could see whether there is the signature packet - * in front of the plaintext. If someone needs this, send me a patch. - */ - gcry_md_open (&c->mfx.md2, DIGEST_ALGO_MD5, 0); - } - if ( DBG_HASHING ) { - gcry_md_start_debug ( c->mfx.md, "verify" ); - if ( c->mfx.md2 ) - gcry_md_start_debug ( c->mfx.md2, "verify2" ); - } - if ( c->pipemode.op == 'B' ) - rc = handle_plaintext( pt, &c->mfx, 1, 0, NULL ); - else { - int failed; - - rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig, &failed); - if( rc && failed && !c->sigs_only) { - /* can't write output but we hash it anyway to - * check the signature */ - rc = handle_plaintext( pt, &c->mfx, 1, clearsig, NULL ); - } - } - if( rc ) - log_error( "handle plaintext failed: %s\n", gpg_strerror (rc)); - free_packet(pkt); - c->last_was_session_key = 0; - - /* We add a marker control packet instead of the plaintext packet. - * This is so that we can later detect invalid packet sequences. - */ - n = new_kbnode (create_gpg_control (CTRLPKT_PLAINTEXT_MARK, NULL, 0)); - if (c->list) - add_kbnode (c->list, n); - else - c->list = n; -} - - -static int -proc_compressed_cb( iobuf_t a, void *info ) -{ - return proc_signature_packets( info, a, ((CTX)info)->signed_data, - ((CTX)info)->sigfilename ); -} - -static int -proc_encrypt_cb( iobuf_t a, void *info ) -{ - return proc_encryption_packets( info, a ); -} - -static void -proc_compressed( CTX c, PACKET *pkt ) -{ - PKT_compressed *zd = pkt->pkt.compressed; - int rc; - - /*printf("zip: compressed data packet\n");*/ - if( c->sigs_only ) - rc = handle_compressed( c, zd, proc_compressed_cb, c ); - else if( c->encrypt_only ) - rc = handle_compressed( c, zd, proc_encrypt_cb, c ); - else - rc = handle_compressed( c, zd, NULL, NULL ); - if( rc ) - log_error("uncompressing failed: %s\n", gpg_strerror (rc)); - free_packet(pkt); - c->last_was_session_key = 0; -} - -/**************** - * check the signature - * Returns: 0 = valid signature or an error code - */ -static int -do_check_sig( CTX c, KBNODE node, int *is_selfsig, - int *is_expkey, int *is_revkey ) -{ - PKT_signature *sig; - MD_HANDLE md = NULL, md2 = NULL; - int algo, rc; - - assert( node->pkt->pkttype == PKT_SIGNATURE ); - if( is_selfsig ) - *is_selfsig = 0; - sig = node->pkt->pkt.signature; - - algo = sig->digest_algo; - if( (rc = gcry_md_test_algo(algo)) ) - return rc; - - if( sig->sig_class == 0x00 ) { - if( c->mfx.md ) - gcry_md_copy (&md,c->mfx.md); - else /* detached signature */ - gcry_md_open (&md, 0, 0 ); /* signature_check() will - enable the md*/ - } - else if( sig->sig_class == 0x01 ) { - /* how do we know that we have to hash the (already hashed) text - * in canonical mode ??? (calculating both modes???) */ - if( c->mfx.md ) { - gcry_md_copy (&md, c->mfx.md); - if (c->mfx.md2) - gcry_md_copy (&md2, c->mfx.md2); - } - else { /* detached signature */ - log_debug("Do we really need this here?"); - gcry_md_open (&md, 0, 0 ); /* signature_check() will - enable the md*/ - gcry_md_open (&md2, 0, 0 ); - } - } - else if( (sig->sig_class&~3) == 0x10 - || sig->sig_class == 0x18 - || sig->sig_class == 0x1f - || sig->sig_class == 0x20 - || sig->sig_class == 0x28 - || sig->sig_class == 0x30 ) { - if( c->list->pkt->pkttype == PKT_PUBLIC_KEY - || c->list->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - return check_key_signature( c->list, node, is_selfsig ); - } - else if( sig->sig_class == 0x20 ) { - log_info(_("standalone revocation - " - "use \"gpg --import\" to apply\n")); - return GPG_ERR_NOT_PROCESSED; - } - else { - log_error("invalid root packet for sigclass %02x\n", - sig->sig_class); - return GPG_ERR_SIG_CLASS; - } - } - else - return GPG_ERR_SIG_CLASS; - rc = signature_check2( sig, md, NULL, is_expkey, is_revkey, NULL ); - if( gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2 ) - rc = signature_check2( sig, md2, NULL, is_expkey, is_revkey, NULL ); - gcry_md_close (md); - gcry_md_close (md2); - - return rc; -} - - -static void -print_userid( PACKET *pkt ) -{ - if( !pkt ) - BUG(); - if( pkt->pkttype != PKT_USER_ID ) { - printf("ERROR: unexpected packet type %d", pkt->pkttype ); - return; - } - if( opt.with_colons ) - { - if(pkt->pkt.user_id->attrib_data) - printf("%u %lu", - pkt->pkt.user_id->numattribs, - pkt->pkt.user_id->attrib_len); - else - print_string( stdout, pkt->pkt.user_id->name, - pkt->pkt.user_id->len, ':'); - } - else - print_utf8_string( stdout, pkt->pkt.user_id->name, - pkt->pkt.user_id->len ); -} - - -/**************** - * List the certificate in a user friendly way - */ - -static void -list_node( CTX c, KBNODE node ) -{ - int any=0; - int mainkey; - - if( !node ) - ; - else if( (mainkey = (node->pkt->pkttype == PKT_PUBLIC_KEY) ) - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - PKT_public_key *pk = node->pkt->pkt.public_key; - - if( opt.with_colons ) { - u32 keyid[2]; - keyid_from_pk( pk, keyid ); - if( mainkey ) { - c->local_id = pk->local_id; - c->trustletter = opt.fast_list_mode? - 0 : get_validity_info( pk, NULL ); - } - printf("%s:", mainkey? "pub":"sub" ); - if( c->trustletter ) - putchar( c->trustletter ); - printf(":%u:%d:%08lX%08lX:%s:%s:", - nbits_from_pk( pk ), - pk->pubkey_algo, - (ulong)keyid[0],(ulong)keyid[1], - colon_datestr_from_pk( pk ), - colon_strtime (pk->expiredate) ); - if( c->local_id ) - printf("%lu", c->local_id ); - putchar(':'); - if( mainkey && !opt.fast_list_mode ) - putchar( get_ownertrust_info (pk) ); - putchar(':'); - if( node->next && node->next->pkt->pkttype == PKT_RING_TRUST) { - putchar('\n'); any=1; - if( opt.fingerprint ) - print_fingerprint( pk, NULL, 0 ); - printf("rtv:1:%u:\n", - node->next->pkt->pkt.ring_trust->trustval ); - } - } - else - printf("%s %4u%c/%08lX %s ", - mainkey? "pub":"sub", - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo ), - (ulong)keyid_from_pk( pk, NULL ), - datestr_from_pk( pk ) ); - - if( mainkey ) { - /* and now list all userids with their signatures */ - for( node = node->next; node; node = node->next ) { - if( node->pkt->pkttype == PKT_SIGNATURE ) { - if( !any ) { - if( node->pkt->pkt.signature->sig_class == 0x20 ) - puts("[revoked]"); - else - putchar('\n'); - any = 1; - } - list_node(c, node ); - } - else if( node->pkt->pkttype == PKT_USER_ID ) { - if( any ) { - if( opt.with_colons ) - printf("%s:::::::::", - node->pkt->pkt.user_id->attrib_data?"uat":"uid"); - else - printf( "uid%*s", 28, "" ); - } - print_userid( node->pkt ); - if( opt.with_colons ) - putchar(':'); - putchar('\n'); - if( opt.fingerprint && !any ) - print_fingerprint( pk, NULL, 0 ); - if( node->next - && node->next->pkt->pkttype == PKT_RING_TRUST ) { - printf("rtv:2:%u:\n", - node->next->pkt->pkt.ring_trust->trustval ); - } - any=1; - } - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - if( !any ) { - putchar('\n'); - any = 1; - } - list_node(c, node ); - } - } - } - else if( pk->expiredate ) { /* of subkey */ - printf(_(" [expires: %s]"), expirestr_from_pk( pk ) ); - } - - if( !any ) - putchar('\n'); - if( !mainkey && opt.fingerprint > 1 ) - print_fingerprint( pk, NULL, 0 ); - } - else if( (mainkey = (node->pkt->pkttype == PKT_SECRET_KEY) ) - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *sk = node->pkt->pkt.secret_key; - - if( opt.with_colons ) { - u32 keyid[2]; - keyid_from_sk( sk, keyid ); - printf("%s::%u:%d:%08lX%08lX:%s:%s:::", - mainkey? "sec":"ssb", - nbits_from_sk( sk ), - sk->pubkey_algo, - (ulong)keyid[0],(ulong)keyid[1], - colon_datestr_from_sk( sk ), - colon_strtime (sk->expiredate) - /* fixme: add LID */ ); - } - else - printf("%s %4u%c/%08lX %s ", - mainkey? "sec":"ssb", - nbits_from_sk( sk ), - pubkey_letter( sk->pubkey_algo ), - (ulong)keyid_from_sk( sk, NULL ), - datestr_from_sk( sk ) ); - if( mainkey ) { - /* and now list all userids with their signatures */ - for( node = node->next; node; node = node->next ) { - if( node->pkt->pkttype == PKT_SIGNATURE ) { - if( !any ) { - if( node->pkt->pkt.signature->sig_class == 0x20 ) - puts("[revoked]"); - else - putchar('\n'); - any = 1; - } - list_node(c, node ); - } - else if( node->pkt->pkttype == PKT_USER_ID ) { - if( any ) { - if( opt.with_colons ) - printf("%s:::::::::", - node->pkt->pkt.user_id->attrib_data?"uat":"uid"); - else - printf( "uid%*s", 28, "" ); - } - print_userid( node->pkt ); - if( opt.with_colons ) - putchar(':'); - putchar('\n'); - if( opt.fingerprint && !any ) - print_fingerprint( NULL, sk, 0 ); - any=1; - } - else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - if( !any ) { - putchar('\n'); - any = 1; - } - list_node(c, node ); - } - } - } - if( !any ) - putchar('\n'); - if( !mainkey && opt.fingerprint > 1 ) - print_fingerprint( NULL, sk, 0 ); - } - else if( node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - int is_selfsig = 0; - int rc2=0; - size_t n; - char *p; - int sigrc = ' '; - - if( !opt.list_sigs ) - return; - - if( sig->sig_class == 0x20 || sig->sig_class == 0x30 ) - fputs("rev", stdout); - else - fputs("sig", stdout); - if( opt.check_sigs ) { - fflush(stdout); - switch( gpg_err_code (rc2=do_check_sig( c, node, - &is_selfsig, - NULL, NULL )) ) { - case 0: sigrc = '!'; break; - case GPG_ERR_BAD_SIGNATURE: sigrc = '-'; break; - case GPG_ERR_NO_PUBKEY: - case GPG_ERR_UNUSABLE_PUBKEY: sigrc = '?'; break; - default: sigrc = '%'; break; - } - } - else { /* check whether this is a self signature */ - u32 keyid[2]; - - if( c->list->pkt->pkttype == PKT_PUBLIC_KEY - || c->list->pkt->pkttype == PKT_SECRET_KEY ) { - if( c->list->pkt->pkttype == PKT_PUBLIC_KEY ) - keyid_from_pk( c->list->pkt->pkt.public_key, keyid ); - else - keyid_from_sk( c->list->pkt->pkt.secret_key, keyid ); - - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) - is_selfsig = 1; - } - } - if( opt.with_colons ) { - putchar(':'); - if( sigrc != ' ' ) - putchar(sigrc); - printf("::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo, - (ulong)sig->keyid[0], (ulong)sig->keyid[1], - colon_datestr_from_sig(sig), - colon_expirestr_from_sig(sig)); - - if(sig->trust_depth || sig->trust_value) - printf("%d %d",sig->trust_depth,sig->trust_value); - printf(":"); - - if(sig->trust_regexp) - print_string(stdout,sig->trust_regexp, - strlen(sig->trust_regexp),':'); - printf(":"); - } - else - printf("%c %08lX %s ", - sigrc, (ulong)sig->keyid[1], datestr_from_sig(sig)); - if( sigrc == '%' ) - printf("[%s] ", gpg_strerror (rc2) ); - else if( sigrc == '?' ) - ; - else if( is_selfsig ) { - if( opt.with_colons ) - putchar(':'); - fputs( sig->sig_class == 0x18? "[keybind]":"[selfsig]", stdout); - if( opt.with_colons ) - putchar(':'); - } - else if( !opt.fast_list_mode ) { - p = get_user_id( sig->keyid, &n ); - print_string( stdout, p, n, opt.with_colons ); - xfree (p); - } - if( opt.with_colons ) - printf(":%02x%c:", sig->sig_class, sig->flags.exportable?'x':'l'); - putchar('\n'); - } - else - log_error("invalid node with packet of type %d\n", node->pkt->pkttype); -} - - - -int -proc_packets( void *anchor, iobuf_t a ) -{ - int rc; - CTX c = xcalloc (1, sizeof *c ); - - c->anchor = anchor; - rc = do_proc_packets( c, a ); - xfree ( c ); - return rc; -} - - - -int -proc_signature_packets( void *anchor, iobuf_t a, - STRLIST signedfiles, const char *sigfilename ) -{ - CTX c = xcalloc (1, sizeof *c ); - int rc; - - c->anchor = anchor; - c->sigs_only = 1; - c->signed_data = signedfiles; - c->sigfilename = sigfilename; - rc = do_proc_packets( c, a ); - xfree ( c ); - return rc; -} - -int -proc_encryption_packets( void *anchor, iobuf_t a ) -{ - CTX c = xcalloc (1, sizeof *c ); - int rc; - - c->anchor = anchor; - c->encrypt_only = 1; - rc = do_proc_packets( c, a ); - xfree ( c ); - return rc; -} - - -int -do_proc_packets( CTX c, iobuf_t a ) -{ - PACKET *pkt = xmalloc ( sizeof *pkt ); - int rc=0; - int any_data=0; - int newpkt; - - c->iobuf = a; - init_packet(pkt); - while( (rc=parse_packet(a, pkt)) != -1 ) { - any_data = 1; - if( rc ) { - free_packet(pkt); - /* stop processing when an invalid packet has been encountered - * but don't do so when we are doing a --list-packet. */ - if( gpg_err_code (rc) == GPG_ERR_INV_PACKET && opt.list_packets != 2 ) - break; - continue; - } - newpkt = -1; - if( opt.list_packets ) { - switch( pkt->pkttype ) { - case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break; - case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break; - case PKT_COMPRESSED: proc_compressed( c, pkt ); break; - default: newpkt = 0; break; - } - } - else if( c->sigs_only ) { - switch( pkt->pkttype ) { - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - case PKT_USER_ID: - case PKT_SYMKEY_ENC: - case PKT_PUBKEY_ENC: - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: - write_status_text( STATUS_UNEXPECTED, "0" ); - rc = GPG_ERR_UNEXPECTED; - goto leave; - case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break; - case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break; - case PKT_COMPRESSED: proc_compressed( c, pkt ); break; - case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break; - case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break; - default: newpkt = 0; break; - } - } - else if( c->encrypt_only ) { - switch( pkt->pkttype ) { - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - case PKT_USER_ID: - write_status_text( STATUS_UNEXPECTED, "0" ); - rc = GPG_ERR_UNEXPECTED; - goto leave; - case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break; - case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break; - case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break; - case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break; - case PKT_COMPRESSED: proc_compressed( c, pkt ); break; - case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break; - case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break; - default: newpkt = 0; break; - } - } - else { - switch( pkt->pkttype ) { - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - release_list( c ); - c->list = new_kbnode( pkt ); - newpkt = 1; - break; - case PKT_PUBLIC_SUBKEY: - case PKT_SECRET_SUBKEY: - newpkt = add_subkey( c, pkt ); - break; - case PKT_USER_ID: newpkt = add_user_id( c, pkt ); break; - case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break; - case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break; - case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break; - case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break; - case PKT_COMPRESSED: proc_compressed( c, pkt ); break; - case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break; - case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break; - case PKT_RING_TRUST: newpkt = add_ring_trust( c, pkt ); break; - default: newpkt = 0; break; - } - } - /* This is a very ugly construct and frankly, I don't remember why - * I used it. Adding the MDC check here is a hack. - * The right solution is to initiate another context for encrypted - * packet and not to reuse the current one ... It works right - * when there is a compression packet inbetween which adds just - * an extra layer. - * Hmmm: Rewrite this whole module here?? - */ - if( pkt->pkttype != PKT_SIGNATURE && pkt->pkttype != PKT_MDC ) - c->have_data = pkt->pkttype == PKT_PLAINTEXT; - - if( newpkt == -1 ) - ; - else if( newpkt ) { - pkt = xmalloc ( sizeof *pkt ); - init_packet(pkt); - } - else - free_packet(pkt); - if ( c->pipemode.stop_now ) { - /* we won't get an EOF in pipemode, so we have to - * break the loop here */ - rc = -1; - break; - } - } - if( gpg_err_code (rc) == GPG_ERR_INV_PACKET ) - write_status_text( STATUS_NODATA, "3" ); - if( any_data ) - rc = 0; - else if( rc == -1 ) - write_status_text( STATUS_NODATA, "2" ); - - - leave: - release_list( c ); - xfree (c->dek); - free_packet( pkt ); - xfree ( pkt ); - free_md_filter_context( &c->mfx ); - return rc; -} - - -static int -check_sig_and_print( CTX c, KBNODE node ) -{ - PKT_signature *sig = node->pkt->pkt.signature; - const char *astr, *tstr; - int rc, is_expkey=0, is_revkey=0; - - if( opt.skip_verify ) { - log_info(_("signature verification suppressed\n")); - return 0; - } - - /* It is not in all cases possible to check multiple signatures: - * PGP 2 (which is also allowed by OpenPGP), does use the packet - * sequence: sig+data, OpenPGP does use onepas+data=sig and GnuPG - * sometimes uses (because I did'nt read the specs right) data+sig. - * Because it is possible to create multiple signatures with - * different packet sequence (e.g. data+sig and sig+data) it might - * not be possible to get it right: let's say we have: - * data+sig, sig+data,sig+data and we have not yet encountered the last - * data, we could also see this a one data with 2 signatures and then - * data+sig. - * To protect against this we check that all signatures follow - * without any intermediate packets. Note, that we won't get this - * error when we use onepass packets or cleartext signatures because - * we reset the list every time - * - * FIXME: Now that we have these marker packets, we should create a - * real grammar and check against this. - */ - { - KBNODE n; - int n_sig=0; - - for (n=c->list; n; n=n->next ) { - if ( n->pkt->pkttype == PKT_SIGNATURE ) - n_sig++; - } - if (n_sig > 1) { /* more than one signature - check sequence */ - int tmp, onepass; - - for (tmp=onepass=0,n=c->list; n; n=n->next ) { - if (n->pkt->pkttype == PKT_ONEPASS_SIG) - onepass++; - else if (n->pkt->pkttype == PKT_GPG_CONTROL - && n->pkt->pkt.gpg_control->control - == CTRLPKT_CLEARSIGN_START ) { - onepass++; /* handle the same way as a onepass */ - } - else if ( (tmp && n->pkt->pkttype != PKT_SIGNATURE) ) { - log_error(_("can't handle these multiple signatures\n")); - return 0; - } - else if ( n->pkt->pkttype == PKT_SIGNATURE ) - tmp = 1; - else if (!tmp && !onepass - && n->pkt->pkttype == PKT_GPG_CONTROL - && n->pkt->pkt.gpg_control->control - == CTRLPKT_PLAINTEXT_MARK ) { - /* plaintext before signatures but no one-pass packets*/ - log_error(_("can't handle these multiple signatures\n")); - return 0; - } - } - } - } - - tstr = asctimestamp(sig->timestamp); - astr = gcry_pk_algo_name (sig->pubkey_algo); - if(opt.verify_options&VERIFY_SHOW_LONG_KEYID) - { - log_info(_("Signature made %.*s\n"),(int)strlen(tstr), tstr); - log_info(_(" using %s key %08lX%08lX\n"), - astr? astr: "?",(ulong)sig->keyid[0],(ulong)sig->keyid[1] ); - } - else - log_info(_("Signature made %.*s using %s key ID %08lX\n"), - (int)strlen(tstr), tstr, astr? astr: "?", - (ulong)sig->keyid[1] ); - - rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey ); - if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY - && opt.keyserver_scheme && opt.keyserver_options.auto_key_retrieve) { - if( keyserver_import_keyid ( sig->keyid )==0 ) - rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey ); - } - - - /* If the key still isn't found, try to inform the user where it - can be found. */ - if(gpg_err_code (rc)==GPG_ERR_NO_PUBKEY && sig->flags.pref_ks) - { - const byte *p; - int seq=0; - size_t n; - - while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&n,&seq,NULL))) - { - /* According to my favorite copy editor, in English - grammar, you say "at" if the key is located on a web - page, but "from" if it is located on a keyserver. I'm - not going to even try to make two strings here :) */ - log_info(_("Key available at: ") ); - print_string( log_get_stream(), p, n, 0 ); - putc( '\n', log_get_stream() ); - } - } - - - if( !rc || gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE ) { - KBNODE un, keyblock; - int count=0, statno; - char keyid_str[50]; - PKT_public_key *pk=NULL; - - if(rc) - statno=STATUS_BADSIG; - else if(sig->flags.expired) - statno=STATUS_EXPSIG; - else if(is_expkey) - statno=STATUS_EXPKEYSIG; - else if(is_revkey) - statno=STATUS_REVKEYSIG; - else - statno=STATUS_GOODSIG; - - keyblock = get_pubkeyblock( sig->keyid ); - - sprintf (keyid_str, "%08lX%08lX [uncertain] ", - (ulong)sig->keyid[0], (ulong)sig->keyid[1]); - - /* find and print the primary user ID */ - for( un=keyblock; un; un = un->next ) { - int valid; - - if(un->pkt->pkttype==PKT_PUBLIC_KEY) - { - pk=un->pkt->pkt.public_key; - continue; - } - if( un->pkt->pkttype != PKT_USER_ID ) - continue; - if ( !un->pkt->pkt.user_id->created ) - continue; - if ( un->pkt->pkt.user_id->is_revoked ) - continue; - if ( un->pkt->pkt.user_id->is_expired ) - continue; - if ( !un->pkt->pkt.user_id->is_primary ) - continue; - /* We want the textual user ID here */ - if ( un->pkt->pkt.user_id->attrib_data ) - continue; - - assert(pk); - - /* Get it before we print anything to avoid interrupting - the output with the "please do a --check-trustdb" - line. */ - valid=get_validity(pk,un->pkt->pkt.user_id); - - keyid_str[17] = 0; /* cut off the "[uncertain]" part */ - write_status_text_and_buffer (statno, keyid_str, - un->pkt->pkt.user_id->name, - un->pkt->pkt.user_id->len, - -1 ); - - log_info(rc? _("BAD signature from \"") - : sig->flags.expired ? _("Expired signature from \"") - : _("Good signature from \"")); - print_utf8_string( log_get_stream(), un->pkt->pkt.user_id->name, - un->pkt->pkt.user_id->len ); - if(opt.verify_options&VERIFY_SHOW_VALIDITY) - fprintf (log_get_stream(), - "\" [%s]\n",trust_value_to_string(valid)); - else - fputs("\"\n", log_get_stream() ); - count++; - } - if( !count ) { /* just in case that we have no valid textual - userid */ - /* Try for an invalid textual userid */ - for( un=keyblock; un; un = un->next ) { - if( un->pkt->pkttype == PKT_USER_ID && - !un->pkt->pkt.user_id->attrib_data ) - break; - } - - /* Try for any userid at all */ - if(!un) { - for( un=keyblock; un; un = un->next ) { - if( un->pkt->pkttype == PKT_USER_ID ) - break; - } - } - - if (opt.trust_model==TM_ALWAYS || !un) - keyid_str[17] = 0; /* cut off the "[uncertain]" part */ - - write_status_text_and_buffer (statno, keyid_str, - un? un->pkt->pkt.user_id->name:"[?]", - un? un->pkt->pkt.user_id->len:3, - -1 ); - - log_info(rc? _("BAD signature from \"") - : sig->flags.expired ? _("Expired signature from \"") - : _("Good signature from \"")); - if (opt.trust_model!=TM_ALWAYS && un) { - fputs(_("[uncertain]"), log_get_stream() ); - putc(' ', log_get_stream() ); - } - print_utf8_string( log_get_stream(), - un? un->pkt->pkt.user_id->name:"[?]", - un? un->pkt->pkt.user_id->len:3 ); - fputs("\"\n", log_get_stream() ); - } - - /* If we have a good signature and already printed - * the primary user ID, print all the other user IDs */ - if ( count && !rc ) { - for( un=keyblock; un; un = un->next ) { - if( un->pkt->pkttype != PKT_USER_ID ) - continue; - if ( un->pkt->pkt.user_id->is_revoked ) - continue; - if ( un->pkt->pkt.user_id->is_expired ) - continue; - /* Only skip textual primaries */ - if ( un->pkt->pkt.user_id->is_primary && - !un->pkt->pkt.user_id->attrib_data ) - continue; - - if(un->pkt->pkt.user_id->attrib_data) - { - dump_attribs(un->pkt->pkt.user_id,pk,NULL); - - if(opt.verify_options&VERIFY_SHOW_PHOTOS) - show_photos(un->pkt->pkt.user_id->attribs, - un->pkt->pkt.user_id->numattribs,pk,NULL); - } - - log_info( _(" aka \"")); - print_utf8_string( log_get_stream(), un->pkt->pkt.user_id->name, - un->pkt->pkt.user_id->len ); - if(opt.verify_options&VERIFY_SHOW_VALIDITY) - fprintf (log_get_stream(), "\" [%s]\n", - trust_value_to_string(get_validity(pk, - un->pkt-> - pkt.user_id))); - else - fputs("\"\n", log_get_stream() ); - } - } - release_kbnode( keyblock ); - - if( !rc ) - { - if(opt.verify_options&VERIFY_SHOW_POLICY) - show_policy_url(sig,0,1); - else - show_policy_url(sig,0,2); - - if(opt.verify_options&VERIFY_SHOW_KEYSERVER) - show_keyserver_url(sig,0,1); - else - show_keyserver_url(sig,0,2); - - if(opt.verify_options&VERIFY_SHOW_NOTATION) - show_notation(sig,0,1); - else - show_notation(sig,0,2); - } - - if( !rc && is_status_enabled() ) { - /* print a status response with the fingerprint */ - PKT_public_key *vpk = xcalloc (1, sizeof *vpk ); - - if( !get_pubkey( vpk, sig->keyid ) ) { - byte array[MAX_FINGERPRINT_LEN], *p; - char buf[MAX_FINGERPRINT_LEN*4+90], *bufp; - size_t i, n; - - bufp = buf; - fingerprint_from_pk( vpk, array, &n ); - p = array; - for(i=0; i < n ; i++, p++, bufp += 2) - sprintf(bufp, "%02X", *p ); - /* TODO: Replace the reserved '0' in the field below - with bits for status flags (policy url, notation, - etc.). Remember to make the buffer larger to - match! */ - sprintf(bufp, " %s %lu %lu %d 0 %d %d %02X ", - strtimestamp( sig->timestamp ), - (ulong)sig->timestamp,(ulong)sig->expiredate, - sig->version,sig->pubkey_algo,sig->digest_algo, - sig->sig_class); - bufp = bufp + strlen (bufp); - if (!vpk->is_primary) { - u32 akid[2]; - - akid[0] = vpk->main_keyid[0]; - akid[1] = vpk->main_keyid[1]; - free_public_key (vpk); - vpk = xcalloc (1, sizeof *vpk ); - if (get_pubkey (vpk, akid)) { - /* impossible error, we simply return a zeroed out fpr */ - n = MAX_FINGERPRINT_LEN < 20? MAX_FINGERPRINT_LEN : 20; - memset (array, 0, n); - } - else - fingerprint_from_pk( vpk, array, &n ); - } - p = array; - for(i=0; i < n ; i++, p++, bufp += 2) - sprintf(bufp, "%02X", *p ); - write_status_text( STATUS_VALIDSIG, buf ); - } - free_public_key( vpk ); - } - - if( !rc ) - rc = check_signatures_trust( sig ); - - if(sig->flags.expired) - { - log_info(_("Signature expired %s\n"), - asctimestamp(sig->expiredate)); - rc=GPG_ERR_GENERAL; /* need a better error here? */ - } - else if(sig->expiredate) - log_info(_("Signature expires %s\n"),asctimestamp(sig->expiredate)); - - if(opt.verbose) - log_info(_("%s signature, digest algorithm %s\n"), - sig->sig_class==0x00?_("binary"): - sig->sig_class==0x01?_("textmode"):_("unknown"), - gcry_md_algo_name (sig->digest_algo)); - - if( rc ) - g10_errors_seen = 1; - if( opt.batch && rc ) - g10_exit(1); - } - else { - char buf[50]; - sprintf(buf, "%08lX%08lX %d %d %02x %lu %d", - (ulong)sig->keyid[0], (ulong)sig->keyid[1], - sig->pubkey_algo, sig->digest_algo, - sig->sig_class, (ulong)sig->timestamp, rc ); - write_status_text( STATUS_ERRSIG, buf ); - if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY ) { - buf[16] = 0; - write_status_text( STATUS_NO_PUBKEY, buf ); - } - if( rc != GPG_ERR_NOT_PROCESSED ) - log_error(_("Can't check signature: %s\n"), gpg_strerror (rc) ); - } - return rc; -} - - -/**************** - * Process the tree which starts at node - */ -static void -proc_tree( CTX c, KBNODE node ) -{ - KBNODE n1; - int rc; - - if( opt.list_packets || opt.list_only ) - return; - - /* we must skip our special plaintext marker packets here becuase - they may be the root packet. These packets are only used in - addionla checks and skipping them here doesn't matter */ - while ( node - && node->pkt->pkttype == PKT_GPG_CONTROL - && node->pkt->pkt.gpg_control->control - == CTRLPKT_PLAINTEXT_MARK ) { - node = node->next; - } - if (!node) - return; - - c->local_id = 0; - c->trustletter = ' '; - if( node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - merge_keys_and_selfsig( node ); - list_node( c, node ); - } - else if( node->pkt->pkttype == PKT_SECRET_KEY ) { - merge_keys_and_selfsig( node ); - list_node( c, node ); - } - else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) { - /* check all signatures */ - if( !c->have_data ) { - free_md_filter_context( &c->mfx ); - /* prepare to create all requested message digests */ - gcry_md_open (&c->mfx.md, 0, 0); - - /* fixme: why looking for the signature packet and not 1passpacket*/ - for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); ) { - gcry_md_enable ( c->mfx.md, n1->pkt->pkt.signature->digest_algo); - } - /* ask for file and hash it */ - if( c->sigs_only ) { - rc = hash_datafiles( c->mfx.md, NULL, - c->signed_data, c->sigfilename, - n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 ); - } - else { - rc = ask_for_detached_datafile( c->mfx.md, c->mfx.md2, - iobuf_get_real_fname(c->iobuf), - n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 ); - } - if( rc ) { - log_error("can't hash datafile: %s\n", gpg_strerror (rc)); - return; - } - } - else if ( c->signed_data ) { - log_error (_("not a detached signature\n") ); - return; - } - - for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); ) - check_sig_and_print( c, n1 ); - } - else if( node->pkt->pkttype == PKT_GPG_CONTROL - && node->pkt->pkt.gpg_control->control - == CTRLPKT_CLEARSIGN_START ) { - /* clear text signed message */ - if( !c->have_data ) { - log_error("cleartext signature without data\n" ); - return; - } - else if ( c->signed_data ) { - log_error (_("not a detached signature\n") ); - return; - } - - for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); ) - check_sig_and_print( c, n1 ); - } - else if( node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - int multiple_ok=1; - - n1=find_next_kbnode(node, PKT_SIGNATURE); - if(n1) - { - byte class=sig->sig_class; - byte hash=sig->digest_algo; - - for(; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE))) - { - /* We can't currently handle multiple signatures of - different classes or digests (we'd pretty much have - to run a different hash context for each), but if - they are all the same, make an exception. */ - if(n1->pkt->pkt.signature->sig_class!=class - || n1->pkt->pkt.signature->digest_algo!=hash) - { - multiple_ok=0; - log_info(_("WARNING: multiple signatures detected. " - "Only the first will be checked.\n")); - break; - } - } - } - - if( sig->sig_class != 0x00 && sig->sig_class != 0x01 ) - log_info(_("standalone signature of class 0x%02x\n"), - sig->sig_class); - else if( !c->have_data ) { - /* detached signature */ - free_md_filter_context( &c->mfx ); - gcry_md_open (&c->mfx.md, sig->digest_algo, 0); - if( !opt.pgp2_workarounds ) - ; - else if( sig->digest_algo == DIGEST_ALGO_MD5 - && is_RSA( sig->pubkey_algo ) ) { - /* enable a workaround for a pgp2 bug */ - gcry_md_open (&c->mfx.md2, DIGEST_ALGO_MD5, 0 ); - } - else if( sig->digest_algo == DIGEST_ALGO_SHA1 - && sig->pubkey_algo == PUBKEY_ALGO_DSA - && sig->sig_class == 0x01 ) { - /* enable the workaround also for pgp5 when the detached - * signature has been created in textmode */ - gcry_md_open (&c->mfx.md2, sig->digest_algo, 0 ); - } -#if 0 /* workaround disabled */ - /* Here we have another hack to work around a pgp 2 bug - * It works by not using the textmode for detached signatures; - * this will let the first signature check (on md) fail - * but the second one (on md2) which adds an extra CR should - * then produce the "correct" hash. This is very, very ugly - * hack but it may help in some cases (and break others) - */ - /* c->mfx.md2? 0 :(sig->sig_class == 0x01) */ -#endif - if ( DBG_HASHING ) { - gcry_md_start_debug ( c->mfx.md, "verify" ); - if ( c->mfx.md2 ) - gcry_md_start_debug ( c->mfx.md2, "verify2" ); - } - if( c->sigs_only ) { - rc = hash_datafiles( c->mfx.md, c->mfx.md2, - c->signed_data, c->sigfilename, - (sig->sig_class == 0x01) ); - } - else { - rc = ask_for_detached_datafile( c->mfx.md, c->mfx.md2, - iobuf_get_real_fname(c->iobuf), - (sig->sig_class == 0x01) ); - } - if( rc ) { - log_error("can't hash datafile: %s\n", gpg_strerror (rc)); - return; - } - } - else if ( c->signed_data ) { - log_error (_("not a detached signature\n") ); - return; - } - else if ( c->pipemode.op == 'B' ) - ; /* this is a detached signature trough the pipemode handler */ - else if (!opt.quiet) - log_info(_("old style (PGP 2.x) signature\n")); - - if(multiple_ok) - for( n1 = node; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )) ) - check_sig_and_print( c, n1 ); - else - check_sig_and_print( c, node ); - } - else { - dump_kbnode (c->list); - log_error(_("invalid root packet detected in proc_tree()\n")); - dump_kbnode (node); - } -} diff --git a/g10/mdfilter.c b/g10/mdfilter.c deleted file mode 100644 index b58189146..000000000 --- a/g10/mdfilter.c +++ /dev/null @@ -1,76 +0,0 @@ -/* mdfilter.c - filter data and calculate a message digest - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "filter.h" - - - -/**************** - * This filter is used to collect a message digest - */ -int -md_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - md_filter_context_t *mfx = opaque; - int i, rc=0; - - if( control == IOBUFCTRL_UNDERFLOW ) { - if( mfx->maxbuf_size && size > mfx->maxbuf_size ) - size = mfx->maxbuf_size; - i = iobuf_read( a, buf, size ); - if( i == -1 ) i = 0; - if( i ) { - gcry_md_write(mfx->md, buf, i ); - if( mfx->md2 ) - gcry_md_write(mfx->md2, buf, i ); - } - else - rc = -1; /* eof */ - *ret_len = i; - } - else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "md_filter"; - return rc; -} - - -void -free_md_filter_context( md_filter_context_t *mfx ) -{ - gcry_md_close (mfx->md); - gcry_md_close (mfx->md2); - mfx->md = NULL; - mfx->md2 = NULL; - mfx->maxbuf_size = 0; -} - diff --git a/g10/misc.c b/g10/misc.c deleted file mode 100644 index 7012a8a25..000000000 --- a/g10/misc.c +++ /dev/null @@ -1,1000 +0,0 @@ -/* misc.c - miscellaneous functions - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <assert.h> -#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 -#include <asm/sysinfo.h> -#include <asm/unistd.h> -#endif -#ifdef HAVE_SETRLIMIT -#include <time.h> -#include <sys/time.h> -#include <sys/resource.h> -#endif - -#include "gpg.h" -#include "util.h" -#include "main.h" -#include "photoid.h" -#include "options.h" -#include "i18n.h" - -#define MAX_EXTERN_MPI_BITS 16384 - - -#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 -static int -setsysinfo(unsigned long op, void *buffer, unsigned long size, - int *start, void *arg, unsigned long flag) -{ - return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag); -} - -void -trap_unaligned(void) -{ - unsigned int buf[2]; - - buf[0] = SSIN_UACPROC; - buf[1] = UAC_SIGBUS | UAC_NOPRINT; - setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0); -} -#else -void -trap_unaligned(void) -{ /* dummy */ -} -#endif - - -int -disable_core_dumps() -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else -#ifdef HAVE_SETRLIMIT - struct rlimit limit; - - limit.rlim_cur = 0; - limit.rlim_max = 0; - if( !setrlimit( RLIMIT_CORE, &limit ) ) - return 0; - if( errno != EINVAL && errno != ENOSYS ) - log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) ); -#endif - return 1; -#endif -} - - - -u16 -checksum_u16( unsigned n ) -{ - u16 a; - - a = (n >> 8) & 0xff; - a += n & 0xff; - return a; -} - - -u16 -checksum( byte *p, unsigned n ) -{ - u16 a; - - for(a=0; n; n-- ) - a += *p++; - return a; -} - -u16 -checksum_mpi( gcry_mpi_t a ) -{ - int rc; - u16 csum; - byte *buffer; - size_t nbytes; - - rc = gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &nbytes, a ); - if (rc) - BUG (); - /* fixme: for numbers not in secure memory we should use a stack - * based buffer and only allocate a larger one if mpi_print return - * an error */ - buffer = gcry_is_secure(a)? gcry_xmalloc_secure(nbytes):gcry_xmalloc(nbytes); - rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, NULL, a ); - if (rc) - BUG (); - csum = checksum (buffer, nbytes ); - xfree (buffer ); - return csum; -} - -u32 -buffer_to_u32( const byte *buffer ) -{ - unsigned long a; - a = *buffer << 24; - a |= buffer[1] << 16; - a |= buffer[2] << 8; - a |= buffer[3]; - return a; -} - - -static void -no_exp_algo(void) -{ - static int did_note = 0; - - if( !did_note ) { - did_note = 1; - log_info(_("Experimental algorithms should not be used!\n")); - } -} - -void -print_pubkey_algo_note( int algo ) -{ - if( algo >= 100 && algo <= 110 ) - no_exp_algo(); -} - -void -print_cipher_algo_note( int algo ) -{ - if( algo >= 100 && algo <= 110 ) - no_exp_algo(); - else if( algo == CIPHER_ALGO_3DES - || algo == CIPHER_ALGO_CAST5 - || algo == CIPHER_ALGO_BLOWFISH - || algo == CIPHER_ALGO_TWOFISH - || algo == CIPHER_ALGO_RIJNDAEL - || algo == CIPHER_ALGO_RIJNDAEL192 - || algo == CIPHER_ALGO_RIJNDAEL256 - ) - ; - else { - static int did_note = 0; - - if( !did_note ) { - did_note = 1; - log_info(_("this cipher algorithm is deprecated; " - "please use a more standard one!\n")); - } - } -} - -void -print_digest_algo_note( int algo ) -{ - if( algo >= 100 && algo <= 110 ) - no_exp_algo(); -} - - -/* Return a string which is used as a kind of process ID */ -const byte * -get_session_marker( size_t *rlen ) -{ - static byte marker[SIZEOF_UNSIGNED_LONG*2]; - static int initialized; - - if ( !initialized ) { - volatile ulong aa, bb; /* we really want the uninitialized value */ - ulong a, b; - - initialized = 1; - /* also this marker is guessable it is not easy to use this - * for a faked control packet because an attacker does not - * have enough control about the time the verification does - * take place. Of course, we can add just more random but - * than we need the random generator even for verification - * tasks - which does not make sense. */ - a = aa ^ (ulong)getpid(); - b = bb ^ (ulong)time(NULL); - memcpy( marker, &a, SIZEOF_UNSIGNED_LONG ); - memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG ); - } - *rlen = sizeof(marker); - return marker; -} - -/**************** - * Wrapper around the libgcrypt function with addional checks on - * openPGP contraints for the algo ID. - */ -int -openpgp_cipher_test_algo( int algo ) -{ - if( algo < 0 || algo > 110 ) - return GPG_ERR_CIPHER_ALGO; - return gcry_cipher_test_algo (algo); -} - -int -openpgp_pk_test_algo( int algo, unsigned int usage_flags ) -{ - size_t value = usage_flags; - - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; -#ifdef __GNUC__ -#warning need to handle the usage here? -#endif - if (algo < 0 || algo > 110) - return GPG_ERR_PUBKEY_ALGO; - return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, &value); -} - -int -openpgp_pk_algo_usage ( int algo ) -{ - int use = 0; - - /* they are hardwired in gpg 1.0 */ - switch ( algo ) { - case PUBKEY_ALGO_RSA: - use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH; - break; - case PUBKEY_ALGO_RSA_E: - use = PUBKEY_USAGE_ENC; - break; - case PUBKEY_ALGO_RSA_S: - use = PUBKEY_USAGE_SIG; - break; - case PUBKEY_ALGO_ELGAMAL_E: - use = PUBKEY_USAGE_ENC; - break; - case PUBKEY_ALGO_DSA: - use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH; - break; - case PUBKEY_ALGO_ELGAMAL: - use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH; - break; - default: - break; - } - return use; -} - -int -openpgp_md_test_algo( int algo ) -{ - if( algo < 0 || algo > 110 ) - return GPG_ERR_DIGEST_ALGO; - return gcry_md_test_algo (algo); -} - -int -openpgp_md_map_name (const char *string) -{ - int i = gcry_md_map_name (string); - - if (!i && (string[0]=='H' || string[0]=='h')) - { /* Didn't find it, so try the Hx format */ - long val; - char *endptr; - - string++; - - val=strtol(string,&endptr,10); - if (*string!='\0' && *endptr=='\0' && !openpgp_md_test_algo(val)) - i = val; - } - return i < 0 || i > 110? 0 : i; -} - -int -openpgp_cipher_map_name (const char *string) -{ - int i = gcry_cipher_map_name (string); - - if (!i && (string[0]=='S' || string[0]=='s')) - { /* Didn't find it, so try the Sx format */ - long val; - char *endptr; - - string++; - - val=strtol(string,&endptr,10); - if (*string!='\0' && *endptr=='\0' && !openpgp_cipher_test_algo(val)) - i = val; - } - return i < 0 || i > 110? 0 : i; -} - -int -openpgp_pk_map_name (const char *string) -{ - int i = gcry_pk_map_name (string); - return i < 0 || i > 110? 0 : i; -} - -#ifdef USE_IDEA -/* Special warning for the IDEA cipher */ -void -idea_cipher_warn(int show) -{ - static int warned=0; - - if(!warned || show) - { - log_info(_("the IDEA cipher plugin is not present\n")); - log_info(_("please see http://www.gnupg.org/why-not-idea.html " - "for more information\n")); - warned=1; - } -} -#endif - -/* Expand %-strings. Returns a string which must be m_freed. Returns - NULL if the string cannot be expanded (too large). */ -char * -pct_expando(const char *string,struct expando_args *args) -{ - const char *ch=string; - int idx=0,maxlen=0,done=0; - u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0}; - char *ret=NULL; - - if(args->pk) - keyid_from_pk(args->pk,pk_keyid); - - if(args->sk) - keyid_from_sk(args->sk,sk_keyid); - - /* This is used so that %k works in photoid command strings in - --list-secret-keys (which of course has a sk, but no pk). */ - if(!args->pk && args->sk) - keyid_from_sk(args->sk,pk_keyid); - - while(*ch!='\0') - { - char *str=NULL; - - if(!done) - { - /* 8192 is way bigger than we'll need here */ - if(maxlen>=8192) - goto fail; - - maxlen+=1024; - ret= xrealloc(ret,maxlen); - } - - done=0; - - if(*ch=='%') - { - switch(*(ch+1)) - { - case 's': /* short key id */ - if(idx+8<maxlen) - { - sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]); - idx+=8; - done=1; - } - break; - - case 'S': /* long key id */ - if(idx+16<maxlen) - { - sprintf(&ret[idx],"%08lX%08lX", - (ulong)sk_keyid[0],(ulong)sk_keyid[1]); - idx+=16; - done=1; - } - break; - - case 'k': /* short key id */ - if(idx+8<maxlen) - { - sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]); - idx+=8; - done=1; - } - break; - - case 'K': /* long key id */ - if(idx+16<maxlen) - { - sprintf(&ret[idx],"%08lX%08lX", - (ulong)pk_keyid[0],(ulong)pk_keyid[1]); - idx+=16; - done=1; - } - break; - - case 'p': /* primary pk fingerprint of a sk */ - case 'f': /* pk fingerprint */ - case 'g': /* sk fingerprint */ - { - byte array[MAX_FINGERPRINT_LEN]; - size_t len; - int i; - - if( ch[1]=='p' && args->sk) - { - if(args->sk->is_primary) - fingerprint_from_sk(args->sk,array,&len); - else if(args->sk->main_keyid[0] || args->sk->main_keyid[1]) - { - PKT_public_key *pk= xcalloc(1, sizeof(PKT_public_key)); - - if(get_pubkey_fast(pk,args->sk->main_keyid)==0) - fingerprint_from_pk(pk,array,&len); - else - memset(array,0,(len=MAX_FINGERPRINT_LEN)); - free_public_key(pk); - } - else - memset(array,0,(len=MAX_FINGERPRINT_LEN)); - } - else if( ch[1]=='f' && args->pk) - fingerprint_from_pk(args->pk,array,&len); - else if( ch[1]=='g' && args->sk) - fingerprint_from_sk(args->sk,array,&len); - else - memset(array, 0, (len=MAX_FINGERPRINT_LEN)); - - if(idx+(len*2)<maxlen) - { - for(i=0;i<len;i++) - { - sprintf(&ret[idx],"%02X",array[i]); - idx+=2; - } - done=1; - } - } - break; - - case 't': /* e.g. "jpg" */ - str=image_type_to_string(args->imagetype,0); - /* fall through */ - - case 'T': /* e.g. "image/jpeg" */ - if(str==NULL) - str=image_type_to_string(args->imagetype,2); - - if(idx+strlen(str)<maxlen) - { - strcpy(&ret[idx],str); - idx+=strlen(str); - done=1; - } - break; - - case '%': - if(idx+1<maxlen) - { - ret[idx++]='%'; - ret[idx]='\0'; - done=1; - } - break; - - /* Any unknown %-keys (like %i, %o, %I, and %O) are - passed through for later expansion. Note this also - handles the case where the last character in the - string is a '%' - the terminating \0 will end up here - and properly terminate the string. */ - default: - if(idx+2<maxlen) - { - ret[idx++]='%'; - ret[idx++]=*(ch+1); - ret[idx]='\0'; - done=1; - } - break; - } - - if(done) - ch++; - } - else - { - if(idx+1<maxlen) - { - ret[idx++]=*ch; - ret[idx]='\0'; - done=1; - } - } - - if(done) - ch++; - } - - return ret; - - fail: - xfree (ret); - return NULL; -} - -int -hextobyte( const char *s ) -{ - int c; - - if( *s >= '0' && *s <= '9' ) - c = 16 * (*s - '0'); - else if( *s >= 'A' && *s <= 'F' ) - c = 16 * (10 + *s - 'A'); - else if( *s >= 'a' && *s <= 'f' ) - c = 16 * (10 + *s - 'a'); - else - return -1; - s++; - if( *s >= '0' && *s <= '9' ) - c += *s - '0'; - else if( *s >= 'A' && *s <= 'F' ) - c += 10 + *s - 'A'; - else if( *s >= 'a' && *s <= 'f' ) - c += 10 + *s - 'a'; - else - return -1; - return c; -} - -void -deprecated_warning(const char *configname,unsigned int configlineno, - const char *option,const char *repl1,const char *repl2) -{ - if(configname) - { - if(strncmp("--",option,2)==0) - option+=2; - - if(strncmp("--",repl1,2)==0) - repl1+=2; - - log_info(_("%s:%d: deprecated option \"%s\"\n"), - configname,configlineno,option); - } - else - log_info(_("WARNING: \"%s\" is a deprecated option\n"),option); - - log_info(_("please use \"%s%s\" instead\n"),repl1,repl2); -} - -const char * -compress_algo_to_string(int algo) -{ - const char *s="?"; - - switch(algo) - { - case 0: - s="Uncompressed"; - break; - - case 1: - s="ZIP"; - break; - - case 2: - s="ZLIB"; - break; - } - - return s; -} - -int -string_to_compress_algo(const char *string) -{ - if(ascii_strcasecmp(string,"uncompressed")==0) - return 0; - else if(ascii_strcasecmp(string,"zip")==0) - return 1; - else if(ascii_strcasecmp(string,"zlib")==0) - return 2; - else if(ascii_strcasecmp(string,"z0")==0) - return 0; - else if(ascii_strcasecmp(string,"z1")==0) - return 1; - else if(ascii_strcasecmp(string,"z2")==0) - return 2; - else - return -1; -} - -int -check_compress_algo(int algo) -{ - if(algo>=0 && algo<=2) - return 0; - - return GPG_ERR_COMPR_ALGO; -} - -int -default_cipher_algo(void) -{ - if(opt.def_cipher_algo) - return opt.def_cipher_algo; - else if(opt.personal_cipher_prefs) - return opt.personal_cipher_prefs[0].value; - else - return opt.s2k_cipher_algo; -} - -/* There is no default_digest_algo function, but see - sign.c:hash_for */ - -int -default_compress_algo(void) -{ - if(opt.def_compress_algo!=-1) - return opt.def_compress_algo; - else if(opt.personal_compress_prefs) - return opt.personal_compress_prefs[0].value; - else - return DEFAULT_COMPRESS_ALGO; -} - -const char * -compliance_option_string(void) -{ - switch(opt.compliance) - { - case CO_RFC2440: - return "--openpgp"; - case CO_PGP2: - return "--pgp2"; - case CO_PGP6: - return "--pgp6"; - case CO_PGP7: - return "--pgp7"; - case CO_PGP8: - return "--pgp8"; - default: - return "???"; - } -} - -static const char * -compliance_string(void) -{ - switch(opt.compliance) - { - case CO_RFC2440: - return "OpenPGP"; - case CO_PGP2: - return "PGP 2.x"; - case CO_PGP6: - return "PGP 6.x"; - case CO_PGP7: - return "PGP 7.x"; - case CO_PGP8: - return "PGP 8.x"; - default: - return "???"; - } -} - -void -compliance_failure(void) -{ - log_info(_("this message may not be usable by %s\n"),compliance_string()); - opt.compliance=CO_GNUPG; -} - -int -parse_options(char *str,unsigned int *options,struct parse_options *opts) -{ - char *tok; - - while((tok=strsep(&str," ,"))) - { - int i,rev=0; - - if(tok[0]=='\0') - continue; - - if(ascii_strncasecmp("no-",tok,3)==0) - { - rev=1; - tok+=3; - } - - for(i=0;opts[i].name;i++) - { - if(ascii_strcasecmp(opts[i].name,tok)==0) - { - if(rev) - *options&=~opts[i].bit; - else - *options|=opts[i].bit; - break; - } - } - - if(!opts[i].name) - return 0; - } - - return 1; -} - - - -/* Temporary helper. */ -int -pubkey_get_npkey( int algo ) -{ - size_t n; - - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &n)) - n = 0; - return n; -} - -/* Temporary helper. */ -int -pubkey_get_nskey( int algo ) -{ - size_t n; - - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &n )) - n = 0; - return n; -} - -/* Temporary helper. */ -int -pubkey_get_nsig( int algo ) -{ - size_t n; - - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSIGN, NULL, &n)) - n = 0; - return n; -} - -/* Temporary helper. */ -int -pubkey_get_nenc( int algo ) -{ - size_t n; - - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NENCR, NULL, &n )) - n = 0; - return n; -} - - -/* Temporary helper. */ -unsigned int -pubkey_nbits( int algo, gcry_mpi_t *key ) -{ - int rc, nbits; - gcry_sexp_t sexp; - - if( algo == GCRY_PK_DSA ) { - rc = gcry_sexp_build ( &sexp, NULL, - "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", - key[0], key[1], key[2], key[3] ); - } - else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) { - rc = gcry_sexp_build ( &sexp, NULL, - "(public-key(elg(p%m)(g%m)(y%m)))", - key[0], key[1], key[2] ); - } - else if( algo == GCRY_PK_RSA ) { - rc = gcry_sexp_build ( &sexp, NULL, - "(public-key(rsa(n%m)(e%m)))", - key[0], key[1] ); - } - else - return 0; - - if ( rc ) - BUG (); - - nbits = gcry_pk_get_nbits( sexp ); - gcry_sexp_release( sexp ); - return nbits; -} - - -/* MPI helper functions. */ - - -/**************** - * write an mpi to out. - */ -int -mpi_write( iobuf_t out, gcry_mpi_t a ) -{ - char buffer[(MAX_EXTERN_MPI_BITS+7)/8]; - size_t nbytes; - int rc; - - nbytes = (MAX_EXTERN_MPI_BITS+7)/8; - rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a ); - if( !rc ) - rc = iobuf_write( out, buffer, nbytes ); - - return rc; -} - -/**************** - * Writyeg a MPI to out, but in this case it is an opaque one, - * s used vor v3 protected keys. - */ -int -mpi_write_opaque( iobuf_t out, gcry_mpi_t a ) -{ - size_t nbytes, nbits; - int rc; - char *p; - - assert( gcry_mpi_get_flag( a, GCRYMPI_FLAG_OPAQUE ) ); - p = gcry_mpi_get_opaque( a, &nbits ); - nbytes = (nbits+7) / 8; - iobuf_put( out, nbits >> 8 ); - iobuf_put( out, nbits ); - rc = iobuf_write( out, p, nbytes ); - return rc; -} - - -/**************** - * Read an external representation of an mpi and return the MPI - * The external format is a 16 bit unsigned value stored in network byte order, - * giving the number of bits for the following integer. The integer is stored - * with MSB first (left padded with zeroes to align on a byte boundary). - */ -gcry_mpi_t -mpi_read(iobuf_t inp, unsigned int *ret_nread, int secure) -{ - int c, c1, c2, i; - unsigned int nbits, nbytes, nread=0; - gcry_mpi_t a = NULL; - byte *buf = NULL; - byte *p; - - if( (c = c1 = iobuf_get(inp)) == -1 ) - goto leave; - nbits = c << 8; - if( (c = c2 = iobuf_get(inp)) == -1 ) - goto leave; - nbits |= c; - if( nbits > MAX_EXTERN_MPI_BITS ) { - log_error("mpi too large (%u bits)\n", nbits); - goto leave; - } - nread = 2; - nbytes = (nbits+7) / 8; - buf = secure? gcry_xmalloc_secure( nbytes+2 ) : gcry_xmalloc( nbytes+2 ); - p = buf; - p[0] = c1; - p[1] = c2; - for( i=0 ; i < nbytes; i++ ) { - p[i+2] = iobuf_get(inp) & 0xff; - nread++; - } - nread += nbytes; - if( gcry_mpi_scan( &a, GCRYMPI_FMT_PGP, buf, nread, &nread ) ) - a = NULL; - - leave: - gcry_free(buf); - if( nread > *ret_nread ) - log_bug("mpi larger than packet"); - else - *ret_nread = nread; - return a; -} - -/**************** - * Same as mpi_read but the value is stored as an opaque MPI. - * This function is used to read encrypted MPI of v3 packets. - */ -gcry_mpi_t -mpi_read_opaque(iobuf_t inp, unsigned *ret_nread ) -{ - int c, c1, c2, i; - unsigned nbits, nbytes, nread=0; - gcry_mpi_t a = NULL; - byte *buf = NULL; - byte *p; - - if( (c = c1 = iobuf_get(inp)) == -1 ) - goto leave; - nbits = c << 8; - if( (c = c2 = iobuf_get(inp)) == -1 ) - goto leave; - nbits |= c; - if( nbits > MAX_EXTERN_MPI_BITS ) { - log_error("mpi too large (%u bits)\n", nbits); - goto leave; - } - nread = 2; - nbytes = (nbits+7) / 8; - buf = gcry_xmalloc( nbytes ); - p = buf; - for( i=0 ; i < nbytes; i++ ) { - p[i] = iobuf_get(inp) & 0xff; - } - nread += nbytes; - a = gcry_mpi_set_opaque(NULL, buf, nbits ); - buf = NULL; - - leave: - gcry_free(buf); - if( nread > *ret_nread ) - log_bug("mpi larger than packet"); - else - *ret_nread = nread; - return a; -} - - -int -mpi_print( FILE *fp, gcry_mpi_t a, int mode ) -{ - int n=0; - - if( !a ) - return fprintf(fp, "[MPI_NULL]"); - if( !mode ) { - unsigned int n1; - n1 = gcry_mpi_get_nbits(a); - n += fprintf(fp, "[%u bits]", n1); - } - else { - int rc; - unsigned char *buffer; - - rc = gcry_mpi_aprint( GCRYMPI_FMT_HEX, &buffer, NULL, a ); - assert( !rc ); - fputs( buffer, fp ); - n += strlen(buffer); - gcry_free( buffer ); - } - return n; -} - - diff --git a/g10/mkdtemp.c b/g10/mkdtemp.c deleted file mode 100644 index 55e5b189f..000000000 --- a/g10/mkdtemp.c +++ /dev/null @@ -1,98 +0,0 @@ -/* mkdtemp.c - libc replacement function - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* This is a replacement function for mkdtemp in case the platform - we're building on (like mine!) doesn't have it. */ - -#include <config.h> -#include <string.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include "types.h" -#include "cipher.h" - -#ifdef MKDIR_TAKES_ONE_ARG -# undef mkdir -# define mkdir(a,b) mkdir(a) -#endif - -char *mkdtemp(char *template) -{ - unsigned int attempts,idx,count=0; - byte *ch; - - idx=strlen(template); - - /* Walk backwards to count all the Xes */ - while(idx>0 && template[idx-1]=='X') - { - count++; - idx--; - } - - if(count==0) - { - errno=EINVAL; - return NULL; - } - - ch=&template[idx]; - - /* Try 4 times to make the temp directory */ - for(attempts=0;attempts<4;attempts++) - { - unsigned int remaining=count; - char *marker=ch; - byte *randombits; - - idx=0; - - /* Using really random bits is probably overkill here. The - worst thing that can happen with a directory name collision - is that the function will return an error. */ - - randombits=get_random_bits(4*remaining,0,0); - - while(remaining>1) - { - sprintf(marker,"%02X",randombits[idx++]); - marker+=2; - remaining-=2; - } - - /* Any leftover Xes? get_random_bits rounds up to full bytes, - so this is safe. */ - if(remaining>0) - sprintf(marker,"%X",randombits[idx]&0xF); - - xfree (randombits); - - if(mkdir(template,0700)==0) - break; - } - - if(attempts==4) - return NULL; /* keeps the errno from mkdir, whatever it is */ - - return template; -} diff --git a/g10/openfile.c b/g10/openfile.c deleted file mode 100644 index 7dbbf7d6a..000000000 --- a/g10/openfile.c +++ /dev/null @@ -1,391 +0,0 @@ -/* openfile.c - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "ttyio.h" -#include "options.h" -#include "main.h" -#include "status.h" -#include "i18n.h" - -#ifdef USE_ONLY_8DOT3 -#define SKELEXT ".skl" -#else -#define SKELEXT EXTSEP_S "skel" -#endif - -#if defined (HAVE_DRIVE_LETTERS) || defined (__riscos__) -#define CMP_FILENAME(a,b) ascii_strcasecmp( (a), (b) ) -#else -#define CMP_FILENAME(a,b) strcmp( (a), (b) ) -#endif - -#ifdef MKDIR_TAKES_ONE_ARG -#undef mkdir -#define mkdir(a,b) mkdir(a) -#endif - -/* FIXME: Implement opt.interactive. */ - -/**************** - * Check whether FNAME exists and ask if it's okay to overwrite an - * existing one. - * Returns: True: it's okay to overwrite or the file does not exist - * False: Do not overwrite - */ -int -overwrite_filep( const char *fname ) -{ - if( !fname || (*fname == '-' && !fname[1]) ) - return 1; /* writing to stdout is always okay */ - - if( access( fname, F_OK ) ) - return 1; /* does not exist */ - -#ifndef HAVE_DOSISH_SYSTEM - if ( !strcmp ( fname, "/dev/null" ) ) - return 1; /* does not do any harm */ -#endif - - /* fixme: add some backup stuff in case of overwrite */ - if( opt.answer_yes ) - return 1; - if( opt.answer_no || opt.batch ) - return 0; /* do not overwrite */ - - tty_printf(_("File `%s' exists. "), fname); - if( cpr_get_answer_is_yes("openfile.overwrite.okay", - _("Overwrite (y/N)? ")) ) - return 1; - return 0; -} - - -/**************** - * Strip know extensions from iname and return a newly allocated - * filename. Return NULL if we can't do that. - */ -char * -make_outfile_name( const char *iname ) -{ - size_t n; - - if( (!iname || (*iname=='-' && !iname[1]) )) - return xstrdup ("-"); - - n = strlen(iname); - if( n > 4 && ( !CMP_FILENAME(iname+n-4, EXTSEP_S "gpg") - || !CMP_FILENAME(iname+n-4, EXTSEP_S "pgp") - || !CMP_FILENAME(iname+n-4, EXTSEP_S "sig") - || !CMP_FILENAME(iname+n-4, EXTSEP_S "asc") ) ) { - char *buf = xstrdup ( iname ); - buf[n-4] = 0; - return buf; - } - else if( n > 5 && !CMP_FILENAME(iname+n-5, EXTSEP_S "sign") ) { - char *buf = xstrdup ( iname ); - buf[n-5] = 0; - return buf; - } - - log_info(_("%s: unknown suffix\n"), iname ); - return NULL; -} - - -/**************** - * Ask for a outputfilename and use the given one as default. - * Return NULL if no file has been given or it is not possible to - * ask the user. - */ -char * -ask_outfile_name( const char *name, size_t namelen ) -{ - size_t n; - const char *s; - char *prompt; - char *fname; - char *defname; - - if( opt.batch ) - return NULL; - - s = _("Enter new filename"); - - n = strlen(s) + namelen + 10; - defname = name && namelen? make_printable_string( name, namelen, 0): NULL; - prompt = xmalloc (n); - if( defname ) - sprintf(prompt, "%s [%s]: ", s, defname ); - else - sprintf(prompt, "%s: ", s ); - fname = cpr_get("openfile.askoutname", prompt ); - cpr_kill_prompt(); - xfree (prompt); - if( !*fname ) { - xfree ( fname ); fname = NULL; - fname = defname; defname = NULL; - } - xfree (defname); - if (fname) - trim_spaces (fname); - return fname; -} - - -/**************** - * Make an output filename for the inputfile INAME. - * Returns an iobuf_t and an errorcode - * Mode 0 = use ".gpg" - * 1 = use ".asc" - * 2 = use ".sig" - */ -int -open_outfile( const char *iname, int mode, iobuf_t *a ) -{ - int rc = 0; - - *a = NULL; - if( (!iname || (*iname=='-' && !iname[1])) && !opt.outfile ) { - if( !(*a = iobuf_create(NULL)) ) { - rc = gpg_error_from_errno (errno); - log_error(_("%s: can't open: %s\n"), "[stdout]", strerror(errno) ); - } - else if( opt.verbose ) - log_info(_("writing to stdout\n")); - } - else { - char *buf = NULL; - const char *name; - - if( opt.dry_run ) - name = "/dev/null"; - else if( opt.outfile ) - name = opt.outfile; - else { -#ifdef USE_ONLY_8DOT3 - if (opt.mangle_dos_filenames) - { - /* It is quite common DOS system to have only one dot in a - * a filename So if we have something like this, we simple - * replace the suffix execpt in cases where the suffix is - * larger than 3 characters and not the same as. - * We should really map the filenames to 8.3 but this tends to - * be more complicated and is probaly a duty of the filesystem - */ - char *dot; - const char *newsfx = mode==1 ? ".asc" : - mode==2 ? ".sig" : ".gpg"; - - buf = xmalloc (strlen(iname)+4+1); - strcpy(buf,iname); - dot = strchr(buf, '.' ); - if ( dot && dot > buf && dot[1] && strlen(dot) <= 4 - && CMP_FILENAME(newsfx, dot) ) - { - strcpy(dot, newsfx ); - } - else if ( dot && !dot[1] ) /* don't duplicate a dot */ - strcpy( dot, newsfx+1 ); - else - strcat ( buf, newsfx ); - } - if (!buf) -#endif /* USE_ONLY_8DOT3 */ - { - buf = xmalloc (strlen(iname)+4+1); - strcpy(stpcpy(buf,iname), mode==1 ? EXTSEP_S "asc" : - mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg"); - } - name = buf; - } - - rc = 0; - while( !overwrite_filep (name) ) - { - char *tmp = ask_outfile_name (NULL, 0); - if ( !tmp || !*tmp ) - { - xfree (tmp); - rc = GPG_ERR_EEXIST; - break; - } - xfree (buf); - name = buf = tmp; - } - - if( !rc ) - { - if( !(*a = iobuf_create( name )) ) - { - rc = gpg_error_from_errno (errno); - log_error(_("%s: can't create: %s\n"), name, strerror(errno) ); - } - else if( opt.verbose ) - log_info(_("writing to `%s'\n"), name ); - } - xfree (buf); - } - - return rc; -} - - -/**************** - * Try to open a file without the extension ".sig" or ".asc" - * Return NULL if such a file is not available. - */ -iobuf_t -open_sigfile( const char *iname, progress_filter_context_t *pfx ) -{ - iobuf_t a = NULL; - size_t len; - - if( iname && !(*iname == '-' && !iname[1]) ) { - len = strlen(iname); - if( len > 4 && ( !strcmp(iname + len - 4, EXTSEP_S "sig") - || ( len > 5 && !strcmp(iname + len - 5, EXTSEP_S "sign") ) - || !strcmp(iname + len - 4, EXTSEP_S "asc")) ) { - char *buf; - buf = xstrdup (iname); - buf[len-(buf[len-1]=='n'?5:4)] = 0 ; - a = iobuf_open( buf ); - if( a && opt.verbose ) - log_info(_("assuming signed data in `%s'\n"), buf ); - if (a && pfx) - handle_progress (pfx, a, buf); - xfree (buf); - } - } - return a; -} - -/**************** - * Copy the option file skeleton to the given directory. - */ -static void -copy_options_file( const char *destdir ) -{ - const char *datadir = GNUPG_DATADIR; - char *fname; - FILE *src, *dst; - int linefeeds=0; - int c; - mode_t oldmask; - int esc = 0; - int any_option = 0; - - if( opt.dry_run ) - return; - - fname = xmalloc ( strlen(datadir) + strlen(destdir) + 15 ); - strcpy(stpcpy(fname, datadir), DIRSEP_S "options" SKELEXT ); - src = fopen( fname, "r" ); - if( !src ) { - log_error(_("%s: can't open: %s\n"), fname, strerror(errno) ); - xfree (fname); - return; - } - strcpy(stpcpy(fname, destdir), DIRSEP_S "gpg" EXTSEP_S "conf" ); - oldmask=umask(077); - dst = fopen( fname, "w" ); - umask(oldmask); - if( !dst ) { - log_error(_("%s: can't create: %s\n"), fname, strerror(errno) ); - fclose( src ); - xfree (fname); - return; - } - - while( (c=getc(src)) != EOF ) { - if( linefeeds < 3 ) { - if( c == '\n' ) - linefeeds++; - } - else { - putc( c, dst ); - if (c== '\n') - esc = 1; - else if (esc == 1) { - if (c == ' ' || c == '\t') - ; - else if (c == '#') - esc = 2; - else - any_option = 1; - } - } - } - fclose( dst ); - fclose( src ); - log_info(_("new configuration file `%s' created\n"), fname ); - if (any_option) - log_info (_("WARNING: options in `%s'" - " are not yet active during this run\n"), - fname); - xfree (fname); -} - - -void -try_make_homedir( const char *fname ) -{ - const char *defhome = GNUPG_DEFAULT_HOMEDIR; - - /* Create the directory only if the supplied directory name - * is the same as the default one. This way we avoid to create - * arbitrary directories when a non-default homedirectory is used. - * To cope with HOME, we do compare only the suffix if we see that - * the default homedir does start with a tilde. - */ - if( opt.dry_run || opt.no_homedir_creation ) - return; - - if ( ( *defhome == '~' - && ( strlen(fname) >= strlen (defhome+1) - && !strcmp(fname+strlen(fname)-strlen(defhome+1), - defhome+1 ) )) - || ( *defhome != '~' - && !compare_filenames( fname, defhome ) ) - ) { - if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) ) - log_fatal( _("%s: can't create directory: %s\n"), - fname, strerror(errno) ); - else if( !opt.quiet ) - log_info( _("%s: directory created\n"), fname ); - copy_options_file( fname ); -/* log_info(_("you have to start GnuPG again, " */ -/* "so it can read the new configuration file\n") ); */ -/* g10_exit(1); */ - } -} diff --git a/g10/options.h b/g10/options.h deleted file mode 100644 index a4cbc3834..000000000 --- a/g10/options.h +++ /dev/null @@ -1,255 +0,0 @@ -/* options.h - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_OPTIONS_H -#define G10_OPTIONS_H - -#include <types.h> -#include "main.h" -#include "packet.h" - -#undef ENABLE_COMMENT_PACKETS /* don't create comment packets */ - -#ifndef EXTERN_UNLESS_MAIN_MODULE -/* Norcraft can't cope with common symbols */ -#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE) -#define EXTERN_UNLESS_MAIN_MODULE extern -#else -#define EXTERN_UNLESS_MAIN_MODULE -#endif -#endif - -EXTERN_UNLESS_MAIN_MODULE -struct { - int verbose; - int quiet; - unsigned debug; - int armor; - int compress; - char *outfile; - int dry_run; - int list_only; - int textmode; - int expert; - int ask_sig_expire; - int ask_cert_expire; - int batch; /* run in batch mode */ - int answer_yes; /* answer yes on most questions */ - int answer_no; /* answer no on most questions */ - int check_sigs; /* check key signatures */ - int with_colons; - int with_key_data; - int with_fingerprint; /* opt --with-fingerprint active */ - int fingerprint; /* list fingerprints */ - int list_sigs; /* list signatures */ - int no_armor; - int list_packets; /* list-packets mode: 1=normal, 2=invoked by command*/ - int def_cipher_algo; - int force_v3_sigs; - int force_v4_certs; - int force_mdc; - int disable_mdc; - int def_digest_algo; - int cert_digest_algo; - int def_compress_algo; - const char *def_secret_key; - char *def_recipient; - int def_recipient_self; - int def_cert_check_level; - int sk_comments; - int no_version; - int marginals_needed; - int completes_needed; - int max_cert_depth; - const char *homedir; - const char *agent_program; - char *display; /* 5 options to be passed to the gpg-agent */ - char *ttyname; - char *ttytype; - char *lc_ctype; - char *lc_messages; - - int skip_verify; - int compress_keys; - int compress_sigs; - /* TM_CLASSIC must be zero to accomodate trustdbs generated before - we started storing the trust model inside the trustdb. */ - enum {TM_CLASSIC=0, TM_PGP=1, TM_ALWAYS, TM_AUTO} trust_model; - unsigned int force_ownertrust; - enum - { - CO_GNUPG=0, CO_RFC2440, CO_RFC1991, CO_PGP2, CO_PGP6, CO_PGP7, CO_PGP8 - } compliance; - int pgp2_workarounds; - unsigned int emulate_bugs; /* bug emulation flags EMUBUG_xxxx */ - int shm_coprocess; - const char *set_filename; - STRLIST comments; - int throw_keyid; - const char *photo_viewer; - int s2k_mode; - int s2k_digest_algo; - int s2k_cipher_algo; - int simple_sk_checksum; /* create the deprecated rfc2440 secret - key protection*/ - int not_dash_escaped; - int escape_from; - int lock_once; - char *keyserver_uri; - char *keyserver_scheme; - char *keyserver_host; - char *keyserver_port; - char *keyserver_opaque; - struct - { - int verbose; - int include_revoked; - int include_disabled; - int include_subkeys; - int honor_http_proxy; - int broken_http_proxy; - int use_temp_files; - int keep_temp_files; - int fake_v3_keyids; - int auto_key_retrieve; - int try_dns_srv; - unsigned int import_options; - unsigned int export_options; - STRLIST other; - } keyserver_options; - int exec_disable; - int exec_path_set; - unsigned int import_options; - unsigned int export_options; - unsigned int list_options; - unsigned int verify_options; - char *def_preference_list; - prefitem_t *personal_cipher_prefs; - prefitem_t *personal_digest_prefs; - prefitem_t *personal_compress_prefs; - int no_perm_warn; - int no_mdc_warn; - char *temp_dir; - int no_encrypt_to; - int interactive; - STRLIST sig_notation_data; - STRLIST cert_notation_data; - STRLIST sig_policy_url; - STRLIST cert_policy_url; - STRLIST sig_keyserver_url; - int use_embedded_filename; - int allow_non_selfsigned_uid; - int allow_freeform_uid; - int no_literal; - ulong set_filesize; - int fast_list_mode; - int fixed_list_mode; - int ignore_time_conflict; - int ignore_valid_from; - int ignore_crc_error; - int ignore_mdc_error; - int command_fd; - const char *override_session_key; - int show_session_key; - int use_agent; - const char *gpg_agent_info; - int merge_only; - int try_all_secrets; - int no_expensive_trust_checks; - int no_sig_cache; - int no_sig_create_check; - int no_auto_check_trustdb; - int preserve_permissions; - int no_homedir_creation; - struct groupitem *grouplist; - int strict; - int mangle_dos_filenames; - int enable_progress_filter; -} opt; - - -#define EMUBUG_MDENCODE 4 - -#define DBG_PACKET_VALUE 1 /* debug packet reading/writing */ -#define DBG_MPI_VALUE 2 /* debug mpi details */ -#define DBG_CIPHER_VALUE 4 /* debug cipher handling */ - /* (may reveal sensitive data) */ -#define DBG_FILTER_VALUE 8 /* debug internal filter handling */ -#define DBG_IOBUF_VALUE 16 /* debug iobuf stuff */ -#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */ -#define DBG_CACHE_VALUE 64 /* debug the cacheing */ -#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ -#define DBG_TRUST_VALUE 256 /* debug the trustdb */ -#define DBG_HASHING_VALUE 512 /* debug hashing operations */ -#define DBG_EXTPROG_VALUE 1024 /* debug external program calls */ - - -#define DBG_PACKET (opt.debug & DBG_PACKET_VALUE) -#define DBG_CIPHER (opt.debug & DBG_CIPHER_VALUE) -#define DBG_FILTER (opt.debug & DBG_FILTER_VALUE) -#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE) -#define DBG_TRUST (opt.debug & DBG_TRUST_VALUE) -#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) -#define DBG_EXTPROG (opt.debug & DBG_EXTPROG_VALUE) - -#define GNUPG (opt.compliance==CO_GNUPG) -#define RFC1991 (opt.compliance==CO_RFC1991 || opt.compliance==CO_PGP2) -#define RFC2440 (opt.compliance==CO_RFC2440) -#define PGP2 (opt.compliance==CO_PGP2) -#define PGP6 (opt.compliance==CO_PGP6) -#define PGP7 (opt.compliance==CO_PGP7) -#define PGP8 (opt.compliance==CO_PGP8) - -/* Various option flags */ - -#define IMPORT_ALLOW_LOCAL_SIGS 1 -#define IMPORT_REPAIR_PKS_SUBKEY_BUG 2 -#define IMPORT_FAST_IMPORT 4 -#define IMPORT_SK2PK 8 - -#define EXPORT_INCLUDE_NON_RFC 1 -#define EXPORT_INCLUDE_LOCAL_SIGS 2 -#define EXPORT_INCLUDE_ATTRIBUTES 4 -#define EXPORT_INCLUDE_SENSITIVE_REVKEYS 8 -#define EXPORT_SEXP_FORMAT 16 - - -#define LIST_SHOW_PHOTOS 1 -#define LIST_SHOW_POLICY 2 -#define LIST_SHOW_NOTATION 4 -#define LIST_SHOW_KEYSERVER 8 -#define LIST_SHOW_VALIDITY 16 -#define LIST_SHOW_LONG_KEYID 32 -#define LIST_SHOW_KEYRING 64 -#define LIST_SHOW_SIG_EXPIRE 128 - - -#define VERIFY_SHOW_PHOTOS 1 -#define VERIFY_SHOW_POLICY 2 -#define VERIFY_SHOW_NOTATION 4 -#define VERIFY_SHOW_KEYSERVER 8 -#define VERIFY_SHOW_VALIDITY 16 -#define VERIFY_SHOW_LONG_KEYID 32 - -#endif /*G10_OPTIONS_H*/ - - - - diff --git a/g10/options.skel b/g10/options.skel deleted file mode 100644 index 3d15f811c..000000000 --- a/g10/options.skel +++ /dev/null @@ -1,212 +0,0 @@ -# These first three lines are not copied to the gpg.conf file in -# the users home directory. -# $Id$ -# Options for GnuPG -# Copyright 1998, 1999, 2000, 2001, 2002, 2003 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. -# -# Unless you specify which option file to use (with the command line -# option "--options filename"), GnuPG uses the file ~/.gnupg/gpg.conf -# by default. -# -# An options file can contain any long options which are available in -# GnuPG. If the first non white space character of a line is a '#', -# this line is ignored. Empty lines are also ignored. -# -# See the man page for a list of options. - -# Uncomment the following option to get rid of the copyright notice - -#no-greeting - -# If you have more than 1 secret key in your keyring, you may want to -# uncomment the following option and set your preferred keyid. - -#default-key 621CC013 - -# If you do not pass a recipient to gpg, it will ask for one. Using -# this option you can encrypt to a default key. Key validation will -# not be done in this case. The second form uses the default key as -# default recipient. - -#default-recipient some-user-id -#default-recipient-self - -# By default GnuPG creates version 3 signatures for data files. This -# is not strictly OpenPGP compliant but PGP 6 and most versions of PGP -# 7 require them. To disable this behavior, you may use this option -# or --openpgp. - -#no-force-v3-sigs - -# Because some mailers change lines starting with "From " to ">From " -# it is good to handle such lines in a special way when creating -# cleartext signatures; all other PGP versions do it this way too. -# To enable full OpenPGP compliance you may want to use this option. - -#no-escape-from-lines - -# If you do not use the Latin-1 (ISO-8859-1) charset, you should tell -# GnuPG which is the native character set. Please check the man page -# for supported character sets. This character set is only used for -# metadata and not for the actual message which does not undergo any -# translation. Note that future version of GnuPG will change to UTF-8 -# as default character set. - -#charset utf-8 - -# Group names may be defined like this: -# group mynames = paige 0x12345678 joe patti -# -# Any time "mynames" is a recipient (-r or --recipient), it will be -# expanded to the names "paige", "joe", and "patti", and the key ID -# "0x12345678". Note there is only one level of expansion - you -# cannot make an group that points to another group. Note also that -# if there are spaces in the recipient name, this will appear as two -# recipients. In these cases it is better to use the key ID. - -#group mynames = paige 0x12345678 joe patti - -# Some old Windows platforms require 8.3 filenames. If your system -# can handle long filenames, uncomment this. - -#no-mangle-dos-filenames - -# Lock the file only once for the lifetime of a process. If you do -# not define this, the lock will be obtained and released every time -# it is needed - normally this is not needed. - -#lock-once - -# GnuPG can send and receive keys to and from a keyserver. These -# servers can be HKP, email, or LDAP (if GnuPG is built with LDAP -# support). -# -# Example HKP keyserver: -# hkp://subkeys.pgp.net -# -# Example email keyserver: -# mailto:pgp-public-keys@keys.pgp.net -# -# Example LDAP keyservers: -# ldap://pgp.surfnet.nl:11370 -# ldap://keyserver.pgp.com -# -# Regular URL syntax applies, and you can set an alternate port -# through the usual method: -# hkp://keyserver.example.net:22742 -# -# If you have problems connecting to a HKP server through a buggy http -# proxy, you can use keyserver option broken-http-proxy (see below), -# but first you should make sure that you have read the man page -# regarding proxies (keyserver option honor-http-proxy) -# -# Most users just set the name and type of their preferred keyserver. -# Note that most servers (with the notable exception of -# ldap://keyserver.pgp.com) synchronize changes with each other. Note -# also that a single server name may actually point to multiple -# servers via DNS round-robin. hkp://subkeys.pgp.net is an example of -# such a "server", which spreads the load over a number of physical -# servers. - -keyserver hkp://subkeys.pgp.net -#keyserver mailto:pgp-public-keys@keys.nl.pgp.net -#keyserver ldap://pgp.surfnet.nl:11370 -#keyserver ldap://keyserver.pgp.com - -# Common options for keyserver functions: -# -# include-disabled = when searching, include keys marked as "disabled" -# on the keyserver (not all keyservers support this). -# -# no-include-revoked = when searching, do not include keys marked as -# "revoked" on the keyserver. -# -# verbose = show more information as the keys are fetched. -# Can be used more than once to increase the amount -# of information shown. -# -# use-temp-files = use temporary files instead of a pipe to talk to the -# keyserver. Some platforms (Win32 for one) always -# have this on. -# -# keep-temp-files = do not delete temporary files after using them -# (really only useful for debugging) -# -# honor-http-proxy = if the keyserver uses HTTP, honor the http_proxy -# environment variable -# -# broken-http-proxy = try to work around a buggy HTTP proxy -# -# auto-key-retrieve = automatically fetch keys as needed from the keyserver -# when verifying signatures or when importing keys that -# have been revoked by a revocation key that is not -# present on the keyring. -# -# no-include-attributes = do not include attribute IDs (aka "photo IDs") -# when sending keys to the keyserver. - -#keyserver-options auto-key-retrieve - -# Uncomment this line to display photo user IDs in key listings and -# when a signature from a key with a photo is verified. - -#show-photos - -# Use this program to display photo user IDs -# -# %i is expanded to a temporary file that contains the photo. -# %I is the same as %i, but the file isn't deleted afterwards by GnuPG. -# %k is expanded to the key ID of the key. -# %K is expanded to the long OpenPGP key ID of the key. -# %t is expanded to the extension of the image (e.g. "jpg"). -# %T is expanded to the MIME type of the image (e.g. "image/jpeg"). -# %f is expanded to the fingerprint of the key. -# %% is %, of course. -# -# If %i or %I are not present, then the photo is supplied to the -# viewer on standard input. If your platform supports it, standard -# input is the best way to do this as it avoids the time and effort in -# generating and then cleaning up a secure temp file. -# -# The default program is "xloadimage -fork -quiet -title 'KeyID 0x%k' stdin" -# On Mac OS X and Windows, the default is to use your regular JPEG image -# viewer. -# -# Some other viewers: -# photo-viewer "qiv %i" -# photo-viewer "ee %i" -# photo-viewer "display -title 'KeyID 0x%k'" -# -# This one saves a copy of the photo ID in your home directory: -# photo-viewer "cat > ~/photoid-for-key-%k.%t" -# -# Use your MIME handler to view photos: -# photo-viewer "metamail -q -d -b -c %T -s 'KeyID 0x%k' -f GnuPG" - -# Passphrase agent -# -# We support the old experimental passphrase agent protocol as well as -# the new Assuan based one (currently available in the "newpg" package -# at ftp.gnupg.org/gcrypt/alpha/aegypten/). To make use of the agent, -# you have to run an agent as daemon and use the option -# -# use-agent -# -# which tries to use the agent but will fallback to the regular mode -# if there is a problem connecting to the agent. The normal way to -# locate the agent is by looking at the environment variable -# GPG_AGENT_INFO which should have been set during gpg-agent startup. -# In certain situations the use of this variable is not possible, thus -# the option -# -# --gpg-agent-info=<path>:<pid>:1 -# -# may be used to override it. diff --git a/g10/packet.h b/g10/packet.h deleted file mode 100644 index 2d87c9c7d..000000000 --- a/g10/packet.h +++ /dev/null @@ -1,514 +0,0 @@ -/* packet.h - packet definitions - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_PACKET_H -#define G10_PACKET_H - -#include "gpg.h" -#include <gcrypt.h> - -#include "types.h" -#include "../common/iobuf.h" -#include "../jnlib/strlist.h" -#include "cipher.h" -#include "filter.h" -#include "global.h" - -#define DEBUG_PARSE_PACKET 1 - -typedef enum { - PKT_NONE =0, - PKT_PUBKEY_ENC =1, /* public key encrypted packet */ - PKT_SIGNATURE =2, /* secret key encrypted packet */ - PKT_SYMKEY_ENC =3, /* session key packet (OpenPGP)*/ - PKT_ONEPASS_SIG =4, /* one pass sig packet (OpenPGP)*/ - PKT_SECRET_KEY =5, /* secret key */ - PKT_PUBLIC_KEY =6, /* public key */ - PKT_SECRET_SUBKEY =7, /* secret subkey (OpenPGP) */ - PKT_COMPRESSED =8, /* compressed data packet */ - PKT_ENCRYPTED =9, /* conventional encrypted data */ - PKT_MARKER =10, /* marker packet (OpenPGP) */ - PKT_PLAINTEXT =11, /* plaintext data with filename and mode */ - PKT_RING_TRUST =12, /* keyring trust packet */ - PKT_USER_ID =13, /* user id packet */ - PKT_PUBLIC_SUBKEY =14, /* public subkey (OpenPGP) */ - PKT_OLD_COMMENT =16, /* comment packet from an OpenPGP draft */ - PKT_ATTRIBUTE =17, /* PGP's attribute packet */ - PKT_ENCRYPTED_MDC =18, /* integrity protected encrypted data */ - PKT_MDC =19, /* manipulation detection code packet */ - PKT_COMMENT =61, /* new comment packet (private) */ - PKT_GPG_CONTROL =63 /* internal control packet */ -} pkttype_t; - -typedef struct packet_struct PACKET; - -/* PKT_GPG_CONTROL types */ -typedef enum { - CTRLPKT_CLEARSIGN_START = 1, - CTRLPKT_PIPEMODE = 2, - CTRLPKT_PLAINTEXT_MARK =3 -} ctrlpkttype_t; - -typedef enum { - PREFTYPE_NONE = 0, - PREFTYPE_SYM = 1, - PREFTYPE_HASH = 2, - PREFTYPE_ZIP = 3 -} preftype_t; - -typedef struct { - byte type; - byte value; -} prefitem_t; - -typedef struct { - int mode; - byte hash_algo; - byte salt[8]; - u32 count; -} STRING2KEY; - -typedef struct { - byte version; - byte cipher_algo; /* cipher algorithm used */ - STRING2KEY s2k; - byte seskeylen; /* keylength in byte or 0 for no seskey */ - byte seskey[1]; -} PKT_symkey_enc; - -typedef struct { - u32 keyid[2]; /* 64 bit keyid */ - byte version; - byte pubkey_algo; /* algorithm used for public key scheme */ - byte throw_keyid; - gcry_mpi_t data[PUBKEY_MAX_NENC]; -} PKT_pubkey_enc; - - -typedef struct { - u32 keyid[2]; /* 64 bit keyid */ - byte sig_class; /* sig classification */ - byte digest_algo; /* algorithm used for digest */ - byte pubkey_algo; /* algorithm used for public key scheme */ - byte last; /* a stupid flag */ -} PKT_onepass_sig; - - -typedef struct { - size_t size; /* allocated */ - size_t len; /* used */ - byte data[1]; -} subpktarea_t; - -struct revocation_key { - byte class; - byte algid; - byte fpr[MAX_FINGERPRINT_LEN]; -}; - -typedef struct { - ulong local_id; /* internal use, valid if > 0 */ - struct { - unsigned checked:1; /* signature has been checked */ - unsigned valid:1; /* signature is good (if checked is set) */ - unsigned unknown_critical:1; - unsigned exportable:1; - unsigned revocable:1; - unsigned policy_url:1; /* At least one policy URL is present */ - unsigned notation:1; /* At least one notation is present */ - unsigned pref_ks:1; /* At least one preferred keyserver is present */ - unsigned expired:1; - } flags; - u32 keyid[2]; /* 64 bit keyid */ - u32 timestamp; /* signature made */ - u32 expiredate; /* expires at this date or 0 if not at all */ - byte version; - byte sig_class; /* sig classification, append for MD calculation*/ - byte pubkey_algo; /* algorithm used for public key scheme */ - /* (PUBKEY_ALGO_xxx) */ - byte digest_algo; /* algorithm used for digest (DIGEST_ALGO_xxxx) */ - byte trust_depth; - byte trust_value; - const byte *trust_regexp; - struct revocation_key **revkey; - int numrevkeys; - subpktarea_t *hashed; /* all subpackets with hashed data (v4 only) */ - subpktarea_t *unhashed; /* ditto for unhashed data */ - byte digest_start[2]; /* first 2 bytes of the digest */ - gcry_mpi_t data[PUBKEY_MAX_NSIG]; -} PKT_signature; - -#define ATTRIB_IMAGE 1 - -/* This is the cooked form of attributes */ -struct user_attribute { - byte type; - const byte *data; - u32 len; -}; - -typedef struct { - int ref; /* reference counter */ - int len; /* length of the name */ - struct user_attribute *attribs; - int numattribs; - byte *attrib_data; /* if this is not NULL, the packet is an attribute */ - unsigned long attrib_len; - byte *namehash; - int help_key_usage; - u32 help_key_expire; - int help_full_count; - int help_marginal_count; - int is_primary; /* 2 if set via the primary flag, 1 if calculated */ - int is_revoked; - int is_expired; - u32 expiredate; /* expires at this date or 0 if not at all */ - prefitem_t *prefs; /* list of preferences (may be NULL)*/ - int mdc_feature; - int ks_modify; - u32 created; /* according to the self-signature */ - byte selfsigversion; - char name[1]; -} PKT_user_id; - - -/**************** - * Note about the pkey/skey elements: We assume that the secret keys - * has the same elemts as the public key at the begin of the array, so - * that npkey < nskey and it is possible to compare the secret and - * public keys by comparing the first npkey elements of pkey against skey. - */ -typedef struct { - u32 timestamp; /* key made */ - u32 expiredate; /* expires at this date or 0 if not at all */ - u32 max_expiredate; /* must not expire past this date */ - byte hdrbytes; /* number of header bytes */ - byte version; - byte selfsigversion; /* highest version of all of the self-sigs */ - byte pubkey_algo; /* algorithm used for public key scheme */ - byte pubkey_usage; /* for now only used to pass it to getkey() */ - byte req_usage; /* hack to pass a request to getkey() */ - byte req_algo; /* Ditto */ - u32 has_expired; /* set to the expiration date if expired */ - int is_revoked; /* key has been revoked */ - int is_valid; /* key (especially subkey) is valid */ - int dont_cache; /* do not cache this */ - ulong local_id; /* internal use, valid if > 0 */ - u32 main_keyid[2]; /* keyid of the primary key */ - u32 keyid[2]; /* calculated by keyid_from_pk() */ - byte is_primary; - byte is_disabled; /* 0 for unset, 1 for enabled, 2 for disabled. */ - prefitem_t *prefs; /* list of preferences (may be NULL) */ - int mdc_feature; /* mdc feature set */ - PKT_user_id *user_id; /* if != NULL: found by that uid */ - struct revocation_key *revkey; - int numrevkeys; - u32 trust_timestamp; - byte trust_depth; - byte trust_value; - const byte *trust_regexp; - gcry_mpi_t pkey[PUBKEY_MAX_NPKEY]; -} PKT_public_key; - -/* Evaluates as true if the pk is disabled, and false if it isn't. If - there is no disable value cached, fill one in. */ -#define pk_is_disabled(a) (((a)->is_disabled)?((a)->is_disabled==2):(cache_disabled_value((a)))) - -typedef struct { - u32 timestamp; /* key made */ - u32 expiredate; /* expires at this date or 0 if not at all */ - u32 max_expiredate; /* must not expire past this date */ - byte hdrbytes; /* number of header bytes */ - byte version; - byte pubkey_algo; /* algorithm used for public key scheme */ - byte pubkey_usage; - byte req_usage; - byte req_algo; - u32 has_expired; /* set to the expiration date if expired */ - int is_revoked; /* key has been revoked */ - int is_valid; /* key (especially subkey) is valid */ - u32 main_keyid[2]; /* keyid of the primary key */ - u32 keyid[2]; - byte is_primary; - byte is_protected; /* The secret info is protected and must */ - /* be decrypted before use, the protected */ - /* MPIs are simply (void*) pointers to memory */ - /* and should never be passed to a mpi_xxx() */ - struct { - byte algo; /* cipher used to protect the secret information*/ - byte sha1chk; /* SHA1 is used instead of a 16 bit checksum */ - STRING2KEY s2k; - byte ivlen; /* used length of the iv */ - byte iv[16]; /* initialization vector for CFB mode */ - } protect; - gcry_mpi_t skey[PUBKEY_MAX_NSKEY]; - u16 csum; /* checksum */ -} PKT_secret_key; - - -typedef struct { - int len; /* length of data */ - char data[1]; -} PKT_comment; - -typedef struct { - u32 len; /* reserved */ - byte new_ctb; - byte algorithm; - iobuf_t buf; /* iobuf_t reference */ -} PKT_compressed; - -typedef struct { - u32 len; /* length of encrypted data */ - int extralen; /* this is (blocksize+2) */ - byte new_ctb; /* uses a new CTB */ - byte mdc_method; /* > 0: integrity protected encrypted data packet */ - iobuf_t buf; /* iobuf_t reference */ -} PKT_encrypted; - -typedef struct { - byte hash[20]; -} PKT_mdc; - -typedef struct { - unsigned int trustval; - unsigned int sigcache; -} PKT_ring_trust; - -typedef struct { - u32 len; /* length of encrypted data */ - iobuf_t buf; /* iobuf_t reference */ - byte new_ctb; - byte is_partial; /* partial length encoded */ - int mode; - u32 timestamp; - int namelen; - char name[1]; -} PKT_plaintext; - -typedef struct { - int control; - size_t datalen; - char data[1]; -} PKT_gpg_control; - -/* combine all packets into a union */ -struct packet_struct { - pkttype_t pkttype; - union { - void *generic; - PKT_symkey_enc *symkey_enc; /* PKT_SYMKEY_ENC */ - PKT_pubkey_enc *pubkey_enc; /* PKT_PUBKEY_ENC */ - PKT_onepass_sig *onepass_sig; /* PKT_ONEPASS_SIG */ - PKT_signature *signature; /* PKT_SIGNATURE */ - PKT_public_key *public_key; /* PKT_PUBLIC_[SUB)KEY */ - PKT_secret_key *secret_key; /* PKT_SECRET_[SUB]KEY */ - PKT_comment *comment; /* PKT_COMMENT */ - PKT_user_id *user_id; /* PKT_USER_ID */ - PKT_compressed *compressed; /* PKT_COMPRESSED */ - PKT_encrypted *encrypted; /* PKT_ENCRYPTED[_MDC] */ - PKT_mdc *mdc; /* PKT_MDC */ - PKT_ring_trust *ring_trust; /* PKT_RING_TRUST */ - PKT_plaintext *plaintext; /* PKT_PLAINTEXT */ - PKT_gpg_control *gpg_control; /* PKT_GPG_CONTROL */ - } pkt; -}; - -#define init_packet(a) do { (a)->pkttype = 0; \ - (a)->pkt.generic = NULL; \ - } while(0) - -typedef enum { - SIGSUBPKT_TEST_CRITICAL=-3, - SIGSUBPKT_LIST_UNHASHED=-2, - SIGSUBPKT_LIST_HASHED =-1, - SIGSUBPKT_NONE = 0, - SIGSUBPKT_SIG_CREATED = 2, /* signature creation time */ - SIGSUBPKT_SIG_EXPIRE = 3, /* signature expiration time */ - SIGSUBPKT_EXPORTABLE = 4, /* exportable */ - SIGSUBPKT_TRUST = 5, /* trust signature */ - SIGSUBPKT_REGEXP = 6, /* regular expression */ - SIGSUBPKT_REVOCABLE = 7, /* revocable */ - SIGSUBPKT_KEY_EXPIRE = 9, /* key expiration time */ - SIGSUBPKT_ARR =10, /* additional recipient request */ - SIGSUBPKT_PREF_SYM =11, /* preferred symmetric algorithms */ - SIGSUBPKT_REV_KEY =12, /* revocation key */ - SIGSUBPKT_ISSUER =16, /* issuer key ID */ - SIGSUBPKT_NOTATION =20, /* notation data */ - SIGSUBPKT_PREF_HASH =21, /* preferred hash algorithms */ - SIGSUBPKT_PREF_COMPR =22, /* preferred compression algorithms */ - SIGSUBPKT_KS_FLAGS =23, /* key server preferences */ - SIGSUBPKT_PREF_KS =24, /* preferred key server */ - SIGSUBPKT_PRIMARY_UID =25, /* primary user id */ - SIGSUBPKT_POLICY =26, /* policy URL */ - SIGSUBPKT_KEY_FLAGS =27, /* key flags */ - SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */ - SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */ - SIGSUBPKT_FEATURES =30, /* feature flags */ - - SIGSUBPKT_FLAG_CRITICAL=128 -} sigsubpkttype_t; - - -/*-- mainproc.c --*/ -int proc_packets( void *ctx, iobuf_t a ); -int proc_signature_packets( void *ctx, iobuf_t a, - STRLIST signedfiles, const char *sigfile ); -int proc_encryption_packets( void *ctx, iobuf_t a ); -int list_packets( iobuf_t a ); - -/*-- parse-packet.c --*/ -int set_packet_list_mode( int mode ); - -#if DEBUG_PARSE_PACKET -int dbg_search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid, - const char* file, int lineno ); -int dbg_parse_packet( iobuf_t inp, PACKET *ret_pkt, - const char* file, int lineno ); -int dbg_copy_all_packets( iobuf_t inp, iobuf_t out, - const char* file, int lineno ); -int dbg_copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff, - const char* file, int lineno ); -int dbg_skip_some_packets( iobuf_t inp, unsigned n, - const char* file, int lineno ); -#define search_packet( a,b,c,d ) \ - dbg_search_packet( (a), (b), (c), (d), __FILE__, __LINE__ ) -#define parse_packet( a, b ) \ - dbg_parse_packet( (a), (b), __FILE__, __LINE__ ) -#define copy_all_packets( a,b ) \ - dbg_copy_all_packets((a),(b), __FILE__, __LINE__ ) -#define copy_some_packets( a,b,c ) \ - dbg_copy_some_packets((a),(b),(c), __FILE__, __LINE__ ) -#define skip_some_packets( a,b ) \ - dbg_skip_some_packets((a),(b), __FILE__, __LINE__ ) -#else -int search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid ); -int parse_packet( iobuf_t inp, PACKET *ret_pkt); -int copy_all_packets( iobuf_t inp, iobuf_t out ); -int copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff ); -int skip_some_packets( iobuf_t inp, unsigned n ); -#endif - -const byte *enum_sig_subpkt ( const subpktarea_t *subpkts, - sigsubpkttype_t reqtype, - size_t *ret_n, int *start, int *critical ); -const byte *parse_sig_subpkt ( const subpktarea_t *buffer, - sigsubpkttype_t reqtype, - size_t *ret_n ); -const byte *parse_sig_subpkt2 ( PKT_signature *sig, - sigsubpkttype_t reqtype, - size_t *ret_n ); -int parse_one_sig_subpkt( const byte *buffer, size_t n, int type ); -void parse_revkeys(PKT_signature *sig); -int parse_attribute_subpkts(PKT_user_id *uid); -void make_attribute_uidname(PKT_user_id *uid, size_t max_namelen); -PACKET *create_gpg_control ( ctrlpkttype_t type, - const byte *data, - size_t datalen ); - -/*-- build-packet.c --*/ -int build_packet( iobuf_t inp, PACKET *pkt ); -u32 calc_packet_length( PACKET *pkt ); -void hash_public_key( MD_HANDLE md, PKT_public_key *pk ); -void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, - const byte *buffer, size_t buflen ); -void build_sig_subpkt_from_sig( PKT_signature *sig ); -int delete_sig_subpkt(subpktarea_t *buffer, sigsubpkttype_t type ); -void build_attribute_subpkt(PKT_user_id *uid,byte type, - const void *buf,u32 buflen, - const void *header,u32 headerlen); - -/*-- free-packet.c --*/ -void free_symkey_enc( PKT_symkey_enc *enc ); -void free_pubkey_enc( PKT_pubkey_enc *enc ); -void free_seckey_enc( PKT_signature *enc ); -int digest_algo_from_sig( PKT_signature *sig ); -void release_public_key_parts( PKT_public_key *pk ); -void free_public_key( PKT_public_key *key ); -void release_secret_key_parts( PKT_secret_key *sk ); -void free_secret_key( PKT_secret_key *sk ); -void free_attributes(PKT_user_id *uid); -void free_user_id( PKT_user_id *uid ); -void free_comment( PKT_comment *rem ); -void free_packet( PACKET *pkt ); -prefitem_t *copy_prefs (const prefitem_t *prefs); -PKT_public_key *copy_public_key( PKT_public_key *d, PKT_public_key *s ); -void copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk ); -PKT_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s ); -PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s ); -PKT_user_id *scopy_user_id (PKT_user_id *sd ); -int cmp_public_keys( PKT_public_key *a, PKT_public_key *b ); -int cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b ); -int cmp_signatures( PKT_signature *a, PKT_signature *b ); -int cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk ); -int cmp_user_ids( PKT_user_id *a, PKT_user_id *b ); - - -/*-- sig-check.c --*/ -int signature_check( PKT_signature *sig, MD_HANDLE digest ); -int signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate, - int *r_expired, int *r_revoked, PKT_public_key *ret_pk ); - -/*-- seckey-cert.c --*/ -int is_secret_key_protected( PKT_secret_key *sk ); -int check_secret_key( PKT_secret_key *sk, int retries ); -int protect_secret_key( PKT_secret_key *sk, DEK *dek ); - -/*-- pubkey-enc.c --*/ -int get_session_key( PKT_pubkey_enc *k, DEK *dek ); -int get_override_session_key( DEK *dek, const char *string ); - -/*-- compress.c --*/ -int handle_compressed( void *ctx, PKT_compressed *cd, - int (*callback)(iobuf_t, void *), void *passthru ); - -/*-- encr-data.c --*/ -int decrypt_data( void *ctx, PKT_encrypted *ed, DEK *dek ); - -/*-- plaintext.c --*/ -int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, - int nooutput, int clearsig, int *create_failed ); -int ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2, - const char *inname, int textmode ); - -/*-- comment.c --*/ -int write_comment( iobuf_t out, const char *s ); - -/*-- sign.c --*/ -int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, - PKT_user_id *uid, PKT_public_key *subpk, - PKT_secret_key *sk, int sigclass, int digest_algo, - int sigversion, u32 timestamp, u32 duration, - int (*mksubpkt)(PKT_signature *, void *), - void *opaque ); -int update_keysig_packet( PKT_signature **ret_sig, - PKT_signature *orig_sig, - PKT_public_key *pk, - PKT_user_id *uid, - PKT_public_key *subpk, - PKT_secret_key *sk, - int (*mksubpkt)(PKT_signature *, void *), - void *opaque ); - -/*-- keygen.c --*/ -PKT_user_id *generate_user_id(void); - -#endif /*G10_PACKET_H*/ diff --git a/g10/parse-packet.c b/g10/parse-packet.c deleted file mode 100644 index c922eb5d9..000000000 --- a/g10/parse-packet.c +++ /dev/null @@ -1,2332 +0,0 @@ -/* parse-packet.c - read packets - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "packet.h" -#include "iobuf.h" -#include "mpi.h" -#include "util.h" -#include "cipher.h" -#include "memory.h" -#include "filter.h" -#include "photoid.h" -#include "options.h" -#include "main.h" -#include "i18n.h" - -static int mpi_print_mode = 0; -static int list_mode = 0; - -static int parse( iobuf_t inp, PACKET *pkt, int onlykeypkts, - off_t *retpos, int *skip, iobuf_t out, int do_skip -#ifdef DEBUG_PARSE_PACKET - ,const char *dbg_w, const char *dbg_f, int dbg_l -#endif - ); -static int copy_packet( iobuf_t inp, iobuf_t out, int pkttype, - unsigned long pktlen ); -static void skip_packet( iobuf_t inp, int pkttype, unsigned long pktlen ); -static void skip_rest( iobuf_t inp, unsigned long pktlen ); -static void *read_rest( iobuf_t inp, size_t pktlen ); -static int parse_symkeyenc( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_pubkeyenc( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen, - PKT_signature *sig ); -static int parse_onepass_sig( iobuf_t inp, int pkttype, unsigned long pktlen, - PKT_onepass_sig *ops ); -static int parse_key( iobuf_t inp, int pkttype, unsigned long pktlen, - byte *hdr, int hdrlen, PACKET *packet ); -static int parse_user_id( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_attribute( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_comment( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static void parse_trust( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_plaintext( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet, int new_ctb); -static int parse_compressed( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet, int new_ctb ); -static int parse_encrypted( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet, int new_ctb); -static int parse_mdc( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet, int new_ctb); -static int parse_gpg_control( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); - -static unsigned short -read_16(iobuf_t inp) -{ - unsigned short a; - a = iobuf_get_noeof(inp) << 8; - a |= iobuf_get_noeof(inp); - return a; -} - -static unsigned long -read_32(iobuf_t inp) -{ - unsigned long a; - a = iobuf_get_noeof(inp) << 24; - a |= iobuf_get_noeof(inp) << 16; - a |= iobuf_get_noeof(inp) << 8; - a |= iobuf_get_noeof(inp); - return a; -} - - -int -set_packet_list_mode( int mode ) -{ - int old = list_mode; - list_mode = mode; - /* FIXME(gcrypt) mpi_print_mode = DBG_MPI; */ - return old; -} - -static void -unknown_pubkey_warning( int algo ) -{ - static byte unknown_pubkey_algos[256]; - - algo &= 0xff; - if( !unknown_pubkey_algos[algo] ) { - if( opt.verbose ) - log_info(_("can't handle public key algorithm %d\n"), algo ); - unknown_pubkey_algos[algo] = 1; - } -} - -/**************** - * Parse a Packet and return it in packet - * Returns: 0 := valid packet in pkt - * -1 := no more packets - * >0 := error - * Note: The function may return an error and a partly valid packet; - * caller must free this packet. - */ -#ifdef DEBUG_PARSE_PACKET -int -dbg_parse_packet( iobuf_t inp, PACKET *pkt, const char *dbg_f, int dbg_l ) -{ - int skip, rc; - - do { - rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l ); - } while( skip ); - return rc; -} -#else -int -parse_packet( iobuf_t inp, PACKET *pkt ) -{ - int skip, rc; - - do { - rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0 ); - } while( skip ); - return rc; -} -#endif - -/**************** - * Like parse packet, but only return secret or public (sub)key packets. - */ -#ifdef DEBUG_PARSE_PACKET -int -dbg_search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid, - const char *dbg_f, int dbg_l ) -{ - int skip, rc; - - do { - rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0, "search", dbg_f, dbg_l ); - } while( skip ); - return rc; -} -#else -int -search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid ) -{ - int skip, rc; - - do { - rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0 ); - } while( skip ); - return rc; -} -#endif - -/**************** - * Copy all packets from INP to OUT, thereby removing unused spaces. - */ -#ifdef DEBUG_PARSE_PACKET -int -dbg_copy_all_packets( iobuf_t inp, iobuf_t out, - const char *dbg_f, int dbg_l ) -{ - PACKET pkt; - int skip, rc=0; - do { - init_packet(&pkt); - } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0, "copy", dbg_f, dbg_l ))); - return rc; -} -#else -int -copy_all_packets( iobuf_t inp, iobuf_t out ) -{ - PACKET pkt; - int skip, rc=0; - do { - init_packet(&pkt); - } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 ))); - return rc; -} -#endif - -/**************** - * Copy some packets from INP to OUT, thereby removing unused spaces. - * Stop at offset STOPoff (i.e. don't copy packets at this or later offsets) - */ -#ifdef DEBUG_PARSE_PACKET -int -dbg_copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff, - const char *dbg_f, int dbg_l ) -{ - PACKET pkt; - int skip, rc=0; - do { - if( iobuf_tell(inp) >= stopoff ) - return 0; - init_packet(&pkt); - } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0, - "some", dbg_f, dbg_l )) ); - return rc; -} -#else -int -copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff ) -{ - PACKET pkt; - int skip, rc=0; - do { - if( iobuf_tell(inp) >= stopoff ) - return 0; - init_packet(&pkt); - } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )) ); - return rc; -} -#endif - -/**************** - * Skip over N packets - */ -#ifdef DEBUG_PARSE_PACKET -int -dbg_skip_some_packets( iobuf_t inp, unsigned n, - const char *dbg_f, int dbg_l ) -{ - int skip, rc=0; - PACKET pkt; - - for( ;n && !rc; n--) { - init_packet(&pkt); - rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1, "skip", dbg_f, dbg_l ); - } - return rc; -} -#else -int -skip_some_packets( iobuf_t inp, unsigned n ) -{ - int skip, rc=0; - PACKET pkt; - - for( ;n && !rc; n--) { - init_packet(&pkt); - rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1 ); - } - return rc; -} -#endif - - -/**************** - * Parse packet. Set the variable skip points to 1 if the packet - * should be skipped; this is the case if either ONLYKEYPKTS is set - * and the parsed packet isn't one or the - * packet-type is 0, indicating deleted stuff. - * if OUT is not NULL, a special copymode is used. - */ -static int -parse( iobuf_t inp, PACKET *pkt, int onlykeypkts, off_t *retpos, - int *skip, iobuf_t out, int do_skip -#ifdef DEBUG_PARSE_PACKET - ,const char *dbg_w, const char *dbg_f, int dbg_l -#endif - ) -{ - int rc=0, c, ctb, pkttype, lenbytes; - unsigned long pktlen; - byte hdr[8]; - int hdrlen; - int new_ctb = 0; - int with_uid = (onlykeypkts == 2); - - *skip = 0; - assert( !pkt->pkt.generic ); - if( retpos ) - *retpos = iobuf_tell(inp); - - if( (ctb = iobuf_get(inp)) == -1 ) { - rc = -1; - goto leave; - } - hdrlen=0; - hdr[hdrlen++] = ctb; - if( !(ctb & 0x80) ) { - log_error("%s: invalid packet (ctb=%02x)\n", iobuf_where(inp), ctb ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - pktlen = 0; - new_ctb = !!(ctb & 0x40); - if( new_ctb ) { - pkttype = ctb & 0x3f; - if( (c = iobuf_get(inp)) == -1 ) { - log_error("%s: 1st length byte missing\n", iobuf_where(inp) ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - if (pkttype == PKT_COMPRESSED) { - iobuf_set_partial_block_mode(inp, c & 0xff); - pktlen = 0;/* to indicate partial length */ - } - else { - hdr[hdrlen++] = c; - if( c < 192 ) - pktlen = c; - else if( c < 224 ) { - pktlen = (c - 192) * 256; - if( (c = iobuf_get(inp)) == -1 ) { - log_error("%s: 2nd length byte missing\n", - iobuf_where(inp) ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - hdr[hdrlen++] = c; - pktlen += c + 192; - } - else if( c == 255 ) { - pktlen = (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24; - pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 16; - pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8; - if( (c = iobuf_get(inp)) == -1 ) { - log_error("%s: 4 byte length invalid\n", - iobuf_where(inp) ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - pktlen |= (hdr[hdrlen++] = c ); - } - else { /* partial body length */ - iobuf_set_partial_block_mode(inp, c & 0xff); - pktlen = 0;/* to indicate partial length */ - } - } - } - else { - pkttype = (ctb>>2)&0xf; - lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3)); - if( !lenbytes ) { - pktlen = 0; /* don't know the value */ - switch (pkttype) { - case PKT_ENCRYPTED: - case PKT_PLAINTEXT: - /* These partial length encodings are from an very - early GnuPG release and deprecated. However we - still support them read-wise. Note, that we should - not allow them for any key related packets, because - this might render a keyring unusable if an errenous - packet indicated this mode but not complying to it - gets imported. */ - iobuf_set_block_mode(inp, 1); - break; - - case PKT_COMPRESSED: - break; /* the orginal pgp 2 way. */ - - default: - log_error ("%s: old style partial length " - "for invalid packet type\n", iobuf_where(inp) ); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; - } - } - else { - for( ; lenbytes; lenbytes-- ) { - pktlen <<= 8; - pktlen |= hdr[hdrlen++] = iobuf_get_noeof(inp); - } - } - } - - if (pktlen == 0xffffffff) { - /* with a some probability this is caused by a problem in the - * the uncompressing layer - in some error cases it just loops - * and spits out 0xff bytes. */ - log_error ("%s: garbled packet detected\n", iobuf_where(inp) ); - g10_exit (2); - } - - if( out && pkttype ) { - rc = iobuf_write( out, hdr, hdrlen ); - if (!rc) - rc = copy_packet(inp, out, pkttype, pktlen ); - goto leave; - } - - if (with_uid && pkttype == PKT_USER_ID) - ; - else if( do_skip - || !pkttype - || (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY - && pkttype != PKT_PUBLIC_KEY - && pkttype != PKT_SECRET_SUBKEY - && pkttype != PKT_SECRET_KEY ) ) { - skip_rest(inp, pktlen); - *skip = 1; - rc = 0; - goto leave; - } - - if( DBG_PACKET ) { -#ifdef DEBUG_PARSE_PACKET - log_debug("parse_packet(iob=%d): type=%d length=%lu%s (%s.%s.%d)\n", - iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"", - dbg_w, dbg_f, dbg_l ); -#else - log_debug("parse_packet(iob=%d): type=%d length=%lu%s\n", - iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"" ); -#endif - } - pkt->pkttype = pkttype; - rc = GPG_ERR_UNKNOWN_PACKET; /* default error */ - switch( pkttype ) { - case PKT_PUBLIC_KEY: - case PKT_PUBLIC_SUBKEY: - pkt->pkt.public_key = xcalloc (1,sizeof *pkt->pkt.public_key ); - rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt ); - break; - case PKT_SECRET_KEY: - case PKT_SECRET_SUBKEY: - pkt->pkt.secret_key = xcalloc (1,sizeof *pkt->pkt.secret_key ); - rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt ); - break; - case PKT_SYMKEY_ENC: - rc = parse_symkeyenc( inp, pkttype, pktlen, pkt ); - break; - case PKT_PUBKEY_ENC: - rc = parse_pubkeyenc(inp, pkttype, pktlen, pkt ); - break; - case PKT_SIGNATURE: - pkt->pkt.signature = xcalloc (1,sizeof *pkt->pkt.signature ); - rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature ); - break; - case PKT_ONEPASS_SIG: - pkt->pkt.onepass_sig = xcalloc (1,sizeof *pkt->pkt.onepass_sig ); - rc = parse_onepass_sig(inp, pkttype, pktlen, pkt->pkt.onepass_sig ); - break; - case PKT_USER_ID: - rc = parse_user_id(inp, pkttype, pktlen, pkt ); - break; - case PKT_ATTRIBUTE: - pkt->pkttype = pkttype = PKT_USER_ID; /* we store it in the userID */ - rc = parse_attribute(inp, pkttype, pktlen, pkt); - break; - case PKT_OLD_COMMENT: - case PKT_COMMENT: - rc = parse_comment(inp, pkttype, pktlen, pkt); - break; - case PKT_RING_TRUST: - parse_trust(inp, pkttype, pktlen, pkt); - rc = 0; - break; - case PKT_PLAINTEXT: - rc = parse_plaintext(inp, pkttype, pktlen, pkt, new_ctb ); - break; - case PKT_COMPRESSED: - rc = parse_compressed(inp, pkttype, pktlen, pkt, new_ctb ); - break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: - rc = parse_encrypted(inp, pkttype, pktlen, pkt, new_ctb ); - break; - case PKT_MDC: - rc = parse_mdc(inp, pkttype, pktlen, pkt, new_ctb ); - break; - case PKT_GPG_CONTROL: - rc = parse_gpg_control(inp, pkttype, pktlen, pkt ); - break; - default: - skip_packet(inp, pkttype, pktlen); - break; - } - - leave: - if( !rc && iobuf_error(inp) ) - rc = GPG_ERR_INV_KEYRING; - return rc; -} - -static void -dump_hex_line( int c, int *i ) -{ - if( *i && !(*i%8) ) { - if( *i && !(*i%24) ) - printf("\n%4d:", *i ); - else - putchar(' '); - } - if( c == -1 ) - printf(" EOF" ); - else - printf(" %02x", c ); - ++*i; -} - - -static int -copy_packet( iobuf_t inp, iobuf_t out, int pkttype, unsigned long pktlen ) -{ - int rc, n; - char buf[100]; - - if( iobuf_in_block_mode(inp) ) { - while( (n = iobuf_read( inp, buf, 100 )) != -1 ) - if( (rc = iobuf_write(out, buf, n )) ) - return rc; /* write error */ - } - else if( !pktlen && pkttype == PKT_COMPRESSED ) { - log_debug("copy_packet: compressed!\n"); - /* compressed packet, copy till EOF */ - while( (n = iobuf_read( inp, buf, 100 )) != -1 ) - if( (rc = iobuf_write(out, buf, n )) ) - return rc; /* write error */ - } - else { - for( ; pktlen; pktlen -= n ) { - n = pktlen > 100 ? 100 : pktlen; - n = iobuf_read( inp, buf, n ); - if( n == -1 ) - return GPG_ERR_GENERAL; /* FIXME(gcrypt): read error*/; - if( (rc = iobuf_write(out, buf, n )) ) - return rc; /* write error */ - } - } - return 0; -} - - -static void -skip_packet( iobuf_t inp, int pkttype, unsigned long pktlen ) -{ - if( list_mode ) { - if( pkttype == PKT_MARKER ) - fputs(":marker packet:\n", stdout ); - else - printf(":unknown packet: type %2d, length %lu\n", pkttype, pktlen); - if( pkttype ) { - int c, i=0 ; - if( pkttype != PKT_MARKER ) - fputs("dump:", stdout ); - if( iobuf_in_block_mode(inp) ) { - while( (c=iobuf_get(inp)) != -1 ) - dump_hex_line(c, &i); - } - else { - for( ; pktlen; pktlen-- ) - dump_hex_line(iobuf_get(inp), &i); - } - putchar('\n'); - return; - } - } - skip_rest(inp,pktlen); -} - -static void -skip_rest( iobuf_t inp, unsigned long pktlen ) -{ - if( iobuf_in_block_mode(inp) ) { - while( iobuf_get(inp) != -1 ) - ; - } - else { - for( ; pktlen; pktlen-- ) - if( iobuf_get(inp) == -1 ) - break; - } -} - - -static void * -read_rest( iobuf_t inp, size_t pktlen ) -{ - byte *p; - int i; - - if( iobuf_in_block_mode(inp) ) { - log_error("read_rest: can't store stream data\n"); - p = NULL; - } - else { - p = xmalloc ( pktlen ); - for(i=0; pktlen; pktlen--, i++ ) - p[i] = iobuf_get(inp); - } - return p; -} - - - -static int -parse_symkeyenc( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet ) -{ - PKT_symkey_enc *k; - int rc = 0; - int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen; - - if( pktlen < 4 ) { - log_error("packet(%d) too short\n", pkttype); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - version = iobuf_get_noeof(inp); pktlen--; - if( version != 4 ) { - log_error("packet(%d) with unknown version %d\n", pkttype, version); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - if( pktlen > 200 ) { /* (we encode the seskeylen in a byte) */ - log_error("packet(%d) too large\n", pkttype); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - cipher_algo = iobuf_get_noeof(inp); pktlen--; - s2kmode = iobuf_get_noeof(inp); pktlen--; - hash_algo = iobuf_get_noeof(inp); pktlen--; - switch( s2kmode ) { - case 0: /* simple s2k */ - minlen = 0; - break; - case 1: /* salted s2k */ - minlen = 8; - break; - case 3: /* iterated+salted s2k */ - minlen = 9; - break; - default: - log_error("unknown S2K %d\n", s2kmode ); - goto leave; - } - if( minlen > pktlen ) { - log_error("packet with S2K %d too short\n", s2kmode ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - seskeylen = pktlen - minlen; - k = packet->pkt.symkey_enc = xcalloc (1, sizeof *packet->pkt.symkey_enc - + seskeylen - 1 ); - k->version = version; - k->cipher_algo = cipher_algo; - k->s2k.mode = s2kmode; - k->s2k.hash_algo = hash_algo; - if( s2kmode == 1 || s2kmode == 3 ) { - for(i=0; i < 8 && pktlen; i++, pktlen-- ) - k->s2k.salt[i] = iobuf_get_noeof(inp); - } - if( s2kmode == 3 ) { - k->s2k.count = iobuf_get(inp); pktlen--; - } - k->seskeylen = seskeylen; - for(i=0; i < seskeylen && pktlen; i++, pktlen-- ) - k->seskey[i] = iobuf_get_noeof(inp); - assert( !pktlen ); - - if( list_mode ) { - printf(":symkey enc packet: version %d, cipher %d, s2k %d, hash %d\n", - version, cipher_algo, s2kmode, hash_algo); - if( s2kmode == 1 || s2kmode == 3 ) { - printf("\tsalt "); - for(i=0; i < 8; i++ ) - printf("%02x", k->s2k.salt[i]); - if( s2kmode == 3 ) - printf(", count %lu\n", (ulong)k->s2k.count ); - printf("\n"); - } - } - - leave: - skip_rest(inp, pktlen); - return rc; -} - -static int -parse_pubkeyenc( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet ) -{ - unsigned int n; - int rc = 0; - int i, ndata; - PKT_pubkey_enc *k; - - k = packet->pkt.pubkey_enc = xcalloc (1,sizeof *packet->pkt.pubkey_enc); - if( pktlen < 12 ) { - log_error("packet(%d) too short\n", pkttype); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - k->version = iobuf_get_noeof(inp); pktlen--; - if( k->version != 2 && k->version != 3 ) { - log_error("packet(%d) with unknown version %d\n", pkttype, k->version); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - k->keyid[0] = read_32(inp); pktlen -= 4; - k->keyid[1] = read_32(inp); pktlen -= 4; - k->pubkey_algo = iobuf_get_noeof(inp); pktlen--; - k->throw_keyid = 0; /* only used as flag for build_packet */ - if( list_mode ) - printf(":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n", - k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]); - - ndata = pubkey_get_nenc(k->pubkey_algo); - if( !ndata ) { - if( list_mode ) - printf("\tunsupported algorithm %d\n", k->pubkey_algo ); - unknown_pubkey_warning( k->pubkey_algo ); - k->data[0] = NULL; /* no need to store the encrypted data */ - } - else { - for( i=0; i < ndata; i++ ) { - n = pktlen; - k->data[i] = mpi_read(inp, &n, 0); pktlen -=n; - if( list_mode ) { - printf("\tdata: "); - mpi_print(stdout, k->data[i], mpi_print_mode ); - putchar('\n'); - } - if (!k->data[i]) - rc = GPG_ERR_INV_PACKET; - } - } - - leave: - skip_rest(inp, pktlen); - return rc; -} - - -static void -dump_sig_subpkt( int hashed, int type, int critical, - const byte *buffer, size_t buflen, size_t length ) -{ - const char *p=NULL; - int i; - - /* The CERT has warning out with explains how to use GNUPG to - * detect the ARRs - we print our old message here when it is a faked - * ARR and add an additional notice */ - if ( type == SIGSUBPKT_ARR && !hashed ) { - printf("\tsubpkt %d len %u (additional recipient request)\n" - "WARNING: PGP versions > 5.0 and < 6.5.8 will automagically " - "encrypt to this key and thereby reveal the plaintext to " - "the owner of this ARR key. Detailed info follows:\n", - type, (unsigned)length ); - } - - buffer++; - length--; - - printf("\t%s%ssubpkt %d len %u (", /*)*/ - critical ? "critical ":"", - hashed ? "hashed ":"", type, (unsigned)length ); - if( length > buflen ) { - printf("too short: buffer is only %u)\n", (unsigned)buflen ); - return; - } - switch( type ) { - case SIGSUBPKT_SIG_CREATED: - if( length >= 4 ) - printf("sig created %s", strtimestamp( buffer_to_u32(buffer) ) ); - break; - case SIGSUBPKT_SIG_EXPIRE: - if( length >= 4 ) - printf("sig expires after %s", - strtimevalue( buffer_to_u32(buffer) ) ); - break; - case SIGSUBPKT_EXPORTABLE: - if( length ) - printf("%sexportable", *buffer? "":"not "); - break; - case SIGSUBPKT_TRUST: - if(length!=2) - p="[invalid trust subpacket]"; - else - printf("trust signature of depth %d, value %d",buffer[0],buffer[1]); - break; - case SIGSUBPKT_REGEXP: - if(!length) - p="[invalid regexp subpacket]"; - else - printf("regular expression: \"%s\"",buffer); - break; - case SIGSUBPKT_REVOCABLE: - if( length ) - printf("%srevocable", *buffer? "":"not "); - break; - case SIGSUBPKT_KEY_EXPIRE: - if( length >= 4 ) - printf("key expires after %s", - strtimevalue( buffer_to_u32(buffer) ) ); - break; - case SIGSUBPKT_PREF_SYM: - fputs("pref-sym-algos:", stdout ); - for( i=0; i < length; i++ ) - printf(" %d", buffer[i] ); - break; - case SIGSUBPKT_REV_KEY: - fputs("revocation key: ", stdout ); - if( length < 22 ) - p = "[too short]"; - else { - printf("c=%02x a=%d f=", buffer[0], buffer[1] ); - for( i=2; i < length; i++ ) - printf("%02X", buffer[i] ); - } - break; - case SIGSUBPKT_ISSUER: - if( length >= 8 ) - printf("issuer key ID %08lX%08lX", - (ulong)buffer_to_u32(buffer), - (ulong)buffer_to_u32(buffer+4) ); - break; - case SIGSUBPKT_NOTATION: - { - fputs("notation: ", stdout ); - if( length < 8 ) - p = "[too short]"; - else { - const byte *s = buffer; - size_t n1, n2; - - n1 = (s[4] << 8) | s[5]; - n2 = (s[6] << 8) | s[7]; - s += 8; - if( 8+n1+n2 != length ) - p = "[error]"; - else { - print_string( stdout, s, n1, ')' ); - putc( '=', stdout ); - - if( *buffer & 0x80 ) - print_string( stdout, s+n1, n2, ')' ); - else - p = "[not human readable]"; - } - } - } - break; - case SIGSUBPKT_PREF_HASH: - fputs("pref-hash-algos:", stdout ); - for( i=0; i < length; i++ ) - printf(" %d", buffer[i] ); - break; - case SIGSUBPKT_PREF_COMPR: - fputs("pref-zip-algos:", stdout ); - for( i=0; i < length; i++ ) - printf(" %d", buffer[i] ); - break; - case SIGSUBPKT_KS_FLAGS: - fputs("key server preferences:",stdout); - for(i=0;i<length;i++) - printf(" %02X", buffer[i]); - break; - case SIGSUBPKT_PREF_KS: - fputs("preferred key server: ", stdout ); - print_string( stdout, buffer, length, ')' ); - break; - case SIGSUBPKT_PRIMARY_UID: - p = "primary user ID"; - break; - case SIGSUBPKT_POLICY: - fputs("policy: ", stdout ); - print_string( stdout, buffer, length, ')' ); - break; - case SIGSUBPKT_KEY_FLAGS: - fputs ( "key flags:", stdout ); - for( i=0; i < length; i++ ) - printf(" %02X", buffer[i] ); - break; - case SIGSUBPKT_SIGNERS_UID: - p = "signer's user ID"; - break; - case SIGSUBPKT_REVOC_REASON: - if( length ) { - printf("revocation reason 0x%02x (", *buffer ); - print_string( stdout, buffer+1, length-1, ')' ); - p = ")"; - } - break; - case SIGSUBPKT_ARR: - fputs("Big Brother's key (ignored): ", stdout ); - if( length < 22 ) - p = "[too short]"; - else { - printf("c=%02x a=%d f=", buffer[0], buffer[1] ); - for( i=2; i < length; i++ ) - printf("%02X", buffer[i] ); - } - break; - case SIGSUBPKT_FEATURES: - fputs ( "features:", stdout ); - for( i=0; i < length; i++ ) - printf(" %02x", buffer[i] ); - break; - default: - if(type>=100 && type<=110) - p="experimental / private subpacket"; - else - p = "?"; - break; - } - - printf("%s)\n", p? p: ""); -} - -/**************** - * Returns: >= 0 offset into buffer - * -1 unknown type - * -2 unsupported type - * -3 subpacket too short - */ -int -parse_one_sig_subpkt( const byte *buffer, size_t n, int type ) -{ - switch( type ) { - case SIGSUBPKT_REV_KEY: - if(n < 22) - break; - return 0; - case SIGSUBPKT_SIG_CREATED: - case SIGSUBPKT_SIG_EXPIRE: - case SIGSUBPKT_KEY_EXPIRE: - if( n < 4 ) - break; - return 0; - case SIGSUBPKT_KEY_FLAGS: - case SIGSUBPKT_KS_FLAGS: - case SIGSUBPKT_PREF_SYM: - case SIGSUBPKT_PREF_HASH: - case SIGSUBPKT_PREF_COMPR: - case SIGSUBPKT_POLICY: - case SIGSUBPKT_PREF_KS: - case SIGSUBPKT_FEATURES: - case SIGSUBPKT_REGEXP: - return 0; - case SIGSUBPKT_EXPORTABLE: - case SIGSUBPKT_REVOCABLE: - if( !n ) - break; - return 0; - case SIGSUBPKT_ISSUER: /* issuer key ID */ - if( n < 8 ) - break; - return 0; - case SIGSUBPKT_NOTATION: - if( n < 8 ) /* minimum length needed */ - break; - return 0; - case SIGSUBPKT_REVOC_REASON: - if( !n ) - break; - return 0; - case SIGSUBPKT_PRIMARY_UID: - if ( n != 1 ) - break; - return 0; - case SIGSUBPKT_TRUST: - if ( n != 2 ) - break; - return 0; - default: return -1; - } - return -3; -} - - -static int -can_handle_critical( const byte *buffer, size_t n, int type ) -{ - switch( type ) { - case SIGSUBPKT_NOTATION: - if( n >= 8 && (*buffer & 0x80) ) - return 1; /* human readable is handled */ - return 0; - - case SIGSUBPKT_SIG_CREATED: - case SIGSUBPKT_SIG_EXPIRE: - case SIGSUBPKT_KEY_EXPIRE: - case SIGSUBPKT_EXPORTABLE: - case SIGSUBPKT_REVOCABLE: - case SIGSUBPKT_REV_KEY: - case SIGSUBPKT_ISSUER:/* issuer key ID */ - case SIGSUBPKT_PREF_SYM: - case SIGSUBPKT_PREF_HASH: - case SIGSUBPKT_PREF_COMPR: - case SIGSUBPKT_KEY_FLAGS: - case SIGSUBPKT_PRIMARY_UID: - case SIGSUBPKT_FEATURES: - case SIGSUBPKT_TRUST: - case SIGSUBPKT_REGEXP: - /* Is it enough to show the policy or keyserver? */ - case SIGSUBPKT_POLICY: - case SIGSUBPKT_PREF_KS: - return 1; - - default: - return 0; - } -} - - -const byte * -enum_sig_subpkt( const subpktarea_t *pktbuf, sigsubpkttype_t reqtype, - size_t *ret_n, int *start, int *critical ) -{ - const byte *buffer; - int buflen; - int type; - int critical_dummy; - int offset; - size_t n; - int seq = 0; - int reqseq = start? *start: 0; - - if(!critical) - critical=&critical_dummy; - - if( !pktbuf || reqseq == -1 ) { - /* return some value different from NULL to indicate that - * there is no critical bit we do not understand. The caller - * will never use the value. Yes I know, it is an ugly hack */ - return reqtype == SIGSUBPKT_TEST_CRITICAL? (const byte*)&pktbuf : NULL; - } - buffer = pktbuf->data; - buflen = pktbuf->len; - while( buflen ) { - n = *buffer++; buflen--; - if( n == 255 ) { /* 4 byte length header */ - if( buflen < 4 ) - goto too_short; - n = (buffer[0] << 24) | (buffer[1] << 16) - | (buffer[2] << 8) | buffer[3]; - buffer += 4; - buflen -= 4; - } - else if( n >= 192 ) { /* 2 byte special encoded length header */ - if( buflen < 2 ) - goto too_short; - n = (( n - 192 ) << 8) + *buffer + 192; - buffer++; - buflen--; - } - if( buflen < n ) - goto too_short; - type = *buffer; - if( type & 0x80 ) { - type &= 0x7f; - *critical = 1; - } - else - *critical = 0; - if( !(++seq > reqseq) ) - ; - else if( reqtype == SIGSUBPKT_TEST_CRITICAL ) { - if( *critical ) { - if( n-1 > buflen+1 ) - goto too_short; - if( !can_handle_critical(buffer+1, n-1, type ) ) - { - if(opt.verbose) - log_info(_("subpacket of type %d has " - "critical bit set\n"),type); - if( start ) - *start = seq; - return NULL; /* this is an error */ - } - } - } - else if( reqtype < 0 ) /* list packets */ - dump_sig_subpkt( reqtype == SIGSUBPKT_LIST_HASHED, - type, *critical, buffer, buflen, n ); - else if( type == reqtype ) { /* found */ - buffer++; - n--; - if( n > buflen ) - goto too_short; - if( ret_n ) - *ret_n = n; - offset = parse_one_sig_subpkt(buffer, n, type ); - switch( offset ) { - case -3: - log_error("subpacket of type %d too short\n", type); - return NULL; - case -2: - return NULL; - case -1: - BUG(); /* not yet needed */ - default: - break; - } - if( start ) - *start = seq; - return buffer+offset; - } - buffer += n; buflen -=n; - } - if( reqtype == SIGSUBPKT_TEST_CRITICAL ) - return buffer; /* as value true to indicate that there is no */ - /* critical bit we don't understand */ - if( start ) - *start = -1; - return NULL; /* end of packets; not found */ - - too_short: - log_error("buffer shorter than subpacket\n"); - if( start ) - *start = -1; - return NULL; -} - - -const byte * -parse_sig_subpkt (const subpktarea_t *buffer, sigsubpkttype_t reqtype, - size_t *ret_n) -{ - return enum_sig_subpkt( buffer, reqtype, ret_n, NULL, NULL ); -} - -const byte * -parse_sig_subpkt2 (PKT_signature *sig, sigsubpkttype_t reqtype, - size_t *ret_n ) -{ - const byte *p; - - p = parse_sig_subpkt (sig->hashed, reqtype, ret_n ); - if( !p ) - p = parse_sig_subpkt (sig->unhashed, reqtype, ret_n ); - return p; -} - -/* Find all revocation keys. Look in hashed area only. */ -void parse_revkeys(PKT_signature *sig) -{ - struct revocation_key *revkey; - int seq=0; - size_t len; - - if(sig->sig_class!=0x1F) - return; - - while((revkey= - (struct revocation_key *)enum_sig_subpkt(sig->hashed, - SIGSUBPKT_REV_KEY, - &len,&seq,NULL))) - { - if(len==sizeof(struct revocation_key) && - (revkey->class&0x80)) /* 0x80 bit must be set */ - { - sig->revkey=xrealloc(sig->revkey, - sizeof(struct revocation_key *)*(sig->numrevkeys+1)); - sig->revkey[sig->numrevkeys]=revkey; - sig->numrevkeys++; - } - } -} - -static int -parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen, - PKT_signature *sig ) -{ - int md5_len=0; - unsigned n; - int is_v4=0; - int rc=0; - int i, ndata; - - if( pktlen < 16 ) { - log_error("packet(%d) too short\n", pkttype); - goto leave; - } - sig->version = iobuf_get_noeof(inp); pktlen--; - if( sig->version == 4 ) - is_v4=1; - else if( sig->version != 2 && sig->version != 3 ) { - log_error("packet(%d) with unknown version %d\n", pkttype, sig->version); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - - if( !is_v4 ) { - md5_len = iobuf_get_noeof(inp); pktlen--; - } - sig->sig_class = iobuf_get_noeof(inp); pktlen--; - if( !is_v4 ) { - sig->timestamp = read_32(inp); pktlen -= 4; - sig->keyid[0] = read_32(inp); pktlen -= 4; - sig->keyid[1] = read_32(inp); pktlen -= 4; - } - sig->pubkey_algo = iobuf_get_noeof(inp); pktlen--; - sig->digest_algo = iobuf_get_noeof(inp); pktlen--; - sig->flags.exportable=1; - sig->flags.revocable=1; - if( is_v4 ) { /* read subpackets */ - n = read_16(inp); pktlen -= 2; /* length of hashed data */ - if( n > 10000 ) { - log_error("signature packet: hashed data too long\n"); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - if( n ) { - sig->hashed = xmalloc (sizeof (*sig->hashed) + n - 1 ); - sig->hashed->size = n; - sig->hashed->len = n; - if( iobuf_read (inp, sig->hashed->data, n ) != n ) { - log_error ("premature eof while reading " - "hashed signature data\n"); - rc = -1; - goto leave; - } - pktlen -= n; - } - n = read_16(inp); pktlen -= 2; /* length of unhashed data */ - if( n > 10000 ) { - log_error("signature packet: unhashed data too long\n"); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - if( n ) { - sig->unhashed = xmalloc (sizeof(*sig->unhashed) + n - 1 ); - sig->unhashed->size = n; - sig->unhashed->len = n; - if( iobuf_read(inp, sig->unhashed->data, n ) != n ) { - log_error("premature eof while reading " - "unhashed signature data\n"); - rc = -1; - goto leave; - } - pktlen -= n; - } - } - - if( pktlen < 5 ) { /* sanity check */ - log_error("packet(%d) too short\n", pkttype); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - - sig->digest_start[0] = iobuf_get_noeof(inp); pktlen--; - sig->digest_start[1] = iobuf_get_noeof(inp); pktlen--; - - if( is_v4 && sig->pubkey_algo ) { /*extract required information */ - const byte *p; - size_t len; - - /* set sig->flags.unknown_critical if there is a - * critical bit set for packets which we do not understand */ - if( !parse_sig_subpkt (sig->hashed, SIGSUBPKT_TEST_CRITICAL, NULL) - || !parse_sig_subpkt (sig->unhashed, SIGSUBPKT_TEST_CRITICAL, - NULL) ) - { - sig->flags.unknown_critical = 1; - } - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL ); - if(p) - sig->timestamp = buffer_to_u32(p); - else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110)) - log_error("signature packet without timestamp\n"); - - p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL ); - if( p ) - { - sig->keyid[0] = buffer_to_u32(p); - sig->keyid[1] = buffer_to_u32(p+4); - } - else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110)) - log_error("signature packet without keyid\n"); - - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL); - if(p) - sig->expiredate=sig->timestamp+buffer_to_u32(p); - if(sig->expiredate && sig->expiredate<=make_timestamp()) - sig->flags.expired=1; - - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,NULL); - if(p) - sig->flags.policy_url=1; - - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,NULL); - if(p) - sig->flags.pref_ks=1; - - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL); - if(p) - sig->flags.notation=1; - - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_REVOCABLE,NULL); - if(p && *p==0) - sig->flags.revocable=0; - - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_TRUST,&len); - if(p && len==2) - { - sig->trust_depth=p[0]; - sig->trust_value=p[1]; - - /* Only look for a regexp if there is also a trust - subpacket. */ - sig->trust_regexp= - parse_sig_subpkt(sig->hashed,SIGSUBPKT_REGEXP,&len); - - /* If the regular expression is of 0 length, there is no - regular expression. */ - if(len==0) - sig->trust_regexp=NULL; - } - - /* We accept the exportable subpacket from either the hashed - or unhashed areas as older versions of gpg put it in the - unhashed area. In theory, anyway, we should never see this - packet off of a local keyring. */ - - p=parse_sig_subpkt2(sig,SIGSUBPKT_EXPORTABLE,NULL); - if(p && *p==0) - sig->flags.exportable=0; - - /* Find all revocation keys. */ - if(sig->sig_class==0x1F) - parse_revkeys(sig); - } - - if( list_mode ) { - printf(":signature packet: algo %d, keyid %08lX%08lX\n" - "\tversion %d, created %lu, md5len %d, sigclass %02x\n" - "\tdigest algo %d, begin of digest %02x %02x\n", - sig->pubkey_algo, - (ulong)sig->keyid[0], (ulong)sig->keyid[1], - sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class, - sig->digest_algo, - sig->digest_start[0], sig->digest_start[1] ); - if( is_v4 ) { - parse_sig_subpkt (sig->hashed, SIGSUBPKT_LIST_HASHED, NULL ); - parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL); - } - } - - ndata = pubkey_get_nsig(sig->pubkey_algo); - if( !ndata ) { - if( list_mode ) - printf("\tunknown algorithm %d\n", sig->pubkey_algo ); - unknown_pubkey_warning( sig->pubkey_algo ); - /* we store the plain material in data[0], so that we are able - * to write it back with build_packet() */ - sig->data[0] = gcry_mpi_set_opaque(NULL, read_rest(inp, pktlen), - pktlen*8 ); - pktlen = 0; - } - else { - for( i=0; i < ndata; i++ ) { - n = pktlen; - sig->data[i] = mpi_read(inp, &n, 0 ); - pktlen -=n; - if( list_mode ) { - printf("\tdata: "); - mpi_print(stdout, sig->data[i], mpi_print_mode ); - putchar('\n'); - } - if (!sig->data[i]) - rc = GPG_ERR_INV_PACKET; - } - } - - leave: - skip_rest(inp, pktlen); - return rc; -} - - -static int -parse_onepass_sig( iobuf_t inp, int pkttype, unsigned long pktlen, - PKT_onepass_sig *ops ) -{ - int version; - int rc = 0; - - if( pktlen < 13 ) { - log_error("packet(%d) too short\n", pkttype); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - version = iobuf_get_noeof(inp); pktlen--; - if( version != 3 ) { - log_error("onepass_sig with unknown version %d\n", version); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - ops->sig_class = iobuf_get_noeof(inp); pktlen--; - ops->digest_algo = iobuf_get_noeof(inp); pktlen--; - ops->pubkey_algo = iobuf_get_noeof(inp); pktlen--; - ops->keyid[0] = read_32(inp); pktlen -= 4; - ops->keyid[1] = read_32(inp); pktlen -= 4; - ops->last = iobuf_get_noeof(inp); pktlen--; - if( list_mode ) - printf(":onepass_sig packet: keyid %08lX%08lX\n" - "\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n", - (ulong)ops->keyid[0], (ulong)ops->keyid[1], - version, ops->sig_class, - ops->digest_algo, ops->pubkey_algo, ops->last ); - - - leave: - skip_rest(inp, pktlen); - return rc; -} - - -static gcry_mpi_t -read_protected_v3_mpi (iobuf_t inp, unsigned long *length) -{ - int c; - unsigned int nbits, nbytes; - unsigned char *buf, *p; - gcry_mpi_t val; - - if (*length < 2) - { - log_error ("mpi too small\n"); - return NULL; - } - - if ((c=iobuf_get (inp)) == -1) - return NULL; - --*length; - nbits = c << 8; - if ((c=iobuf_get(inp)) == -1) - return NULL; - --*length; - nbits |= c; - - if (nbits > 16384) - { - log_error ("mpi too large (%u bits)\n", nbits); - return NULL; - } - nbytes = (nbits+7) / 8; - buf = p = xmalloc (2 + nbytes); - *p++ = nbits >> 8; - *p++ = nbits; - for (; nbytes && length; nbytes--, --*length) - *p++ = iobuf_get (inp); - if (nbytes) - { - log_error ("packet shorter tham mpi\n"); - xfree (buf); - return NULL; - } - - /* convert buffer into an opaque gcry_mpi_t */ - val = gcry_mpi_set_opaque (NULL, buf, (p-buf)*8); - return val; -} - - -static int -parse_key( iobuf_t inp, int pkttype, unsigned long pktlen, - byte *hdr, int hdrlen, PACKET *pkt ) -{ - int i, version, algorithm; - unsigned n; - unsigned long timestamp, expiredate, max_expiredate; - int npkey, nskey; - int is_v4=0; - int rc=0; - - version = iobuf_get_noeof(inp); pktlen--; - if( pkttype == PKT_PUBLIC_SUBKEY && version == '#' ) { - /* early versions of G10 use old PGP comments packets; - * luckily all those comments are started by a hash */ - if( list_mode ) { - printf(":rfc1991 comment packet: \"" ); - for( ; pktlen; pktlen-- ) { - int c; - c = iobuf_get_noeof(inp); - if( c >= ' ' && c <= 'z' ) - putchar(c); - else - printf("\\x%02x", c ); - } - printf("\"\n"); - } - skip_rest(inp, pktlen); - return 0; - } - else if( version == 4 ) - is_v4=1; - else if( version != 2 && version != 3 ) { - log_error("packet(%d) with unknown version %d\n", pkttype, version); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - - if( pktlen < 11 ) { - log_error("packet(%d) too short\n", pkttype); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - - timestamp = read_32(inp); pktlen -= 4; - if( is_v4 ) { - expiredate = 0; /* have to get it from the selfsignature */ - max_expiredate = 0; - } - else { - unsigned short ndays; - ndays = read_16(inp); pktlen -= 2; - if( ndays ) - expiredate = timestamp + ndays * 86400L; - else - expiredate = 0; - - max_expiredate=expiredate; - } - algorithm = iobuf_get_noeof(inp); pktlen--; - if( list_mode ) - printf(":%s key packet:\n" - "\tversion %d, algo %d, created %lu, expires %lu\n", - pkttype == PKT_PUBLIC_KEY? "public" : - pkttype == PKT_SECRET_KEY? "secret" : - pkttype == PKT_PUBLIC_SUBKEY? "public sub" : - pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??", - version, algorithm, timestamp, expiredate ); - - if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *sk = pkt->pkt.secret_key; - - sk->timestamp = timestamp; - sk->expiredate = expiredate; - sk->max_expiredate = max_expiredate; - sk->hdrbytes = hdrlen; - sk->version = version; - sk->is_primary = pkttype == PKT_SECRET_KEY; - sk->pubkey_algo = algorithm; - sk->req_usage = 0; - sk->pubkey_usage = 0; /* not yet used */ - } - else { - PKT_public_key *pk = pkt->pkt.public_key; - - pk->timestamp = timestamp; - pk->expiredate = expiredate; - pk->max_expiredate = max_expiredate; - pk->hdrbytes = hdrlen; - pk->version = version; - pk->is_primary = pkttype == PKT_PUBLIC_KEY; - pk->pubkey_algo = algorithm; - pk->req_usage = 0; - pk->pubkey_usage = 0; /* not yet used */ - pk->is_revoked = 0; - pk->is_disabled = 0; - pk->keyid[0] = 0; - pk->keyid[1] = 0; - } - nskey = pubkey_get_nskey( algorithm ); - npkey = pubkey_get_npkey( algorithm ); - if( !npkey ) { - if( list_mode ) - printf("\tunknown algorithm %d\n", algorithm ); - unknown_pubkey_warning( algorithm ); - } - - - if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *sk = pkt->pkt.secret_key; - byte temp[16]; - size_t snlen = 0; - - if( !npkey ) { - sk->skey[0] = gcry_mpi_set_opaque( NULL, read_rest(inp, pktlen), - pktlen*8 ); - pktlen = 0; - goto leave; - } - - for(i=0; i < npkey; i++ ) { - n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n; - if( list_mode ) { - printf( "\tskey[%d]: ", i); - mpi_print(stdout, sk->skey[i], mpi_print_mode ); - putchar('\n'); - } - if (!sk->skey[i]) - rc = GPG_ERR_INV_PACKET; - } - if (rc) /* one of the MPIs were bad */ - goto leave; - sk->protect.algo = iobuf_get_noeof(inp); pktlen--; - sk->protect.sha1chk = 0; - if( sk->protect.algo ) { - sk->is_protected = 1; - sk->protect.s2k.count = 0; - if( sk->protect.algo == 254 || sk->protect.algo == 255 ) { - if( pktlen < 3 ) { - rc = GPG_ERR_INV_PACKET; - goto leave; - } - sk->protect.sha1chk = (sk->protect.algo == 254); - sk->protect.algo = iobuf_get_noeof(inp); pktlen--; - /* Note that a sk->protect.algo > 110 is illegal, but - I'm not erroring on it here as otherwise there - would be no way to delete such a key. */ - sk->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--; - sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--; - /* check for the special GNU extension */ - if( is_v4 && sk->protect.s2k.mode == 101 ) { - for(i=0; i < 4 && pktlen; i++, pktlen-- ) - temp[i] = iobuf_get_noeof(inp); - if( i < 4 || memcmp( temp, "GNU", 3 ) ) { - if( list_mode ) - printf( "\tunknown S2K %d\n", - sk->protect.s2k.mode ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - /* here we know that it is a gnu extension - * What follows is the GNU protection mode: - * All values have special meanings - * and they are mapped in the mode with a base of 1000. - */ - sk->protect.s2k.mode = 1000 + temp[3]; - } - switch( sk->protect.s2k.mode ) { - case 1: - case 3: - for(i=0; i < 8 && pktlen; i++, pktlen-- ) - temp[i] = iobuf_get_noeof(inp); - memcpy(sk->protect.s2k.salt, temp, 8 ); - break; - } - switch( sk->protect.s2k.mode ) { - case 0: if( list_mode ) printf( "\tsimple S2K" ); - break; - case 1: if( list_mode ) printf( "\tsalted S2K" ); - break; - case 3: if( list_mode ) printf( "\titer+salt S2K" ); - break; - case 1001: if( list_mode ) printf( "\tgnu-dummy S2K" ); - break; - case 1002: if (list_mode) printf("\tgnu-divert-to-card S2K"); - break; - default: - if( list_mode ) - printf( "\tunknown %sS2K %d\n", - sk->protect.s2k.mode < 1000? "":"GNU ", - sk->protect.s2k.mode ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - - if( list_mode ) { - printf(", algo: %d,%s hash: %d", - sk->protect.algo, - sk->protect.sha1chk?" SHA1 protection," - :" simple checksum,", - sk->protect.s2k.hash_algo ); - if( sk->protect.s2k.mode == 1 - || sk->protect.s2k.mode == 3 ) { - printf(", salt: "); - for(i=0; i < 8; i++ ) - printf("%02x", sk->protect.s2k.salt[i]); - } - putchar('\n'); - } - - if( sk->protect.s2k.mode == 3 ) { - if( pktlen < 1 ) { - rc = GPG_ERR_INV_PACKET; - goto leave; - } - sk->protect.s2k.count = iobuf_get(inp); - pktlen--; - if( list_mode ) - printf("\tprotect count: %lu\n", - (ulong)sk->protect.s2k.count); - } - else if( sk->protect.s2k.mode == 1002 ) { - /* Read the serial number. */ - if (pktlen < 1) { - rc = GPG_ERR_INV_PACKET; - goto leave; - } - snlen = iobuf_get (inp); - pktlen--; - if (pktlen < snlen || snlen == -1) { - rc = GPG_ERR_INV_PACKET; - goto leave; - } - } - } - /* Note that a sk->protect.algo > 110 is illegal, but I'm - not erroring on it here as otherwise there would be no - way to delete such a key. */ - else { /* old version; no S2K, so we set mode to 0, hash MD5 */ - sk->protect.s2k.mode = 0; - sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5; - if( list_mode ) - printf( "\tprotect algo: %d (hash algo: %d)\n", - sk->protect.algo, sk->protect.s2k.hash_algo ); - } - /* It is really ugly that we don't know the size - * of the IV here in cases we are not aware of the algorithm. - * so a - * sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo); - * won't work. The only solution I see is to hardwire it here. - * NOTE: if you change the ivlen above 16, don't forget to - * enlarge temp. - */ - switch( sk->protect.algo ) { - case 7: case 8: case 9: /* reserved for AES */ - case 10: /* Twofish */ - sk->protect.ivlen = 16; - break; - default: - sk->protect.ivlen = 8; - } - if( sk->protect.s2k.mode == 1001 ) - sk->protect.ivlen = 0; - else if( sk->protect.s2k.mode == 1002 ) { - if (snlen > 16) - log_info ("WARNING: serial number of card truncated\n"); - sk->protect.ivlen = snlen < 16? snlen : 16; - - } - if( pktlen < sk->protect.ivlen ) { - rc = GPG_ERR_INV_PACKET; - goto leave; - } - for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- ) - temp[i] = iobuf_get_noeof(inp); - if( list_mode ) { - printf( sk->protect.s2k.mode == 1002? "\tserial-number: " - : "\tprotect IV: "); - for(i=0; i < sk->protect.ivlen; i++ ) - printf(" %02x", temp[i] ); - putchar('\n'); - } - memcpy(sk->protect.iv, temp, sk->protect.ivlen ); - } - else - sk->is_protected = 0; - /* It does not make sense to read it into secure memory. - * If the user is so careless, not to protect his secret key, - * we can assume, that he operates an open system :=(. - * So we put the key into secure memory when we unprotect it. */ - if( sk->protect.s2k.mode == 1001 - || sk->protect.s2k.mode == 1002 ) { - /* better set some dummy stuff here */ - sk->skey[npkey] = gcry_mpi_set_opaque(NULL, xstrdup ("dummydata"), - 10*8); - pktlen = 0; - } - else if( is_v4 && sk->is_protected ) { - /* ugly; the length is encrypted too, so we read all - * stuff up to the end of the packet into the first - * skey element */ - sk->skey[npkey] = gcry_mpi_set_opaque(NULL, read_rest(inp, pktlen), - pktlen*8 ); - pktlen = 0; - if( list_mode ) { - printf("\tencrypted stuff follows\n"); - } - } - else { /* v3 method: the mpi length is not encrypted */ - for(i=npkey; i < nskey; i++ ) { - if ( sk->is_protected ) { - sk->skey[i] = read_protected_v3_mpi (inp, &pktlen); - if( list_mode ) - printf( "\tskey[%d]: [encrypted]\n", i); - } - else { - n = pktlen; - sk->skey[i] = mpi_read(inp, &n, 0 ); - pktlen -=n; - if( list_mode ) { - printf( "\tskey[%d]: ", i); - mpi_print(stdout, sk->skey[i], mpi_print_mode ); - putchar('\n'); - } - } - - if (!sk->skey[i]) - rc = GPG_ERR_INV_PACKET; - } - if (rc) - goto leave; - - sk->csum = read_16(inp); pktlen -= 2; - if( list_mode ) { - printf("\tchecksum: %04hx\n", sk->csum); - } - } - } - else { - PKT_public_key *pk = pkt->pkt.public_key; - - if( !npkey ) { - pk->pkey[0] = gcry_mpi_set_opaque( NULL, read_rest(inp, pktlen), - pktlen*8 ); - pktlen = 0; - goto leave; - } - - for(i=0; i < npkey; i++ ) { - n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n; - if( list_mode ) { - printf( "\tpkey[%d]: ", i); - mpi_print(stdout, pk->pkey[i], mpi_print_mode ); - putchar('\n'); - } - if (!pk->pkey[i]) - rc = GPG_ERR_INV_PACKET; - } - if (rc) - goto leave; - } - - leave: - skip_rest(inp, pktlen); - return rc; -} - -/* Attribute subpackets have the same format as v4 signature - subpackets. This is not part of OpenPGP, but is done in several - versions of PGP nevertheless. */ -int -parse_attribute_subpkts(PKT_user_id *uid) -{ - size_t n; - int count=0; - struct user_attribute *attribs=NULL; - const byte *buffer=uid->attrib_data; - int buflen=uid->attrib_len; - byte type; - - xfree (uid->attribs); - - while(buflen) - { - n = *buffer++; buflen--; - if( n == 255 ) { /* 4 byte length header */ - if( buflen < 4 ) - goto too_short; - n = (buffer[0] << 24) | (buffer[1] << 16) - | (buffer[2] << 8) | buffer[3]; - buffer += 4; - buflen -= 4; - } - else if( n >= 192 ) { /* 2 byte special encoded length header */ - if( buflen < 2 ) - goto too_short; - n = (( n - 192 ) << 8) + *buffer + 192; - buffer++; - buflen--; - } - if( buflen < n ) - goto too_short; - - attribs=xrealloc(attribs,(count+1)*sizeof(struct user_attribute)); - memset(&attribs[count],0,sizeof(struct user_attribute)); - - type=*buffer; - buffer++; - buflen--; - n--; - - attribs[count].type=type; - attribs[count].data=buffer; - attribs[count].len=n; - buffer+=n; - buflen-=n; - count++; - } - - uid->attribs=attribs; - uid->numattribs=count; - return count; - - too_short: - log_error("buffer shorter than attribute subpacket\n"); - uid->attribs=attribs; - uid->numattribs=count; - return count; -} - -static void setup_user_id(PACKET *packet) -{ - packet->pkt.user_id->ref = 1; - packet->pkt.user_id->attribs = NULL; - packet->pkt.user_id->attrib_data = NULL; - packet->pkt.user_id->attrib_len = 0; - packet->pkt.user_id->is_primary = 0; - packet->pkt.user_id->is_revoked = 0; - packet->pkt.user_id->is_expired = 0; - packet->pkt.user_id->expiredate = 0; - packet->pkt.user_id->created = 0; - packet->pkt.user_id->help_key_usage = 0; - packet->pkt.user_id->help_key_expire = 0; - packet->pkt.user_id->prefs = NULL; - packet->pkt.user_id->namehash = NULL; -} - -static int -parse_user_id( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet ) -{ - byte *p; - - packet->pkt.user_id = xmalloc (sizeof *packet->pkt.user_id + pktlen); - packet->pkt.user_id->len = pktlen; - - setup_user_id(packet); - - p = packet->pkt.user_id->name; - for( ; pktlen; pktlen--, p++ ) - *p = iobuf_get_noeof(inp); - *p = 0; - - if( list_mode ) { - int n = packet->pkt.user_id->len; - printf(":user ID packet: \""); - /* fixme: Hey why don't we replace this with print_string?? */ - for(p=packet->pkt.user_id->name; n; p++, n-- ) { - if( *p >= ' ' && *p <= 'z' ) - putchar(*p); - else - printf("\\x%02x", *p ); - } - printf("\"\n"); - } - return 0; -} - - -void -make_attribute_uidname(PKT_user_id *uid, size_t max_namelen) -{ - assert ( max_namelen > 70 ); - if(uid->numattribs<=0) - sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len); - else if(uid->numattribs>1) - sprintf(uid->name,"[%d attributes of size %lu]", - uid->numattribs,uid->attrib_len); - else - { - /* Only one attribute, so list it as the "user id" */ - - if(uid->attribs->type==ATTRIB_IMAGE) - { - u32 len; - byte type; - - if(parse_image_header(uid->attribs,&type,&len)) - sprintf(uid->name,"[%.20s image of size %lu]", - image_type_to_string(type,1),(ulong)len); - else - sprintf(uid->name,"[invalid image]"); - } - else - sprintf(uid->name,"[unknown attribute of size %lu]", - (ulong)uid->attribs->len); - } - - uid->len = strlen(uid->name); -} - -static int -parse_attribute( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet ) -{ - byte *p; - -#define EXTRA_UID_NAME_SPACE 71 - packet->pkt.user_id = xmalloc (sizeof *packet->pkt.user_id - + EXTRA_UID_NAME_SPACE); - - setup_user_id(packet); - - packet->pkt.user_id->attrib_data = xmalloc (pktlen); - packet->pkt.user_id->attrib_len = pktlen; - p = packet->pkt.user_id->attrib_data; - for( ; pktlen; pktlen--, p++ ) - *p = iobuf_get_noeof(inp); - - /* Now parse out the individual attribute subpackets. This is - somewhat pointless since there is only one currently defined - attribute type (jpeg), but it is correct by the spec. */ - parse_attribute_subpkts(packet->pkt.user_id); - - make_attribute_uidname(packet->pkt.user_id, EXTRA_UID_NAME_SPACE); - - if( list_mode ) { - printf(":attribute packet: %s\n", packet->pkt.user_id->name ); - } - return 0; -} - - -static int -parse_comment( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet ) -{ - byte *p; - - packet->pkt.comment = xmalloc (sizeof *packet->pkt.comment + pktlen - 1); - packet->pkt.comment->len = pktlen; - p = packet->pkt.comment->data; - for( ; pktlen; pktlen--, p++ ) - *p = iobuf_get_noeof(inp); - - if( list_mode ) { - int n = packet->pkt.comment->len; - printf(":%scomment packet: \"", pkttype == PKT_OLD_COMMENT? - "OpenPGP draft " : "" ); - for(p=packet->pkt.comment->data; n; p++, n-- ) { - if( *p >= ' ' && *p <= 'z' ) - putchar(*p); - else - printf("\\x%02x", *p ); - } - printf("\"\n"); - } - return 0; -} - - -static void -parse_trust( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *pkt ) -{ - int c; - - if (pktlen) - { - c = iobuf_get_noeof(inp); - pktlen--; - pkt->pkt.ring_trust = xmalloc ( sizeof *pkt->pkt.ring_trust ); - pkt->pkt.ring_trust->trustval = c; - pkt->pkt.ring_trust->sigcache = 0; - if (!c && pktlen==1) - { - c = iobuf_get_noeof (inp); - pktlen--; - /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/ - if ( !(c & 0x80) ) - pkt->pkt.ring_trust->sigcache = c; - } - if( list_mode ) - printf(":trust packet: flag=%02x sigcache=%02x\n", - pkt->pkt.ring_trust->trustval, - pkt->pkt.ring_trust->sigcache); - } - else - { - if( list_mode ) - printf(":trust packet: empty\n"); - } - skip_rest (inp, pktlen); -} - - -static int -parse_plaintext( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *pkt, int new_ctb ) -{ - int rc = 0; - int mode, namelen, partial=0; - PKT_plaintext *pt; - byte *p; - int c, i; - - if( pktlen && pktlen < 6 ) { - log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - /* A packet length of zero indicates partial body length. A zero - data length isn't a zero length packet due to the header (mode, - name, etc), so this is accurate. */ - if(pktlen==0) - partial=1; - mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--; - namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--; - pt = pkt->pkt.plaintext = xmalloc (sizeof *pkt->pkt.plaintext + namelen -1); - pt->new_ctb = new_ctb; - pt->mode = mode; - pt->namelen = namelen; - pt->is_partial = partial; - if( pktlen ) { - for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ ) - pt->name[i] = iobuf_get_noeof(inp); - } - else { - for( i=0; i < namelen; i++ ) - if( (c=iobuf_get(inp)) == -1 ) - break; - else - pt->name[i] = c; - } - pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4; - pt->len = pktlen; - pt->buf = inp; - pktlen = 0; - - if( list_mode ) { - printf(":literal data packet:\n" - "\tmode %c, created %lu, name=\"", - mode >= ' ' && mode <'z'? mode : '?', - (ulong)pt->timestamp ); - for(p=pt->name,i=0; i < namelen; p++, i++ ) { - if( *p >= ' ' && *p <= 'z' ) - putchar(*p); - else - printf("\\x%02x", *p ); - } - printf("\",\n\traw data: %lu bytes\n", (ulong)pt->len ); - } - - leave: - return rc; -} - - -static int -parse_compressed( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *pkt, int new_ctb ) -{ - PKT_compressed *zd; - - /* pktlen is here 0, but data follows - * (this should be the last object in a file or - * the compress algorithm should know the length) - */ - zd = pkt->pkt.compressed = xmalloc (sizeof *pkt->pkt.compressed ); - zd->algorithm = iobuf_get_noeof(inp); - zd->len = 0; /* not used */ - zd->new_ctb = new_ctb; - zd->buf = inp; - if( list_mode ) - printf(":compressed packet: algo=%d\n", zd->algorithm); - return 0; -} - - -static int -parse_encrypted( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *pkt, int new_ctb ) -{ - int rc = 0; - PKT_encrypted *ed; - unsigned long orig_pktlen = pktlen; - - ed = pkt->pkt.encrypted = xmalloc (sizeof *pkt->pkt.encrypted ); - ed->len = pktlen; - /* we don't know the extralen which is (cipher_blocksize+2) - because the algorithm ist not specified in this packet. - However, it is only important to know this for some sanity - checks on the packet length - it doesn't matter that we can't - do it */ - ed->extralen = 0; - ed->buf = NULL; - ed->new_ctb = new_ctb; - ed->mdc_method = 0; - if( pkttype == PKT_ENCRYPTED_MDC ) { - /* fixme: add some pktlen sanity checks */ - int version; - - version = iobuf_get_noeof(inp); - if (orig_pktlen) - pktlen--; - if( version != 1 ) { - log_error("encrypted_mdc packet with unknown version %d\n", - version); - /*skip_rest(inp, pktlen); should we really do this? */ - rc = GPG_ERR_INV_PACKET; - goto leave; - } - ed->mdc_method = DIGEST_ALGO_SHA1; - } - if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */ - log_error("packet(%d) too short\n", pkttype); - rc = GPG_ERR_INV_PACKET; - skip_rest(inp, pktlen); - goto leave; - } - if( list_mode ) { - if( orig_pktlen ) - printf(":encrypted data packet:\n\tlength: %lu\n", orig_pktlen); - else - printf(":encrypted data packet:\n\tlength: unknown\n"); - if( ed->mdc_method ) - printf("\tmdc_method: %d\n", ed->mdc_method ); - } - - ed->buf = inp; - pktlen = 0; - - leave: - return rc; -} - - -static int -parse_mdc( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *pkt, int new_ctb ) -{ - int rc = 0; - PKT_mdc *mdc; - byte *p; - - mdc = pkt->pkt.mdc= xmalloc (sizeof *pkt->pkt.mdc ); - if( list_mode ) - printf(":mdc packet: length=%lu\n", pktlen); - if( !new_ctb || pktlen != 20 ) { - log_error("mdc_packet with invalid encoding\n"); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - p = mdc->hash; - for( ; pktlen; pktlen--, p++ ) - *p = iobuf_get_noeof(inp); - - leave: - return rc; -} - - -/* - * This packet is internally generated by PGG (by armor.c) to - * transfer some information to the lower layer. To make sure that - * this packet is really a GPG faked one and not one comming from outside, - * we first check that tehre is a unique tag in it. - * The format of such a control packet is: - * n byte session marker - * 1 byte control type CTRLPKT_xxxxx - * m byte control data - */ - -static int -parse_gpg_control( iobuf_t inp, - int pkttype, unsigned long pktlen, PACKET *packet ) -{ - byte *p; - const byte *sesmark; - size_t sesmarklen; - int i; - - if ( list_mode ) - printf(":packet 63: length %lu ", pktlen); - - sesmark = get_session_marker ( &sesmarklen ); - if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */ - goto skipit; - for( i=0; i < sesmarklen; i++, pktlen-- ) { - if ( sesmark[i] != iobuf_get_noeof(inp) ) - goto skipit; - } - if ( list_mode ) - puts ("- gpg control packet"); - - packet->pkt.gpg_control = xmalloc (sizeof *packet->pkt.gpg_control - + pktlen - 1); - packet->pkt.gpg_control->control = iobuf_get_noeof(inp); pktlen--; - packet->pkt.gpg_control->datalen = pktlen; - p = packet->pkt.gpg_control->data; - for( ; pktlen; pktlen--, p++ ) - *p = iobuf_get_noeof(inp); - - return 0; - - skipit: - if ( list_mode ) { - int c; - - i=0; - printf("- private (rest length %lu)\n", pktlen); - if( iobuf_in_block_mode(inp) ) { - while( (c=iobuf_get(inp)) != -1 ) - dump_hex_line(c, &i); - } - else { - for( ; pktlen; pktlen-- ) - dump_hex_line(iobuf_get(inp), &i); - } - putchar('\n'); - } - skip_rest(inp,pktlen); - return GPG_ERR_INV_PACKET; -} - -/* create a gpg control packet to be used internally as a placeholder */ -PACKET * -create_gpg_control( ctrlpkttype_t type, const byte *data, size_t datalen ) -{ - PACKET *packet; - byte *p; - - packet = xmalloc ( sizeof *packet ); - init_packet(packet); - packet->pkttype = PKT_GPG_CONTROL; - packet->pkt.gpg_control = xmalloc (sizeof *packet->pkt.gpg_control - + datalen - 1); - packet->pkt.gpg_control->control = type; - packet->pkt.gpg_control->datalen = datalen; - p = packet->pkt.gpg_control->data; - for( ; datalen; datalen--, p++ ) - *p = *data++; - - return packet; -} diff --git a/g10/passphrase.c b/g10/passphrase.c deleted file mode 100644 index 986070a16..000000000 --- a/g10/passphrase.c +++ /dev/null @@ -1,1237 +0,0 @@ -/* passphrase.c - Get a passphrase - * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <assert.h> -#if !defined(HAVE_DOSISH_SYSTEM) && !defined(__riscos__) -#include <sys/socket.h> -#include <sys/un.h> -#endif -#if defined (_WIN32) || defined (__CYGWIN32__) -# include <windows.h> -#endif -#include <errno.h> -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif -#ifdef HAVE_LANGINFO_CODESET -#include <langinfo.h> -#endif - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "options.h" -#include "ttyio.h" -#include "cipher.h" -#include "keydb.h" -#include "main.h" -#include "i18n.h" -#include "status.h" - - -enum gpga_protocol_codes { - /* Request codes */ - GPGA_PROT_GET_VERSION = 1, - GPGA_PROT_GET_PASSPHRASE = 2, - GPGA_PROT_CLEAR_PASSPHRASE= 3, - GPGA_PROT_SHUTDOWN = 4, - GPGA_PROT_FLUSH = 5, - - /* Reply codes */ - GPGA_PROT_REPLY_BASE = 0x10000, - GPGA_PROT_OKAY = 0x10001, - GPGA_PROT_GOT_PASSPHRASE = 0x10002, - - /* Error codes */ - GPGA_PROT_ERROR_BASE = 0x20000, - GPGA_PROT_PROTOCOL_ERROR = 0x20001, - GPGA_PROT_INVALID_REQUEST= 0x20002, - GPGA_PROT_CANCELED = 0x20003, - GPGA_PROT_NO_PASSPHRASE = 0x20004, - GPGA_PROT_BAD_PASSPHRASE = 0x20005, - GPGA_PROT_INVALID_DATA = 0x20006, - GPGA_PROT_NOT_IMPLEMENTED= 0x20007, - GPGA_PROT_UI_PROBLEM = 0x20008 -}; - - -#define buftou32( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \ - (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3))) -#define u32tobuf( p, a ) do { \ - ((byte*)p)[0] = (byte)((a) >> 24); \ - ((byte*)p)[1] = (byte)((a) >> 16); \ - ((byte*)p)[2] = (byte)((a) >> 8); \ - ((byte*)p)[3] = (byte)((a) ); \ - } while(0) - -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) - - - -static char *fd_passwd = NULL; -static char *next_pw = NULL; -static char *last_pw = NULL; - -#if defined (_WIN32) -static int read_fd = 0; -static int write_fd = 0; -#endif - -static void hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ); - -int -have_static_passphrase() -{ - if ( opt.use_agent ) - return 0; - return !!fd_passwd; -} - -/**************** - * Set the passphrase to be used for the next query and only for the next - * one. - */ -void -set_next_passphrase( const char *s ) -{ - xfree (next_pw); - next_pw = NULL; - if( s ) { - next_pw = gcry_xmalloc_secure ( strlen(s)+1 ); - strcpy(next_pw, s ); - } -} - -/**************** - * Get the last passphrase used in passphrase_to_dek. - * Note: This removes the passphrase from this modules and - * the caller must free the result. May return NULL: - */ -char * -get_last_passphrase() -{ - char *p = last_pw; - last_pw = NULL; - return p; -} - - -void -read_passphrase_from_fd( int fd ) -{ - int i, len; - char *pw; - - if ( opt.use_agent ) - { /* Not used but we have to do a dummy read, so that it won't end - up at the begin of the message if the quite usual trick to - prepend the passphtrase to the message is used. */ - char buf[1]; - - while (!(read (fd, buf, 1) != 1 || *buf == '\n' )) - ; - *buf = 0; - return; - } - - if (!opt.batch ) - tty_printf("Reading passphrase from file descriptor %d ...", fd ); - for (pw = NULL, i = len = 100; ; i++ ) - { - if (i >= len-1 ) - { - char *pw2 = pw; - len += 100; - pw = gcry_xmalloc_secure ( len ); - if( pw2 ) - memcpy(pw, pw2, i ); - else - i=0; - } - if (read( fd, pw+i, 1) != 1 || pw[i] == '\n' ) - break; - } - pw[i] = 0; - if (!opt.batch) - tty_printf("\b\b\b \n" ); - - xfree ( fd_passwd ); - fd_passwd = pw; -} - -static int -writen ( int fd, const void *buf, size_t nbytes ) -{ -#if defined (_WIN32) - DWORD nwritten, nleft = nbytes; - - while (nleft > 0) { - if ( !WriteFile( (HANDLE)write_fd, buf, nleft, &nwritten, NULL) ) { - log_error("write failed: ec=%d\n", (int)GetLastError()); - return -1; - } - /*log_info("** WriteFile fd=%d nytes=%d nwritten=%d\n", - write_fd, nbytes, (int)nwritten);*/ - Sleep(100); - - nleft -= nwritten; - buf = (const BYTE *)buf + nwritten; - } -#elif defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - /* not implemented */ -#else - size_t nleft = nbytes; - int nwritten; - - while( nleft > 0 ) { - nwritten = write( fd, buf, nleft ); - if( nwritten < 0 ) { - if ( errno == EINTR ) - nwritten = 0; - else { - log_error ( "write() failed: %s\n", strerror (errno) ); - return -1; - } - } - nleft -= nwritten; - buf = (const char*)buf + nwritten; - } -#endif - - return 0; -} - - -static int -readn ( int fd, void *buf, size_t buflen, size_t *ret_nread ) -{ -#if defined (_WIN32) - DWORD nread, nleft = buflen; - - while (nleft > 0) { - if ( !ReadFile( (HANDLE)read_fd, buf, nleft, &nread, NULL) ) { - log_error("read() error: ec=%d\n", (int)GetLastError()); - return -1; - } - if (!nread || GetLastError() == ERROR_BROKEN_PIPE) - break; - /*log_info("** ReadFile fd=%d buflen=%d nread=%d\n", - read_fd, buflen, (int)nread);*/ - Sleep(100); - - nleft -= nread; - buf = (BYTE *)buf + nread; - } - if (ret_nread) - *ret_nread = buflen - nleft; - -#elif defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - /* not implemented */ -#else - size_t nleft = buflen; - int nread; - char *p; - - p = buf; - while( nleft > 0 ) { - nread = read ( fd, buf, nleft ); - if( nread < 0 ) { - if (nread == EINTR) - nread = 0; - else { - log_error ( "read() error: %s\n", strerror (errno) ); - return -1; - } - } - else if( !nread ) - break; /* EOF */ - nleft -= nread; - buf = (char*)buf + nread; - } - if( ret_nread ) - *ret_nread = buflen - nleft; -#endif - - return 0; -} - -/* read an entire line */ -static int -readline (int fd, char *buf, size_t buflen) -{ - size_t nleft = buflen; - char *p; - int nread = 0; - - while (nleft > 0) - { - int n = read (fd, buf, nleft); - if (n < 0) - { - if (errno == EINTR) - continue; - return -1; /* read error */ - } - else if (!n) - { - return -1; /* incomplete line */ - } - p = buf; - nleft -= n; - buf += n; - nread += n; - - for (; n && *p != '\n'; n--, p++) - ; - if (n) - { - break; /* at least one full line available - that's enough. - This function is just a temporary hack until we use - the assuna lib in gpg. So it is okay to forget - about pending bytes */ - } - } - - return nread; -} - - - -#if !defined (__riscos__) - -#if !defined (_WIN32) -/* For the new Assuan protocol we may have to send options */ -static int -agent_send_option (int fd, const char *name, const char *value) -{ - char buf[200]; - int nread; - char *line; - int i; - - line = xmalloc (7 + strlen (name) + 1 + strlen (value) + 2); - strcpy (stpcpy (stpcpy (stpcpy ( - stpcpy (line, "OPTION "), name), "="), value), "\n"); - i = writen (fd, line, strlen (line)); - xfree (line); - if (i) - return -1; - - /* get response */ - nread = readline (fd, buf, DIM(buf)-1); - if (nread < 3) - return -1; - - if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n')) - return 0; /* okay */ - - return -1; -} - -static int -agent_send_all_options (int fd) -{ - char *dft_display = NULL; - const char *dft_ttyname = NULL; - char *dft_ttytype = NULL; - char *old_lc = NULL; - char *dft_lc = NULL; - int rc = 0; - - dft_display = getenv ("DISPLAY"); - if (opt.display || dft_display) - { - if (agent_send_option (fd, "display", - opt.display ? opt.display : dft_display)) - return -1; - } - - if (!opt.ttyname) - { - dft_ttyname = getenv ("GPG_TTY"); - if ((!dft_ttyname || !*dft_ttyname) && tty_get_ttyname ()) - dft_ttyname = tty_get_ttyname (); - } - if (opt.ttyname || dft_ttyname) - { - if (agent_send_option (fd, "ttyname", - opt.ttyname ? opt.ttyname : dft_ttyname)) - return -1; - } - - dft_ttytype = getenv ("TERM"); - if (opt.ttytype || (dft_ttyname && dft_ttytype)) - { - if (agent_send_option (fd, "ttytype", - opt.ttyname ? opt.ttytype : dft_ttytype)) - return -1; - } - -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - old_lc = setlocale (LC_CTYPE, NULL); - if (old_lc) - old_lc = xstrdup (old_lc); - dft_lc = setlocale (LC_CTYPE, ""); -#endif - if (opt.lc_ctype || (dft_ttyname && dft_lc)) - { - rc = agent_send_option (fd, "lc-ctype", - opt.lc_ctype ? opt.lc_ctype : dft_lc); - } -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - if (old_lc) - { - setlocale (LC_CTYPE, old_lc); - xfree (old_lc); - } -#endif - if (rc) - return rc; - -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - old_lc = setlocale (LC_MESSAGES, NULL); - if (old_lc) - old_lc = xstrdup (old_lc); - dft_lc = setlocale (LC_MESSAGES, ""); -#endif - if (opt.lc_messages || (dft_ttyname && dft_lc)) - { - rc = agent_send_option (fd, "lc-messages", - opt.lc_messages ? opt.lc_messages : dft_lc); - } -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - if (old_lc) - { - setlocale (LC_MESSAGES, old_lc); - xfree (old_lc); - } -#endif - return rc; -} -#endif /*!_WIN32*/ - - -/* - * Open a connection to the agent and send the magic string - * Returns: -1 on error or an filedescriptor for urther processing - */ - -static int -agent_open (int *ret_prot) -{ -#if defined (_WIN32) - int fd; - char *infostr, *p; - HANDLE h; - char pidstr[128]; - - *ret_prot = 0; - if ( !(infostr = read_w32_registry_string(NULL, "Software\\GNU\\GnuPG", - "agentPID")) - || *infostr == '0') { - log_error( _("gpg-agent is not available in this session\n")); - return -1; - } - free(infostr); - - sprintf(pidstr, "%u", (unsigned int)GetCurrentProcessId()); - if (write_w32_registry_string(NULL, "Software\\GNU\\GnuPG", - "agentCID", pidstr)) { - log_error( _("can't set client pid for the agent\n") ); - return -1; - } - h = OpenEvent(EVENT_ALL_ACCESS, FALSE, "gpg_agent"); - SetEvent(h); - Sleep(50); /* some time for the server */ - if ( !(p = read_w32_registry_string(NULL, "Software\\GNU\\GnuPG", - "agentReadFD")) ) { - log_error( _("can't get server read FD for the agent\n") ); - return -1; - } - read_fd = atol(p); - free(p); - if ( !(p = read_w32_registry_string(NULL, "Software\\GNU\\GnuPG", - "agentWriteFD")) ) { - log_error ( _("can't get server write FD for the agent\n") ); - return -1; - } - write_fd = atol(p); - free(p); - fd = 0; - - if ( writen ( fd, "GPGA\0\0\0\x01", 8 ) ) { - fd = -1; - } -#else /* Posix */ - - int fd; - char *infostr, *p; - struct sockaddr_un client_addr; - size_t len; - int prot; - - if (opt.gpg_agent_info) - infostr = xstrdup (opt.gpg_agent_info); - else - { - infostr = getenv ( "GPG_AGENT_INFO" ); - if ( !infostr || !*infostr ) { - log_error (_("gpg-agent is not available in this session\n")); - opt.use_agent = 0; - return -1; - } - infostr = xstrdup ( infostr ); - } - - if ( !(p = strchr ( infostr, ':')) || p == infostr - || (p-infostr)+1 >= sizeof client_addr.sun_path ) { - log_error( _("malformed GPG_AGENT_INFO environment variable\n")); - xfree (infostr ); - opt.use_agent = 0; - return -1; - } - *p++ = 0; - /* See whether this is the new gpg-agent using the Assuna protocl. - This agent identifies itself by have an info string with a - version number in the 3rd field. */ - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if ( prot < 0 || prot > 1) { - log_error (_("gpg-agent protocol version %d is not supported\n"),prot); - xfree (infostr ); - opt.use_agent = 0; - return -1; - } - *ret_prot = prot; - - if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ) { - log_error ("can't create socket: %s\n", strerror(errno) ); - xfree (infostr ); - opt.use_agent = 0; - return -1; - } - - memset( &client_addr, 0, sizeof client_addr ); - client_addr.sun_family = AF_UNIX; - strcpy( client_addr.sun_path, infostr ); - len = offsetof (struct sockaddr_un, sun_path) - + strlen(client_addr.sun_path) + 1; - - if( connect( fd, (struct sockaddr*)&client_addr, len ) == -1 ) { - log_error ( _("can't connect to `%s': %s\n"), - infostr, strerror (errno) ); - xfree (infostr ); - close (fd ); - opt.use_agent = 0; - return -1; - } - xfree (infostr); - - if (!prot) { - if ( writen ( fd, "GPGA\0\0\0\x01", 8 ) ) { - close (fd); - fd = -1; - } - } - else { /* assuan based gpg-agent */ - char line[200]; - int nread; - - nread = readline (fd, line, DIM(line)); - if (nread < 3 || !(line[0] == 'O' && line[1] == 'K' - && (line[2] == '\n' || line[2] == ' ')) ) { - log_error ( _("communication problem with gpg-agent\n")); - close (fd ); - opt.use_agent = 0; - return -1; - } - - if (agent_send_all_options (fd)) { - log_error (_("problem with the agent - disabling agent use\n")); - close (fd); - opt.use_agent = 0; - return -1; - } - - } -#endif - - return fd; -} - - -static void -agent_close ( int fd ) -{ -#if defined (_WIN32) - HANDLE h = OpenEvent(EVENT_ALL_ACCESS, FALSE, "gpg_agent"); - ResetEvent(h); -#else - close (fd); -#endif -} -#endif /* !__riscos__ */ - - - -/* - * Ask the GPG Agent for the passphrase. - * Mode 0: Allow cached passphrase - * 1: No cached passphrase FIXME: Not really implemented - * 2: Ditto, but change the text to "repeat entry" - * - * Note that TRYAGAIN_TEXT must not be translated. If canceled is not - * NULL, the function does set it to 1 if the user canceled the - * operation. - */ -static char * -agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text, - int *canceled) -{ -#if defined(__riscos__) - return NULL; -#else - size_t n; - char *atext = NULL; - char buf[50]; - int fd = -1; - int nread; - u32 reply; - char *pw = NULL; - PKT_public_key *pk = xcalloc (1, sizeof *pk ); - byte fpr[MAX_FINGERPRINT_LEN]; - int have_fpr = 0; - int prot; - char *orig_codeset = NULL; - - if (canceled) - *canceled = 0; - -#if MAX_FINGERPRINT_LEN < 20 -#error agent needs a 20 byte fingerprint -#endif - - memset (fpr, 0, MAX_FINGERPRINT_LEN ); - if( keyid && get_pubkey( pk, keyid ) ) - { - free_public_key( pk ); - pk = NULL; /* oops: no key for some reason */ - } - -#ifdef ENABLE_NLS - /* The Assuan agent protocol requires us to transmit utf-8 strings */ - orig_codeset = bind_textdomain_codeset (PACKAGE_GT, NULL); -#ifdef HAVE_LANGINFO_CODESET - if (!orig_codeset) - orig_codeset = nl_langinfo (CODESET); -#endif - if (orig_codeset) - { /* We only switch when we are able to restore the codeset later. */ - orig_codeset = xstrdup (orig_codeset); - if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8")) - orig_codeset = NULL; - } -#endif - - if ( (fd = agent_open (&prot)) == -1 ) - goto failure; - - if ( !mode && pk && keyid ) - { - char *uid; - size_t uidlen; - const char *algo_name = gcry_pk_algo_name ( pk->pubkey_algo ); - const char *timestr; - char *maink; - - if ( !algo_name ) - algo_name = "?"; - - if( keyid[2] && keyid[3] && keyid[0] != keyid[2] - && keyid[1] != keyid[3] ) - maink = xasprintf ( _(" (main key ID %08lX)"), (ulong)keyid[3] ); - else - maink = NULL; - - uid = get_user_id ( keyid, &uidlen ); - timestr = strtimestamp (pk->timestamp); - atext = xasprintf ( - _("You need a passphrase to unlock the" - " secret key for user:\n" - "\"%.*s\"\n" - "%u-bit %s key, ID %08lX, created %s%s\n" ), - uidlen, uid, - nbits_from_pk (pk), algo_name, (ulong)keyid[1], timestr, - maink?maink:"" ); - xfree (uid); - xfree (maink); - - { - size_t dummy; - fingerprint_from_pk( pk, fpr, &dummy ); - have_fpr = 1; - } - - } - else if (mode == 2 ) - atext = xstrdup ( _("Repeat passphrase\n") ); - else - atext = xstrdup ( _("Enter passphrase\n") ); - - if (!prot) - { /* old style protocol */ - n = 4 + 20 + strlen (atext); - u32tobuf (buf, n ); - u32tobuf (buf+4, GPGA_PROT_GET_PASSPHRASE ); - memcpy (buf+8, fpr, 20 ); - if ( writen ( fd, buf, 28 ) || writen ( fd, atext, strlen (atext) ) ) - goto failure; - xfree (atext); atext = NULL; - - /* get response */ - if ( readn ( fd, buf, 12, &nread ) ) - goto failure; - - if ( nread < 8 ) - { - log_error ( "response from agent too short\n" ); - goto failure; - } - n = buftou32 ( buf ); - reply = buftou32 ( buf + 4 ); - if ( reply == GPGA_PROT_GOT_PASSPHRASE ) - { - size_t pwlen; - size_t nn; - - if ( nread < 12 || n < 8 ) - { - log_error ( "response from agent too short\n" ); - goto failure; - } - pwlen = buftou32 ( buf + 8 ); - nread -= 12; - n -= 8; - if ( pwlen > n || n > 1000 ) - { - log_error (_("passphrase too long\n")); - /* or protocol error */ - goto failure; - } - /* we read the whole block in one chunk to give no hints - * on how long the passhrase actually is - this wastes some bytes - * but because we already have this padding we should not loosen - * this by issuing 2 read calls */ - pw = xmalloc_secure ( n+1 ); - if ( readn ( fd, pw, n, &nn ) ) - goto failure; - if ( n != nn ) - { - log_error (_("invalid response from agent\n")); - goto failure; - } - pw[pwlen] = 0; /* make a C String */ - agent_close (fd); - free_public_key( pk ); -#ifdef ENABLE_NLS - if (orig_codeset) - bind_textdomain_codeset (PACKAGE_GT, orig_codeset); -#endif - xfree (orig_codeset); - return pw; - } - else if ( reply == GPGA_PROT_CANCELED ) - { - log_info ( _("cancelled by user\n") ); - if (canceled) - *canceled = 1; - } - else - log_error ( _("problem with the agent: agent returns 0x%lx\n"), - (ulong)reply ); - } - else - { /* The new Assuan protocol */ - char *line, *p; - const unsigned char *s; - int i; - - if (!tryagain_text) - tryagain_text = "X"; - else - tryagain_text = _(tryagain_text); - - /* We allocate 2 time the needed space for atext so that there - is enough space for escaping */ - line = xmalloc (15 + 46 - + 3*strlen (tryagain_text) + 3*strlen (atext) + 2); - strcpy (line, "GET_PASSPHRASE "); - p = line+15; - if (!mode && have_fpr) - { - for (i=0; i < 20; i++, p +=2 ) - sprintf (p, "%02X", fpr[i]); - } - else - *p++ = 'X'; /* no caching */ - *p++ = ' '; - for (i=0, s=tryagain_text; *s; s++) - { - if (*s < ' ' || *s == '+') - { - sprintf (p, "%%%02X", *s); - p += 3; - } - else if (*s == ' ') - *p++ = '+'; - else - *p++ = *s; - } - *p++ = ' '; - *p++ = 'X'; /* Use the standard prompt */ - *p++ = ' '; - /* copy description */ - for (i=0, s= atext; *s; s++) - { - if (*s < ' ' || *s == '+') - { - sprintf (p, "%%%02X", *s); - p += 3; - } - else if (*s == ' ') - *p++ = '+'; - else - *p++ = *s; - } - *p++ = '\n'; - i = writen (fd, line, p - line); - xfree (line); - if (i) - goto failure; - xfree (atext); atext = NULL; - - /* get response */ - pw = xmalloc_secure (500); - nread = readline (fd, pw, 499); - if (nread < 3) - goto failure; - - if (pw[0] == 'O' && pw[1] == 'K' && pw[2] == ' ') - { /* we got a passphrase - convert it back from hex */ - size_t pwlen = 0; - - for (i=3; i < nread && hexdigitp (pw+i); i+=2) - pw[pwlen++] = xtoi_2 (pw+i); - pw[pwlen] = 0; /* make a C String */ - agent_close (fd); - free_public_key( pk ); -#ifdef ENABLE_NLS - if (orig_codeset) - bind_textdomain_codeset (PACKAGE_GT, orig_codeset); -#endif - xfree (orig_codeset); - return pw; - } - else if (nread > 7 && !memcmp (pw, "ERR 111", 7) - && (pw[7] == ' ' || pw[7] == '\n') ) - { - log_info (_("cancelled by user\n") ); - if (canceled) - *canceled = 1; - } - else - { - log_error (_("problem with the agent - disabling agent use\n")); - opt.use_agent = 0; - } - } - - - failure: -#ifdef ENABLE_NLS - if (orig_codeset) - bind_textdomain_codeset (PACKAGE_GT, orig_codeset); -#endif - xfree (atext); - if ( fd != -1 ) - agent_close (fd); - xfree (pw ); - free_public_key( pk ); - - return NULL; -#endif /* Posix or W32 */ -} - -/* - * Clear the cached passphrase - */ -void -passphrase_clear_cache ( u32 *keyid, int algo ) -{ -#if defined(__riscos__) - return ; -#else - size_t n; - char buf[200]; - int fd = -1; - size_t nread; - u32 reply; - PKT_public_key *pk; - byte fpr[MAX_FINGERPRINT_LEN]; - int prot; - -#if MAX_FINGERPRINT_LEN < 20 -#error agent needs a 20 byte fingerprint -#endif - - if (!opt.use_agent) - return; - - pk = xcalloc (1, sizeof *pk ); - memset (fpr, 0, MAX_FINGERPRINT_LEN ); - if( !keyid || get_pubkey( pk, keyid ) ) - { - log_debug ("oops, no key in passphrase_clear_cache\n"); - goto failure; /* oops: no key for some reason */ - } - - { - size_t dummy; - fingerprint_from_pk( pk, fpr, &dummy ); - } - - if ( (fd = agent_open (&prot)) == -1 ) - goto failure; - - if (!prot) - { - n = 4 + 20; - u32tobuf (buf, n ); - u32tobuf (buf+4, GPGA_PROT_CLEAR_PASSPHRASE ); - memcpy (buf+8, fpr, 20 ); - if ( writen ( fd, buf, 28 ) ) - goto failure; - - /* get response */ - if ( readn ( fd, buf, 8, &nread ) ) - goto failure; - - if ( nread < 8 ) { - log_error ( "response from agent too short\n" ); - goto failure; - } - - reply = buftou32 ( buf + 4 ); - if ( reply != GPGA_PROT_OKAY && reply != GPGA_PROT_NO_PASSPHRASE ) - { - log_error ( _("problem with the agent: agent returns 0x%lx\n"), - (ulong)reply ); - } - } - else - { /* The assuan protocol */ - char *line, *p; - int i; - - line = xmalloc (17 + 40 + 2); - strcpy (line, "CLEAR_PASSPHRASE "); - p = line+17; - for (i=0; i < 20; i++, p +=2 ) - sprintf (p, "%02X", fpr[i]); - *p++ = '\n'; - i = writen (fd, line, p - line); - xfree (line); - if (i) - goto failure; - - /* get response */ - nread = readline (fd, buf, DIM(buf)-1); - if (nread < 3) - goto failure; - - if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n')) - ; - else - { - log_error (_("problem with the agent - disabling agent use\n")); - opt.use_agent = 0; - } - } - - failure: - if (fd != -1) - agent_close (fd); - free_public_key( pk ); -#endif /* Posix or W32 */ -} - - - - -/**************** - * Get a passphrase for the secret key with KEYID, display TEXT - * if the user needs to enter the passphrase. - * mode 0 = standard, 1 = same but don't show key info, - * 2 = create new passphrase - * Returns: a DEK with a session key; caller must free - * or NULL if the passphrase was not correctly repeated. - * (only for mode 2) - * a dek->keylen of 0 means: no passphrase entered. - * (only for mode 2) - * - * pubkey_algo is only informational. Note that TRYAGAIN_TEXT must - * not be translated as this is done within this function (required to - * switch to utf-8 when the agent is in use). If CANCELED is not - * NULL, it is set to 1 if the user choosed to cancel the operation, - * otherwise it will be set to 0. - */ -DEK * -passphrase_to_dek( u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, - const char *tryagain_text, int *canceled) -{ - char *pw = NULL; - DEK *dek; - STRING2KEY help_s2k; - - if (canceled) - *canceled = 0; - - if( !s2k ) { - /* This is used for the old rfc1991 mode - * Note: This must match the code in encode.c with opt.rfc1991 set */ - s2k = &help_s2k; - s2k->mode = 0; - s2k->hash_algo = opt.s2k_digest_algo; - } - - if( !next_pw && is_status_enabled() ) { - char buf[50]; - - if( keyid ) { - u32 used_kid[2]; - char *us; - - if( keyid[2] && keyid[3] ) { - used_kid[0] = keyid[2]; - used_kid[1] = keyid[3]; - } - else { - used_kid[0] = keyid[0]; - used_kid[1] = keyid[1]; - } - - us = get_long_user_id_string( keyid ); - write_status_text( STATUS_USERID_HINT, us ); - xfree (us); - - sprintf( buf, "%08lX%08lX %08lX%08lX %d 0", - (ulong)keyid[0], (ulong)keyid[1], - (ulong)used_kid[0], (ulong)used_kid[1], - pubkey_algo ); - - write_status_text( STATUS_NEED_PASSPHRASE, buf ); - } - else { - sprintf( buf, "%d %d %d", cipher_algo, s2k->mode, s2k->hash_algo ); - write_status_text( STATUS_NEED_PASSPHRASE_SYM, buf ); - } - } - - if( keyid && !opt.batch && !next_pw && mode!=1 ) { - PKT_public_key *pk = xcalloc (1, sizeof *pk ); - size_t n; - char *p; - - tty_printf(_("\nYou need a passphrase to unlock the secret key for\n" - "user: \"") ); - p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ); - xfree (p); - tty_printf("\"\n"); - - if( !get_pubkey( pk, keyid ) ) { - const char *s = gcry_pk_algo_name ( pk->pubkey_algo ); - tty_printf( _("%u-bit %s key, ID %08lX, created %s"), - nbits_from_pk( pk ), s?s:"?", (ulong)keyid[1], - strtimestamp(pk->timestamp) ); - if( keyid[2] && keyid[3] && keyid[0] != keyid[2] - && keyid[1] != keyid[3] ) - tty_printf( _(" (main key ID %08lX)"), (ulong)keyid[3] ); - tty_printf("\n"); - } - - tty_printf("\n"); - free_public_key( pk ); - } - - agent_died: - if( next_pw ) { - pw = next_pw; - next_pw = NULL; - } - else if ( opt.use_agent ) { - pw = agent_get_passphrase ( keyid, mode == 2? 1: 0, - tryagain_text, canceled ); - if (!pw) - { - if (!opt.use_agent) - goto agent_died; - pw = xstrdup (""); - } - if( *pw && mode == 2 ) { - char *pw2 = agent_get_passphrase ( keyid, 2, NULL, canceled ); - if (!pw2) - { - if (!opt.use_agent) - { - xfree (pw); - pw = NULL; - goto agent_died; - } - pw2 = xstrdup (""); - } - if( strcmp(pw, pw2) ) { - xfree (pw2); - xfree (pw); - return NULL; - } - xfree (pw2); - } - } - else if( fd_passwd ) { - pw = xmalloc_secure ( strlen(fd_passwd)+1 ); - strcpy( pw, fd_passwd ); - } - else if( opt.batch ) { - log_error(_("can't query password in batchmode\n")); - pw = xstrdup ( "" ); /* return an empty passphrase */ - } - else { - pw = cpr_get_hidden("passphrase.enter", _("Enter passphrase: ") ); - tty_kill_prompt(); - if( mode == 2 && !cpr_enabled() ) { - char *pw2 = cpr_get_hidden("passphrase.repeat", - _("Repeat passphrase: ") ); - tty_kill_prompt(); - if( strcmp(pw, pw2) ) { - xfree (pw2); - xfree (pw); - return NULL; - } - xfree (pw2); - } - } - - if( !pw || !*pw ) - write_status( STATUS_MISSING_PASSPHRASE ); - - dek = xcalloc_secure (1, sizeof *dek ); - dek->algo = cipher_algo; - if( !*pw && mode == 2 ) - dek->keylen = 0; - else - hash_passphrase( dek, pw, s2k, mode==2 ); - xfree (last_pw); - last_pw = pw; - return dek; -} - - -/**************** - * Hash a passphrase using the supplied s2k. If create is true, create - * a new salt or what else must be filled into the s2k for a new key. - * always needs: dek->algo, s2k->mode, s2k->hash_algo. - */ -static void -hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ) -{ - MD_HANDLE md; - int pass, i; - int used = 0; - int pwlen = strlen(pw); - - assert( s2k->hash_algo ); - dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); - if( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) ) - BUG(); - - gcry_md_open (&md, s2k->hash_algo, 1); - for(pass=0; used < dek->keylen ; pass++ ) { - if( pass ) { - gcry_md_reset(md); - for(i=0; i < pass; i++ ) /* preset the hash context */ - gcry_md_putc (md, 0 ); - } - - if( s2k->mode == 1 || s2k->mode == 3 ) { - int len2 = pwlen + 8; - ulong count = len2; - - if( create && !pass ) { - gcry_randomize(s2k->salt, 8, GCRY_STRONG_RANDOM ); - if( s2k->mode == 3 ) - s2k->count = 96; /* 65536 iterations */ - } - - if( s2k->mode == 3 ) { - count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6); - if( count < len2 ) - count = len2; - } - /* a little bit complicated because we need a ulong for count */ - while( count > len2 ) { /* maybe iterated+salted */ - gcry_md_write( md, s2k->salt, 8 ); - gcry_md_write( md, pw, pwlen ); - count -= len2; - } - if( count < 8 ) - gcry_md_write( md, s2k->salt, count ); - else { - gcry_md_write( md, s2k->salt, 8 ); - count -= 8; - gcry_md_write( md, pw, count ); - } - } - else - gcry_md_write( md, pw, pwlen ); - gcry_md_final ( md ); - i = gcry_md_get_algo_dlen (s2k->hash_algo); - if( i > dek->keylen - used ) - i = dek->keylen - used; - memcpy( dek->key+used, gcry_md_read (md, s2k->hash_algo), i ); - used += i; - } - gcry_md_close (md); -} - diff --git a/g10/photoid.c b/g10/photoid.c deleted file mode 100644 index 00cc7a273..000000000 --- a/g10/photoid.c +++ /dev/null @@ -1,333 +0,0 @@ -/* photoid.c - photo ID handling code - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#ifdef _WIN32 -# include <windows.h> -# ifndef VER_PLATFORM_WIN32_WINDOWS -# define VER_PLATFORM_WIN32_WINDOWS 1 -# endif -#endif -#include "packet.h" -#include "status.h" -#include "exec.h" -#include "keydb.h" -#include "util.h" -#include "i18n.h" -#include "iobuf.h" -#include "memory.h" -#include "options.h" -#include "main.h" -#include "photoid.h" - -/* Generate a new photo id packet, or return NULL if canceled */ -PKT_user_id *generate_photo_id(PKT_public_key *pk) -{ - PKT_user_id *uid; - int error=1,i; - unsigned int len; - char *filename=NULL; - byte *photo=NULL; - byte header[16]; - iobuf_t file; - - header[0]=0x10; /* little side of photo header length */ - header[1]=0; /* big side of photo header length */ - header[2]=1; /* 1 == version of photo header */ - header[3]=1; /* 1 == JPEG */ - - for(i=4;i<16;i++) /* The reserved bytes */ - header[i]=0; - -#define EXTRA_UID_NAME_SPACE 71 - uid=xcalloc (1,sizeof(*uid)+71); - - printf(_("\nPick an image to use for your photo ID. " - "The image must be a JPEG file.\n" - "Remember that the image is stored within your public key. " - "If you use a\n" - "very large picture, your key will become very large as well!\n" - "Keeping the image close to 240x288 is a good size to use.\n")); - - while(photo==NULL) - { - printf("\n"); - - xfree (filename); - - filename=cpr_get("photoid.jpeg.add", - _("Enter JPEG filename for photo ID: ")); - - if(strlen(filename)==0) - goto scram; - - file=iobuf_open(filename); - if(!file) - { - log_error(_("Unable to open photo \"%s\": %s\n"), - filename,strerror(errno)); - continue; - } - - len=iobuf_get_filelength(file); - if(len>6144) - { - printf("This JPEG is really large (%d bytes) !\n",len); - if(!cpr_get_answer_is_yes("photoid.jpeg.size", - _("Are you sure you want to use it (y/N)? "))) - { - iobuf_close(file); - continue; - } - } - - photo=xmalloc (len); - iobuf_read(file,photo,len); - iobuf_close(file); - - /* Is it a JPEG? */ - if(photo[0]!=0xFF || photo[1]!=0xD8 || - photo[6]!='J' || photo[7]!='F' || photo[8]!='I' || photo[9]!='F') - { - log_error(_("\"%s\" is not a JPEG file\n"),filename); - xfree (photo); - photo=NULL; - continue; - } - - /* Build the packet */ - build_attribute_subpkt(uid,1,photo,len,header,16); - parse_attribute_subpkts(uid); - make_attribute_uidname(uid, EXTRA_UID_NAME_SPACE); - - /* Showing the photo is not safe when noninteractive since the - "user" may not be able to dismiss a viewer window! */ - if(opt.command_fd==-1) - { - show_photos(uid->attribs,uid->numattribs,pk,NULL); - switch(cpr_get_answer_yes_no_quit("photoid.jpeg.okay", - _("Is this photo correct (y/N/q)? "))) - { - case -1: - goto scram; - case 0: - free_attributes(uid); - xfree (photo); - photo=NULL; - continue; - } - } - } - - error=0; - uid->ref=1; - - scram: - xfree (filename); - xfree (photo); - - if(error) - { - free_attributes(uid); - xfree (uid); - return NULL; - } - - return uid; -} - -/* Returns 0 for error, 1 for valid */ -int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len) -{ - u16 headerlen; - - if(attr->len<3) - return 0; - - /* For historical reasons (i.e. "oops!"), the header length is - little endian. */ - headerlen=(attr->data[1]<<8) | attr->data[0]; - - if(headerlen>attr->len) - return 0; - - if(type && attr->len>=4) - { - if(attr->data[2]==1) /* header version 1 */ - *type=attr->data[3]; - else - *type=0; - } - - *len=attr->len-headerlen; - - if(*len==0) - return 0; - - return 1; -} - -/* style==0 for extension, 1 for name, 2 for MIME type. Remember that - the "name" style string could be used in a user ID name field, so - make sure it is not too big (see parse-packet.c:parse_attribute). - Extensions should be 3 characters long for the best cross-platform - compatibility. */ -char *image_type_to_string(byte type,int style) -{ - char *string; - - switch(type) - { - case 1: /* jpeg */ - if(style==0) - string="jpg"; - else if(style==1) - string="jpeg"; - else - string="image/jpeg"; - break; - - default: - if(style==0) - string="bin"; - else if(style==1) - string="unknown"; - else - string="image/x-unknown"; - break; - } - - return string; -} - -#if !defined(FIXED_PHOTO_VIEWER) && !defined(DISABLE_PHOTO_VIEWER) -static const char *get_default_photo_command(void) -{ -#if defined(_WIN32) - OSVERSIONINFO osvi; - - memset(&osvi,0,sizeof(osvi)); - osvi.dwOSVersionInfoSize=sizeof(osvi); - GetVersionEx(&osvi); - - if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) - return "start /w %i"; - else - return "cmd /c start /w %i"; -#elif defined(__APPLE__) - /* OS X. This really needs more than just __APPLE__. */ - return "open %I"; -#elif defined(__riscos__) - return "Filer_Run %I"; -#else - return "xloadimage -fork -quiet -title 'KeyID 0x%k' stdin"; -#endif -} -#endif - -void show_photos(const struct user_attribute *attrs, - int count,PKT_public_key *pk,PKT_secret_key *sk) -{ -#ifndef DISABLE_PHOTO_VIEWER - int i; - struct expando_args args; - u32 len; - u32 kid[2]={0,0}; - - memset(&args,0,sizeof(args)); - args.pk=pk; - args.sk=sk; - - if(pk) - keyid_from_pk(pk,kid); - else if(sk) - keyid_from_sk(sk,kid); - - for(i=0;i<count;i++) - if(attrs[i].type==ATTRIB_IMAGE && - parse_image_header(&attrs[i],&args.imagetype,&len)) - { - char *command,*name; - struct exec_info *spawn; - int offset=attrs[i].len-len; - -#ifdef FIXED_PHOTO_VIEWER - opt.photo_viewer=FIXED_PHOTO_VIEWER; -#else - if(!opt.photo_viewer) - opt.photo_viewer=get_default_photo_command(); -#endif - - /* make command grow */ - command=pct_expando(opt.photo_viewer,&args); - if(!command) - goto fail; - - name=xmalloc (16+strlen(EXTSEP_S)+ - strlen(image_type_to_string(args.imagetype,0))+1); - - /* Make the filename. Notice we are not using the image - encoding type for more than cosmetics. Most external image - viewers can handle a multitude of types, and even if one - cannot understand a particular type, we have no way to know - which. The spec permits this, by the way. -dms */ - -#ifdef USE_ONLY_8DOT3 - sprintf(name,"%08lX" EXTSEP_S "%s",(ulong)kid[1], - image_type_to_string(args.imagetype,0)); -#else - sprintf(name,"%08lX%08lX" EXTSEP_S "%s",(ulong)kid[0],(ulong)kid[1], - image_type_to_string(args.imagetype,0)); -#endif - - if(exec_write(&spawn,NULL,command,name,1,1)!=0) - { - xfree (name); - goto fail; - } - -#ifdef __riscos__ - riscos_set_filetype_by_mimetype(spawn->tempfile_in, - image_type_to_string(args.imagetype,2)); -#endif - - xfree (name); - - fwrite(&attrs[i].data[offset],attrs[i].len-offset,1,spawn->tochild); - - if(exec_read(spawn)!=0) - { - exec_finish(spawn); - goto fail; - } - - if(exec_finish(spawn)!=0) - goto fail; - } - - return; - - fail: - log_error(_("unable to display photo ID!\n")); -#endif -} diff --git a/g10/photoid.h b/g10/photoid.h deleted file mode 100644 index 187ca5ba2..000000000 --- a/g10/photoid.h +++ /dev/null @@ -1,34 +0,0 @@ -/* photoid.h - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* Photo ID functions */ - -#ifndef _PHOTOID_H_ -#define _PHOTOID_H_ - -#include "packet.h" - -PKT_user_id *generate_photo_id(PKT_public_key *pk); -int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len); -char *image_type_to_string(byte type,int style); -void show_photos(const struct user_attribute *attrs, - int count,PKT_public_key *pk,PKT_secret_key *sk); - -#endif /* !_PHOTOID_H_ */ diff --git a/g10/pipemode.c b/g10/pipemode.c deleted file mode 100644 index 9f2ddfdb5..000000000 --- a/g10/pipemode.c +++ /dev/null @@ -1,317 +0,0 @@ -/* pipemode.c - pipemode handler - * Copyright (C) 1998, 1990, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "status.h" -#include "filter.h" - - -#define CONTROL_PACKET_SPACE 30 -#define FAKED_LITERAL_PACKET_SPACE (9+2+2) - - -enum pipemode_state_e { - STX_init = 0, - STX_wait_operation, - STX_begin, - STX_text, - STX_detached_signature, - STX_detached_signature_wait_text, - STX_signed_data, - STX_wait_init -}; - -struct pipemode_context_s { - enum pipemode_state_e state; - int operation; - int stop; - int block_mode; - UnarmorPump unarmor_ctx; -}; - - -static size_t -make_control ( byte *buf, int code, int operation ) -{ - const byte *sesmark; - size_t sesmarklen, n=0;; - - sesmark = get_session_marker( &sesmarklen ); - if ( sesmarklen > 20 ) - BUG(); - - buf[n++] = 0xff; /* new format, type 63, 1 length byte */ - n++; /* length will fixed below */ - memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen; - buf[n++] = CTRLPKT_PIPEMODE; - buf[n++] = code; - buf[n++] = operation; - buf[1] = n-2; - return n; -} - - - -static int -pipemode_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - struct pipemode_context_s *stx = opaque; - int rc=0; - size_t n = 0; - int esc = 0; - - if( control == IOBUFCTRL_UNDERFLOW ) { - *ret_len = 0; - /* reserve some space for one control packet */ - if ( size <= CONTROL_PACKET_SPACE+FAKED_LITERAL_PACKET_SPACE ) - BUG(); - size -= CONTROL_PACKET_SPACE+FAKED_LITERAL_PACKET_SPACE; - - if ( stx->block_mode ) { - /* reserve 2 bytes for the block length */ - buf[n++] = 0; - buf[n++] = 0; - } - - - while ( n < size ) { - /* FIXME: we have to make sure that we have a large enough - * buffer for a control packet even after we already read - * something. The easest way to do this is probably by ungetting - * the control sequence and returning the buffer we have - * already assembled */ - int c = iobuf_get (a); - if (c == -1) { - if ( stx->state != STX_init ) { - log_error ("EOF encountered at wrong state\n"); - stx->stop = 1; - return -1; - } - break; - } - if ( esc ) { - switch (c) { - case '@': - if ( stx->state == STX_text ) { - buf[n++] = c; - break; - } - else if ( stx->state == STX_detached_signature ) { - esc = 0; - goto do_unarmor; /* not a very elegant solution */ - } - else if ( stx->state == STX_detached_signature_wait_text) { - esc = 0; - break; /* just ignore it in this state */ - } - log_error ("@@ not allowed in current state\n"); - return -1; - case '<': /* begin of stream part */ - if ( stx->state != STX_init ) { - log_error ("nested begin of stream\n"); - stx->stop = 1; - return -1; - } - stx->state = STX_wait_operation; - stx->block_mode = 0; - unarmor_pump_release (stx->unarmor_ctx); - stx->unarmor_ctx = NULL; - break; - case '>': /* end of stream part */ - if ( stx->state != STX_wait_init ) { - log_error ("invalid state for @>\n"); - stx->stop = 1; - return -1; - } - stx->state = STX_init; - break; - case 'V': /* operation = verify */ - case 'E': /* operation = encrypt */ - case 'S': /* operation = sign */ - case 'B': /* operation = detach sign */ - case 'C': /* operation = clearsign */ - case 'D': /* operation = decrypt */ - if ( stx->state != STX_wait_operation ) { - log_error ("invalid state for operation code\n"); - stx->stop = 1; - return -1; - } - stx->operation = c; - if ( stx->operation == 'B') { - stx->state = STX_detached_signature; - if ( !opt.no_armor ) - stx->unarmor_ctx = unarmor_pump_new (); - } - else - stx->state = STX_begin; - n += make_control ( buf+n, 1, stx->operation ); - /* must leave after a control packet */ - goto leave; - - case 't': /* plaintext text follows */ - if ( stx->state == STX_detached_signature_wait_text ) - stx->state = STX_detached_signature; - if ( stx->state == STX_detached_signature ) { - if ( stx->operation != 'B' ) { - log_error ("invalid operation for this state\n"); - stx->stop = 1; - return -1; - } - stx->state = STX_signed_data; - n += make_control ( buf+n, 2, 'B' ); - /* and now we fake a literal data packet much the same - * as in armor.c */ - buf[n++] = 0xaf; /* old packet format, type 11, - var length */ - buf[n++] = 0; /* set the length header */ - buf[n++] = 6; - buf[n++] = 'b'; /* we ignore it anyway */ - buf[n++] = 0; /* namelength */ - memset(buf+n, 0, 4); /* timestamp */ - n += 4; - /* and return now so that we are sure to have - * more space in the bufer for the next control - * packet */ - stx->block_mode = 1; - goto leave2; - } - else { - log_error ("invalid state for @t\n"); - stx->stop = 1; - return -1; - } - break; - - case '.': /* ready */ - if ( stx->state == STX_signed_data ) { - if (stx->block_mode) { - buf[0] = (n-2) >> 8; - buf[1] = (n-2); - if ( buf[0] || buf[1] ) { - /* end of blocks marker */ - buf[n++] = 0; - buf[n++] = 0; - } - stx->block_mode = 0; - } - n += make_control ( buf+n, 3, 'B' ); - } - else { - log_error ("invalid state for @.\n"); - stx->stop = 1; - return -1; - } - stx->state = STX_wait_init; - goto leave; - - default: - log_error ("invalid escape sequence 0x%02x in stream\n", - c); - stx->stop = 1; - return -1; - } - esc = 0; - } - else if (c == '@') - esc = 1; - else if (stx->unarmor_ctx) { - do_unarmor: /* used to handle a @@ */ - c = unarmor_pump (stx->unarmor_ctx, c); - if ( !(c & ~255) ) - buf[n++] = c; - else if ( c < 0 ) { - /* end of armor or error - we don't care becuase - the armor can be modified anyway. The unarmored - stuff should stand for itself. */ - unarmor_pump_release (stx->unarmor_ctx); - stx->unarmor_ctx = NULL; - stx->state = STX_detached_signature_wait_text; - } - } - else if (stx->state == STX_detached_signature_wait_text) - ; /* just wait */ - else - buf[n++] = c; - } - - leave: - if ( !n ) { - stx->stop = 1; - rc = -1; /* eof */ - } - if ( stx->block_mode ) { - /* fixup the block length */ - buf[0] = (n-2) >> 8; - buf[1] = (n-2); - } - leave2: - /*log_hexdump ("pipemode:", buf, n );*/ - *ret_len = n; - } - else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "pipemode_filter"; - return rc; -} - - - -void -run_in_pipemode(void) -{ - iobuf_t fp; - armor_filter_context_t afx; - struct pipemode_context_s stx; - int rc; - - memset( &afx, 0, sizeof afx); - memset( &stx, 0, sizeof stx); - - fp = iobuf_open("-"); - iobuf_push_filter (fp, pipemode_filter, &stx ); - - do { - write_status (STATUS_BEGIN_STREAM); - rc = proc_packets( NULL, fp ); - write_status (STATUS_END_STREAM); - } while ( !stx.stop ); - -} - - - - - - diff --git a/g10/pkclist.c b/g10/pkclist.c deleted file mode 100644 index 71e6492e8..000000000 --- a/g10/pkclist.c +++ /dev/null @@ -1,1372 +0,0 @@ -/* pkclist.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002 - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "trustdb.h" -#include "ttyio.h" -#include "status.h" -#include "photoid.h" -#include "i18n.h" - - -#define CONTROL_D ('D' - 'A' + 1) - - -/**************** - * Show the revocation reason as it is stored with the given signature - */ -static void -do_show_revocation_reason( PKT_signature *sig ) -{ - size_t n, nn; - const byte *p, *pp; - int seq = 0; - const char *text; - - while( (p = enum_sig_subpkt (sig->hashed, SIGSUBPKT_REVOC_REASON, - &n, &seq, NULL )) ) { - if( !n ) - continue; /* invalid - just skip it */ - - if( *p == 0 ) - text = _("No reason specified"); - else if( *p == 0x01 ) - text = _("Key is superseded"); - else if( *p == 0x02 ) - text = _("Key has been compromised"); - else if( *p == 0x03 ) - text = _("Key is no longer used"); - else if( *p == 0x20 ) - text = _("User ID is no longer valid"); - else - text = NULL; - - log_info( _("reason for revocation: ") ); - if( text ) - fputs( text, log_get_stream () ); - else - fprintf( log_get_stream (), "code=%02x", *p ); - putc( '\n', log_get_stream () ); - n--; p++; - pp = NULL; - do { - /* We don't want any empty lines, so skip them */ - while( n && *p == '\n' ) { - p++; - n--; - } - if( n ) { - pp = memchr( p, '\n', n ); - nn = pp? pp - p : n; - log_info( _("revocation comment: ") ); - print_string( log_get_stream(), p, nn, 0 ); - putc( '\n', log_get_stream() ); - p += nn; n -= nn; - } - } while( pp ); - } -} - -/* Mode 0: try and find the revocation based on the pk (i.e. check - subkeys, etc.) Mode 1: use only the revocation on the main pk */ - -void -show_revocation_reason( PKT_public_key *pk, int mode ) -{ - /* Hmmm, this is not so easy becuase we have to duplicate the code - * used in the trustbd to calculate the keyflags. We need to find - * a clean way to check revocation certificates on keys and - * signatures. And there should be no duplicate code. Because we - * enter this function only when the trustdb told us that we have - * a revoked key, we could simply look for a revocation cert and - * display this one, when there is only one. Let's try to do this - * until we have a better solution. */ - KBNODE node, keyblock = NULL; - byte fingerprint[MAX_FINGERPRINT_LEN]; - size_t fingerlen; - int rc; - - /* get the keyblock */ - fingerprint_from_pk( pk, fingerprint, &fingerlen ); - rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen ); - if( rc ) { /* that should never happen */ - log_debug( "failed to get the keyblock\n"); - return; - } - - for( node=keyblock; node; node = node->next ) { - if( (mode && node->pkt->pkttype == PKT_PUBLIC_KEY) || - ( ( node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - && !cmp_public_keys( node->pkt->pkt.public_key, pk ) ) ) - break; - } - if( !node ) { - log_debug("Oops, PK not in keyblock\n"); - release_kbnode( keyblock ); - return; - } - /* now find the revocation certificate */ - for( node = node->next; node ; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - break; - if( node->pkt->pkttype == PKT_SIGNATURE - && (node->pkt->pkt.signature->sig_class == 0x20 - || node->pkt->pkt.signature->sig_class == 0x28 ) ) { - /* FIXME: we should check the signature here */ - do_show_revocation_reason ( node->pkt->pkt.signature ); - break; - } - } - - /* We didn't find it, so check if the whole key is revoked */ - if(!node && !mode) - show_revocation_reason(pk,1); - - release_kbnode( keyblock ); -} - - -static void -show_paths (const PKT_public_key *pk, int only_first ) -{ - log_debug("not yet implemented\n"); -#if 0 - void *context = NULL; - unsigned otrust, validity; - int last_level, level; - - last_level = 0; - while( (level=enum_cert_paths( &context, &lid, &otrust, &validity)) != -1){ - char *p; - int c, rc; - size_t n; - u32 keyid[2]; - PKT_public_key *pk ; - - if( level < last_level && only_first ) - break; - last_level = level; - - rc = keyid_from_lid( lid, keyid ); - - if( rc ) { - log_error("ooops: can't get keyid for lid %lu\n", lid); - return; - } - - pk = xcalloc (1, sizeof *pk ); - rc = get_pubkey( pk, keyid ); - if( rc ) { - log_error("key %08lX: public key not found: %s\n", - (ulong)keyid[1], gpg_strerror (rc) ); - return; - } - - tty_printf("%*s%4u%c/%08lX.%lu %s \"", - level*2, "", - nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), - (ulong)keyid[1], lid, datestr_from_pk( pk ) ); - - c = trust_letter(otrust); - if( c ) - putchar( c ); - else - printf( "%02x", otrust ); - putchar('/'); - c = trust_letter(validity); - if( c ) - putchar( c ); - else - printf( "%02x", validity ); - putchar(' '); - - p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ), - xfree (p); - tty_printf("\"\n"); - free_public_key( pk ); - } - enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */ -#endif - tty_printf("\n"); -} - - - - -/**************** - * mode: 0 = standard - * 1 = Without key info and additional menu option 'm' - * this does also add an option to set the key to ultimately trusted. - * Returns: - * -2 = nothing changed - caller should show some additional info - * -1 = quit operation - * 0 = nothing changed - * 1 = new ownertrust now in new_trust - */ -static int -do_edit_ownertrust (PKT_public_key *pk, int mode, - unsigned *new_trust, int defer_help ) -{ - char *p; - size_t n; - u32 keyid[2]; - int changed=0; - int quit=0; - int show=0; - int min_num; - int did_help=defer_help; - unsigned int minimum=get_min_ownertrust(pk); - - switch(minimum) - { - default: min_num=0; break; - case TRUST_UNDEFINED: min_num=1; break; - case TRUST_NEVER: min_num=2; break; - case TRUST_MARGINAL: min_num=3; break; - case TRUST_FULLY: min_num=4; break; - } - - keyid_from_pk (pk, keyid); - for(;;) { - /* a string with valid answers */ - const char *ans = _("iImMqQsS"); - - if( !did_help ) - { - if( !mode ) - { - KBNODE keyblock, un; - - tty_printf(_("No trust value assigned to:\n" - "%4u%c/%08lX %s \""), - nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), - (ulong)keyid[1], datestr_from_pk( pk ) ); - p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ), - xfree (p); - tty_printf("\"\n"); - - keyblock = get_pubkeyblock (keyid); - if (!keyblock) - BUG (); - for (un=keyblock; un; un = un->next) { - if (un->pkt->pkttype != PKT_USER_ID ) - continue; - if (un->pkt->pkt.user_id->is_revoked ) - continue; - if (un->pkt->pkt.user_id->is_expired ) - continue; - /* Only skip textual primaries */ - if (un->pkt->pkt.user_id->is_primary && - !un->pkt->pkt.user_id->attrib_data ) - continue; - - if((opt.verify_options&VERIFY_SHOW_PHOTOS) - && un->pkt->pkt.user_id->attrib_data) - show_photos(un->pkt->pkt.user_id->attribs, - un->pkt->pkt.user_id->numattribs,pk,NULL); - - tty_printf (" %s", _(" aka \"")); - tty_print_utf8_string (un->pkt->pkt.user_id->name, - un->pkt->pkt.user_id->len ); - tty_printf("\"\n"); - } - - print_fingerprint (pk, NULL, 2); - tty_printf("\n"); - } - /* This string also used in keyedit.c:sign_uids */ - 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")); - if(min_num<=1) - tty_printf (_(" %d = I don't know\n"), 1); - if(min_num<=2) - tty_printf (_(" %d = I do NOT trust\n"), 2); - if(min_num<=3) - tty_printf (_(" %d = I trust marginally\n"), 3); - if(min_num<=4) - tty_printf (_(" %d = I trust fully\n"), 4); - if (mode) - tty_printf (_(" %d = I trust ultimately\n"), 5); -#if 0 - /* not yet implemented */ - tty_printf (_(" i = please show me more information\n") ); -#endif - if( mode ) - tty_printf(_(" m = back to the main menu\n")); - else - { - tty_printf(_(" s = skip this key\n")); - tty_printf(_(" q = quit\n")); - } - tty_printf("\n"); - if(minimum) - tty_printf(_("The minimum trust level for this key is: %s\n\n"), - trust_value_to_string(minimum)); - did_help = 1; - } - if( strlen(ans) != 8 ) - BUG(); - p = cpr_get("edit_ownertrust.value",_("Your decision? ")); - trim_spaces(p); - cpr_kill_prompt(); - if( !*p ) - did_help = 0; - else if( *p && p[1] ) - ; - else if( !p[1] && ((*p >= '0'+min_num) && *p <= (mode?'5':'4')) ) - { - unsigned int trust; - switch( *p ) - { - case '1': trust = TRUST_UNDEFINED; break; - case '2': trust = TRUST_NEVER ; break; - case '3': trust = TRUST_MARGINAL ; break; - case '4': trust = TRUST_FULLY ; break; - case '5': trust = TRUST_ULTIMATE ; break; - default: BUG(); - } - if (trust == TRUST_ULTIMATE - && !cpr_get_answer_is_yes ("edit_ownertrust.set_ultimate.okay", - _("Do you really want to set this key" - " to ultimate trust? "))) - ; /* no */ - else - { - *new_trust = trust; - changed = 1; - break; - } - } -#if 0 - /* not yet implemented */ - else if( *p == ans[0] || *p == ans[1] ) - { - tty_printf(_("Certificates leading to an ultimately trusted key:\n")); - show = 1; - break; - } -#endif - else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) - { - break ; /* back to the menu */ - } - else if( !mode && (*p == ans[6] || *p == ans[7] ) ) - { - break; /* skip */ - } - else if( !mode && (*p == ans[4] || *p == ans[5] ) ) - { - quit = 1; - break ; /* back to the menu */ - } - xfree (p); p = NULL; - } - xfree (p); - return show? -2: quit? -1 : changed; -} - -/* - * Display a menu to change the ownertrust of the key PK (which should - * be a primary key). - * For mode values see do_edit_ownertrust () - */ -int -edit_ownertrust (PKT_public_key *pk, int mode ) -{ - unsigned int trust; - int no_help = 0; - - for(;;) - { - switch ( do_edit_ownertrust (pk, mode, &trust, no_help ) ) - { - case -1: /* quit */ - return -1; - case -2: /* show info */ - show_paths(pk, 1); - no_help = 1; - break; - case 1: /* trust value set */ - trust &= ~TRUST_FLAG_DISABLED; - trust |= get_ownertrust (pk) & TRUST_FLAG_DISABLED; - update_ownertrust (pk, trust ); - return 1; - default: - return 0; - } - } -} - - -/**************** - * Check whether we can trust this pk which has a trustlevel of TRUSTLEVEL - * Returns: true if we trust. - */ -static int -do_we_trust( PKT_public_key *pk, unsigned int *trustlevel ) -{ - unsigned int trustmask = 0; - - /* FIXME: get_pubkey_byname already checks the validity and won't - * return keys which are either expired or revoked - so these - * question here won't get triggered. We have to find a solution - * for this. It might make sense to have a function in getkey.c - * which does only the basic checks and returns even revoked and - * expired keys. This fnction could then also returhn a list of - * keys if the speicified name is ambiguous - */ - if( (*trustlevel & TRUST_FLAG_REVOKED) ) { - log_info(_("key %08lX: key has been revoked!\n"), - (ulong)keyid_from_pk( pk, NULL) ); - show_revocation_reason( pk, 0 ); - if( opt.batch ) - return 0; /* no */ - - if( !cpr_get_answer_is_yes("revoked_key.override", - _("Use this key anyway? ")) ) - return 0; /* no */ - trustmask |= TRUST_FLAG_REVOKED; - } - if( (*trustlevel & TRUST_FLAG_SUB_REVOKED) ) { - log_info(_("key %08lX: subkey has been revoked!\n"), - (ulong)keyid_from_pk( pk, NULL) ); - show_revocation_reason( pk, 0 ); - if( opt.batch ) - return 0; - - if( !cpr_get_answer_is_yes("revoked_key.override", - _("Use this key anyway? ")) ) - return 0; - trustmask |= TRUST_FLAG_SUB_REVOKED; - } - *trustlevel &= ~trustmask; - - if( opt.trust_model==TM_ALWAYS ) { - if( opt.verbose ) - log_info("No trust check due to --trust-model always option\n"); - return 1; - } - - switch( (*trustlevel & TRUST_MASK) ) { - case TRUST_EXPIRED: - log_info(_("%08lX: key has expired\n"), - (ulong)keyid_from_pk( pk, NULL) ); - return 0; /* no */ - - default: - log_error ("invalid trustlevel %u returned from validation layer\n", - *trustlevel); - /* fall thru */ - case TRUST_UNKNOWN: - case TRUST_UNDEFINED: - log_info(_("%08lX: There is no assurance this key belongs " - "to the named user\n"),(ulong)keyid_from_pk( pk, NULL) ); - return 0; /* no */ - - /* No way to get here? */ - case TRUST_NEVER: - log_info(_("%08lX: We do NOT trust this key\n"), - (ulong)keyid_from_pk( pk, NULL) ); - return 0; /* no */ - - case TRUST_MARGINAL: - log_info(_("%08lX: There is limited assurance this key belongs " - "to the named user\n"),(ulong)keyid_from_pk(pk,NULL)); - return 1; /* yes */ - - case TRUST_FULLY: - if( opt.verbose ) - log_info(_("This key probably belongs to the named user\n")); - return 1; /* yes */ - - case TRUST_ULTIMATE: - if( opt.verbose ) - log_info(_("This key belongs to us\n")); - return 1; /* yes */ - } - - return 1; /* yes */ -} - - - -/**************** - * wrapper around do_we_trust, so we can ask whether to use the - * key anyway. - */ -static int -do_we_trust_pre( PKT_public_key *pk, unsigned int trustlevel ) -{ - int rc; - - rc = do_we_trust( pk, &trustlevel ); - - if( (trustlevel & TRUST_FLAG_REVOKED) && !rc ) - return 0; - if( (trustlevel & TRUST_FLAG_SUB_REVOKED) && !rc ) - return 0; - - if( !opt.batch && !rc ) { - u32 keyid[2]; - - keyid_from_pk( pk, keyid); - tty_printf( "%4u%c/%08lX %s \"", - nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), - (ulong)keyid[1], datestr_from_pk( pk ) ); - /* If the pk was chosen by a particular user ID, this is the - one to ask about. */ - if(pk->user_id) - tty_print_utf8_string(pk->user_id->name,pk->user_id->len); - else - { - size_t n; - char *p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ); - xfree (p); - } - tty_printf("\"\n"); - print_fingerprint (pk, NULL, 2); - tty_printf("\n"); - - tty_printf(_( -"It is NOT certain that the key belongs to the person named\n" -"in the user ID. If you *really* know what you are doing,\n" -"you may answer the next question with yes\n\n")); - - if( cpr_get_answer_is_yes("untrusted_key.override", - _("Use this key anyway? ")) ) - rc = 1; - - /* Hmmm: Should we set a flag to tell the user about - * his decision the next time he encrypts for this recipient? - */ - } - else if( opt.trust_model==TM_ALWAYS && !rc ) { - if( !opt.quiet ) - log_info(_("WARNING: Using untrusted key!\n")); - rc = 1; - } - return rc; -} - - - -/**************** - * Check whether we can trust this signature. - * Returns: Error if we shall not trust this signatures. - */ -int -check_signatures_trust( PKT_signature *sig ) -{ - PKT_public_key *pk = xcalloc (1, sizeof *pk ); - unsigned int trustlevel; - int rc=0; - - rc = get_pubkey( pk, sig->keyid ); - if (rc) - { /* this should not happen */ - log_error("Ooops; the key vanished - can't check the trust\n"); - rc = GPG_ERR_NO_PUBKEY; - goto leave; - } - - if ( opt.trust_model==TM_ALWAYS ) - { - if( !opt.quiet ) - log_info(_("WARNING: Using untrusted key!\n")); - if (opt.with_fingerprint) - print_fingerprint (pk, NULL, 1); - goto leave; - } - - trustlevel = get_validity (pk, NULL); - - if ( (trustlevel & TRUST_FLAG_REVOKED) ) - { - write_status( STATUS_KEYREVOKED ); - log_info(_("WARNING: This key has been revoked by its owner!\n")); - log_info(_(" This could mean that the signature is forgery.\n")); - show_revocation_reason( pk, 0 ); - } - else if ((trustlevel & TRUST_FLAG_SUB_REVOKED) ) - { - write_status( STATUS_KEYREVOKED ); - log_info(_("WARNING: This subkey has been revoked by its owner!\n")); - show_revocation_reason( pk, 0 ); - } - - if ((trustlevel & TRUST_FLAG_DISABLED)) - log_info (_("Note: This key has been disabled.\n")); - - switch ( (trustlevel & TRUST_MASK) ) - { - case TRUST_EXPIRED: - log_info(_("Note: This key has expired!\n")); - print_fingerprint (pk, NULL, 1); - break; - - default: - log_error ("invalid trustlevel %u returned from validation layer\n", - trustlevel); - /* fall thru */ - case TRUST_UNKNOWN: - case TRUST_UNDEFINED: - write_status( STATUS_TRUST_UNDEFINED ); - log_info(_("WARNING: This key is not certified with" - " a trusted signature!\n")); - log_info(_(" There is no indication that the " - "signature belongs to the owner.\n" )); - print_fingerprint (pk, NULL, 1); - break; - - case TRUST_NEVER: - /* currently we won't get that status */ - write_status( STATUS_TRUST_NEVER ); - log_info(_("WARNING: We do NOT trust this key!\n")); - log_info(_(" The signature is probably a FORGERY.\n")); - if (opt.with_fingerprint) - print_fingerprint (pk, NULL, 1); - rc = gpg_error (GPG_ERR_BAD_SIGNATURE); - break; - - case TRUST_MARGINAL: - write_status( STATUS_TRUST_MARGINAL ); - log_info(_("WARNING: This key is not certified with" - " sufficiently trusted signatures!\n")); - log_info(_(" It is not certain that the" - " signature belongs to the owner.\n" )); - print_fingerprint (pk, NULL, 1); - break; - - case TRUST_FULLY: - write_status( STATUS_TRUST_FULLY ); - if (opt.with_fingerprint) - print_fingerprint (pk, NULL, 1); - break; - - case TRUST_ULTIMATE: - write_status( STATUS_TRUST_ULTIMATE ); - if (opt.with_fingerprint) - print_fingerprint (pk, NULL, 1); - break; - } - - leave: - free_public_key( pk ); - return rc; -} - - -void -release_pk_list( PK_LIST pk_list ) -{ - PK_LIST pk_rover; - - for( ; pk_list; pk_list = pk_rover ) { - pk_rover = pk_list->next; - free_public_key( pk_list->pk ); - xfree ( pk_list ); - } -} - - -static int -key_present_in_pk_list(PK_LIST pk_list, PKT_public_key *pk) -{ - for( ; pk_list; pk_list = pk_list->next) - if (cmp_public_keys(pk_list->pk, pk) == 0) - return 0; - - return -1; -} - - -/**************** - * Return a malloced string with a default reciepient if there is any - */ -static char * -default_recipient(void) -{ - PKT_secret_key *sk; - byte fpr[MAX_FINGERPRINT_LEN+1]; - size_t n; - char *p; - int i; - - if( opt.def_recipient ) - return xstrdup ( opt.def_recipient ); - if( !opt.def_recipient_self ) - return NULL; - sk = xcalloc (1, sizeof *sk ); - i = get_seckey_byname( sk, NULL, 0 ); - if( i ) { - free_secret_key( sk ); - return NULL; - } - n = MAX_FINGERPRINT_LEN; - fingerprint_from_sk( sk, fpr, &n ); - free_secret_key( sk ); - p = xmalloc ( 2*n+3 ); - *p++ = '0'; - *p++ = 'x'; - for(i=0; i < n; i++ ) - sprintf( p+2*i, "%02X", fpr[i] ); - p -= 2; - return p; -} - -static int -expand_id(const char *id,STRLIST *into,unsigned int flags) -{ - struct groupitem *groups; - int count=0; - - for(groups=opt.grouplist;groups;groups=groups->next) - { - /* need strcasecmp() here, as this should be localized */ - if(strcasecmp(groups->name,id)==0) - { - STRLIST each,sl; - - /* this maintains the current utf8-ness */ - for(each=groups->values;each;each=each->next) - { - sl=add_to_strlist(into,each->d); - sl->flags=flags; - count++; - } - - break; - } - } - - return count; -} - -/* For simplicity, and to avoid potential loops, we only expand once - - you can't make an alias that points to an alias. */ -static STRLIST -expand_group(STRLIST input) -{ - STRLIST sl,output=NULL,rover; - - for(rover=input;rover;rover=rover->next) - if(expand_id(rover->d,&output,rover->flags)==0) - { - /* Didn't find any groups, so use the existing string */ - sl=add_to_strlist(&output,rover->d); - sl->flags=rover->flags; - } - - return output; -} - -int -build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ) -{ - PK_LIST pk_list = NULL; - PKT_public_key *pk=NULL; - int rc=0; - int any_recipients=0; - STRLIST rov,remusr; - char *def_rec = NULL; - - if(opt.grouplist) - remusr=expand_group(rcpts); - else - remusr=rcpts; - - /* check whether there are any recipients in the list and build the - * list of the encrypt-to ones (we always trust them) */ - for( rov = remusr; rov; rov = rov->next ) { - if( !(rov->flags & 1) ) - { - any_recipients = 1; - - if((rov->flags&2) && (PGP2 || PGP6 || PGP7 || PGP8)) - { - log_info(_("you may not use %s while in %s mode\n"), - "--hidden-recipient", - compliance_option_string()); - - compliance_failure(); - } - } - else if( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) { - pk = xcalloc (1, sizeof *pk ); - pk->req_usage = use; - /* We can encrypt-to a disabled key */ - if( (rc = get_pubkey_byname( pk, rov->d, NULL, NULL, 1 )) ) { - free_public_key( pk ); pk = NULL; - log_error(_("%s: skipped: %s\n"), rov->d, gpg_strerror (rc) ); - write_status_text_and_buffer (STATUS_INV_RECP, "0 ", - rov->d, strlen (rov->d), -1); - goto fail; - } - else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use )) ) { - /* Skip the actual key if the key is already present - * in the list */ - if (key_present_in_pk_list(pk_list, pk) == 0) { - free_public_key(pk); pk = NULL; - log_info(_("%s: skipped: public key already present\n"), - rov->d); - } - else { - PK_LIST r; - r = xmalloc ( sizeof *r ); - r->pk = pk; pk = NULL; - r->next = pk_list; - r->flags = (rov->flags&2)?1:0; - pk_list = r; - - if(r->flags&1 && (PGP2 || PGP6 || PGP7 || PGP8)) - { - log_info(_("you may not use %s while in %s mode\n"), - "--hidden-encrypt-to", - compliance_option_string()); - - compliance_failure(); - } - } - } - else { - free_public_key( pk ); pk = NULL; - log_error(_("%s: skipped: %s\n"), rov->d, gpg_strerror (rc) ); - write_status_text_and_buffer (STATUS_INV_RECP, "0 ", - rov->d, strlen (rov->d), -1); - goto fail; - } - } - } - - if( !any_recipients && !opt.batch ) { /* ask */ - int have_def_rec; - char *answer=NULL; - STRLIST backlog=NULL; - - def_rec = default_recipient(); - have_def_rec = !!def_rec; - if( !have_def_rec ) - tty_printf(_( - "You did not specify a user ID. (you may use \"-r\")\n")); - for(;;) { - rc = 0; - xfree (answer); - if( have_def_rec ) { - answer = def_rec; - def_rec = NULL; - } - else if (backlog) { - answer = strlist_pop (&backlog); - } - else { - answer = cpr_get_utf8("pklist.user_id.enter", - _("\nEnter the user ID. End with an empty line: ")); - trim_spaces(answer); - cpr_kill_prompt(); - } - if( !answer || !*answer ) { - xfree (answer); - break; - } - if(expand_id(answer,&backlog,0)) - continue; - if( pk ) - free_public_key( pk ); - pk = xcalloc (1, sizeof *pk ); - pk->req_usage = use; - rc = get_pubkey_byname( pk, answer, NULL, NULL, 0 ); - if( rc ) - tty_printf(_("No such user ID.\n")); - else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use)) ) { - if( have_def_rec ) { - if (key_present_in_pk_list(pk_list, pk) == 0) { - free_public_key(pk); pk = NULL; - log_info(_("skipped: public key " - "already set as default recipient\n") ); - } - else { - PK_LIST r = xmalloc ( sizeof *r ); - r->pk = pk; pk = NULL; - r->next = pk_list; - r->flags = 0; /* no throwing default ids */ - pk_list = r; - } - any_recipients = 1; - continue; - } - else { - int trustlevel; - - trustlevel = get_validity (pk, pk->user_id); - if( (trustlevel & TRUST_FLAG_DISABLED) ) { - tty_printf(_("Public key is disabled.\n") ); - } - else if( do_we_trust_pre( pk, trustlevel ) ) { - /* Skip the actual key if the key is already present - * in the list */ - if (key_present_in_pk_list(pk_list, pk) == 0) { - free_public_key(pk); pk = NULL; - log_info(_("skipped: public key already set\n") ); - } - else { - PK_LIST r; - u32 keyid[2]; - - keyid_from_pk( pk, keyid); - tty_printf("Added %4u%c/%08lX %s \"", - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo ), - (ulong)keyid[1], - datestr_from_pk( pk ) ); - if(pk->user_id) - tty_print_utf8_string(pk->user_id->name, - pk->user_id->len); - else - { - size_t n; - char *p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ); - xfree (p); - } - tty_printf("\"\n"); - - r = xmalloc ( sizeof *r ); - r->pk = pk; pk = NULL; - r->next = pk_list; - r->flags = 0; /* no throwing interactive ids */ - pk_list = r; - } - any_recipients = 1; - continue; - } - } - } - xfree (def_rec); def_rec = NULL; - have_def_rec = 0; - } - if( pk ) { - free_public_key( pk ); - pk = NULL; - } - } - else if( !any_recipients && (def_rec = default_recipient()) ) { - pk = xcalloc (1, sizeof *pk ); - pk->req_usage = use; - /* The default recipient may be disabled */ - rc = get_pubkey_byname( pk, def_rec, NULL, NULL, 1 ); - if( rc ) - log_error(_("unknown default recipient `%s'\n"), def_rec ); - else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use)) ) { - /* Mark any_recipients here since the default recipient - would have been used if it wasn't already there. It - doesn't really matter if we got this key from the default - recipient or an encrypt-to. */ - any_recipients = 1; - if (key_present_in_pk_list(pk_list, pk) == 0) - log_info(_("skipped: public key already set as default recipient\n")); - else { - PK_LIST r = xmalloc ( sizeof *r ); - r->pk = pk; pk = NULL; - r->next = pk_list; - r->flags = 0; /* no throwing default ids */ - pk_list = r; - } - } - if( pk ) { - free_public_key( pk ); - pk = NULL; - } - xfree (def_rec); def_rec = NULL; - } - else { - any_recipients = 0; - for(; remusr; remusr = remusr->next ) { - if( (remusr->flags & 1) ) - continue; /* encrypt-to keys are already handled */ - - pk = xcalloc (1, sizeof *pk ); - pk->req_usage = use; - if( (rc = get_pubkey_byname( pk, remusr->d, NULL, NULL, 0 )) ) { - free_public_key( pk ); pk = NULL; - log_error(_("%s: skipped: %s\n"), remusr->d, gpg_strerror (rc) ); - write_status_text_and_buffer (STATUS_INV_RECP, "0 ", - remusr->d, strlen (remusr->d), - -1); - goto fail; - } - else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use )) ) { - int trustlevel; - - trustlevel = get_validity (pk, pk->user_id); - if( (trustlevel & TRUST_FLAG_DISABLED) ) { - free_public_key(pk); pk = NULL; - log_info(_("%s: skipped: public key is disabled\n"), - remusr->d); - write_status_text_and_buffer (STATUS_INV_RECP, "0 ", - remusr->d, - strlen (remusr->d), - -1); - rc = gpg_error (GPG_ERR_UNUSABLE_PUBKEY); - goto fail; - } - else if( do_we_trust_pre( pk, trustlevel ) ) { - /* note: do_we_trust may have changed the trustlevel */ - - /* We have at least one valid recipient. It doesn't matters - * if this recipient is already present. */ - any_recipients = 1; - - /* Skip the actual key if the key is already present - * in the list */ - if (key_present_in_pk_list(pk_list, pk) == 0) { - free_public_key(pk); pk = NULL; - log_info(_("%s: skipped: public key already present\n"), - remusr->d); - } - else { - PK_LIST r; - r = xmalloc ( sizeof *r ); - r->pk = pk; pk = NULL; - r->next = pk_list; - r->flags = (remusr->flags&2)?1:0; - pk_list = r; - } - } - else { /* we don't trust this pk */ - free_public_key( pk ); pk = NULL; - write_status_text_and_buffer (STATUS_INV_RECP, "10 ", - remusr->d, - strlen (remusr->d), - -1); - rc = gpg_error (GPG_ERR_UNUSABLE_PUBKEY); - goto fail; - } - } - else { - free_public_key( pk ); pk = NULL; - write_status_text_and_buffer (STATUS_INV_RECP, "0 ", - remusr->d, - strlen (remusr->d), - -1); - log_error(_("%s: skipped: %s\n"), remusr->d, gpg_strerror (rc) ); - goto fail; - } - } - } - - if( !rc && !any_recipients ) { - log_error(_("no valid addressees\n")); - write_status_text (STATUS_NO_RECP, "0"); - rc = GPG_ERR_NO_USER_ID; - } - - fail: - - if( rc ) - release_pk_list( pk_list ); - else - *ret_pk_list = pk_list; - if(opt.grouplist) - free_strlist(remusr); - return rc; -} - - -/* In pgp6 mode, disallow all ciphers except IDEA (1), 3DES (2), and - CAST5 (3), all hashes except MD5 (1), SHA1 (2), and RIPEMD160 (3), - and all compressions except none (0) and ZIP (1). pgp7 and pgp8 - mode expands the cipher list to include AES128 (7), AES192 (8), - AES256 (9), and TWOFISH (10). pgp8 adds the SHA-256 hash (8). For - a true PGP key all of this is unneeded as they are the only items - present in the preferences subpacket, but checking here covers the - weird case of encrypting to a key that had preferences from a - different implementation which was then used with PGP. I am not - completely comfortable with this as the right thing to do, as it - slightly alters the list of what the user is supposedly requesting. - It is not against the RFC however, as the preference chosen will - never be one that the user didn't specify somewhere ("The - implementation may use any mechanism to pick an algorithm in the - intersection"), and PGP has no mechanism to fix such a broken - preference list, so I'm including it. -dms */ - -int -algo_available( preftype_t preftype, int algo, void *hint ) -{ - if( preftype == PREFTYPE_SYM ) - { - if(PGP6 && (algo != CIPHER_ALGO_IDEA - && algo != CIPHER_ALGO_3DES - && algo != CIPHER_ALGO_CAST5)) - return 0; - - if((PGP7 || PGP8) && (algo != CIPHER_ALGO_IDEA - && algo != CIPHER_ALGO_3DES - && algo != CIPHER_ALGO_CAST5 - && algo != CIPHER_ALGO_AES - && algo != CIPHER_ALGO_AES192 - && algo != CIPHER_ALGO_AES256 - && algo != CIPHER_ALGO_TWOFISH)) - return 0; - - return algo && !gcry_cipher_test_algo (algo); - } - else if( preftype == PREFTYPE_HASH ) - { - if(hint && ((*(int *)hint) != gcry_md_get_algo_dlen (algo))) - return 0; - - if((PGP6 || PGP7) && (algo != DIGEST_ALGO_MD5 - && algo != DIGEST_ALGO_SHA1 - && algo != DIGEST_ALGO_RMD160)) - return 0; - - - if(PGP8 && (algo != DIGEST_ALGO_MD5 - && algo != DIGEST_ALGO_SHA1 - && algo != DIGEST_ALGO_RMD160 - && algo != DIGEST_ALGO_SHA256)) - return 0; - - return algo && !gcry_md_test_algo( algo ); - } - else if( preftype == PREFTYPE_ZIP ) - { - if((PGP6 || PGP7 || PGP8) && (algo != COMPRESS_ALGO_NONE - && algo != COMPRESS_ALGO_ZIP)) - return 0; - - return !check_compress_algo( algo ); - } - else - return 0; -} - - - -/**************** - * Return -1 if we could not find an algorithm. - */ -int -select_algo_from_prefs(PK_LIST pk_list, int preftype, int request, void *hint) -{ - PK_LIST pkr; - u32 bits[8]; - const prefitem_t *prefs; - int i, j; - int compr_hack=0; - int any; - - if( !pk_list ) - return -1; - - memset( bits, ~0, 8 * sizeof *bits ); - for( pkr = pk_list; pkr; pkr = pkr->next ) { - u32 mask[8]; - - memset( mask, 0, 8 * sizeof *mask ); - if( preftype == PREFTYPE_SYM ) { - if( PGP2 && - pkr->pk->version < 4 && - pkr->pk->selfsigversion < 4 ) - mask[0] |= (1<<1); /* IDEA is implicitly there for v3 keys - with v3 selfsigs (rfc2440:12.1) if - --pgp2 mode is on. This doesn't - mean it's actually available, of - course. */ - else - mask[0] |= (1<<2); /* 3DES is implicitly there for everyone else */ - } - else if( preftype == PREFTYPE_HASH ) { - /* While I am including this code for completeness, note - that currently --pgp2 mode locks the hash at MD5, so this - function will never even be called. Even if the hash - wasn't locked at MD5, we don't support sign+encrypt in - --pgp2 mode, and that's the only time PREFTYPE_HASH is - used anyway. -dms */ - if( PGP2 && - pkr->pk->version < 4 && - pkr->pk->selfsigversion < 4 ) - mask[0] |= (1<<1); /* MD5 is there for v3 keys with v3 - selfsigs when --pgp2 is on. */ - else - mask[0] |= (1<<2); /* SHA1 is there for everyone else */ - } - else if( preftype == PREFTYPE_ZIP ) - mask[0] |= (1<<0); /* Uncompressed is implicit */ - - if (pkr->pk->user_id) /* selected by user ID */ - prefs = pkr->pk->user_id->prefs; - else - prefs = pkr->pk->prefs; - - any = 0; - if( prefs ) { - for (i=0; prefs[i].type; i++ ) { - if( prefs[i].type == preftype ) { - mask[prefs[i].value/32] |= 1 << (prefs[i].value%32); - any = 1; - } - } - } - - if( (!prefs || !any) && preftype == PREFTYPE_ZIP ) { - mask[0] |= 3; /* asume no_compression and old pgp */ - compr_hack = 1; - } - -#if 0 - log_debug("pref mask=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n", - (ulong)mask[7], (ulong)mask[6], (ulong)mask[5], (ulong)mask[4], - (ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0]); -#endif - for(i=0; i < 8; i++ ) - bits[i] &= mask[i]; -#if 0 - log_debug("pref bits=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n", - (ulong)bits[7], (ulong)bits[6], (ulong)bits[5], (ulong)bits[4], - (ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]); -#endif - } - /* usable algorithms are now in bits - * We now use the last key from pk_list to select - * the algorithm we want to use. there are no - * preferences for the last key, we select the one - * corresponding to first set bit. - */ - i = -1; - any = 0; - - /* Can we use the requested algorithm? */ - if(request>-1 && (bits[request/32] & (1<<(request%32))) && - algo_available(preftype,request,hint)) - return request; - - /* If we have personal prefs set, use them instead of the last key */ - if(preftype==PREFTYPE_SYM && opt.personal_cipher_prefs) - prefs=opt.personal_cipher_prefs; - else if(preftype==PREFTYPE_HASH && opt.personal_digest_prefs) - prefs=opt.personal_digest_prefs; - else if(preftype==PREFTYPE_ZIP && opt.personal_compress_prefs) - prefs=opt.personal_compress_prefs; - - if( prefs ) { - for(j=0; prefs[j].type; j++ ) { - if( prefs[j].type == preftype ) { - if( (bits[prefs[j].value/32] & (1<<(prefs[j].value%32))) ) { - if( algo_available( preftype, prefs[j].value, hint ) ) { - any = 1; - i = prefs[j].value; - break; - } - } - } - } - } - if( !prefs || !any ) { - for(j=0; j < 256; j++ ) - if( (bits[j/32] & (1<<(j%32))) ) { - if( algo_available( preftype, j, hint ) ) { - i = j; - break; - } - } - } - -#if 0 - log_debug("prefs of type %d: selected %d\n", preftype, i ); -#endif - if( compr_hack && !i ) { - /* selected no compression, but we should check whether - * algorithm 1 is also available (the ordering is not relevant - * in this case). */ - if( bits[0] & (1<<1) ) - i = 1; /* yep; we can use compression algo 1 */ - } - - /* "If you are building an authentication system, the recipient - may specify a preferred signing algorithm. However, the signer - would be foolish to use a weak algorithm simply because the - recipient requests it." RFC2440:13. If we settle on MD5, and - SHA1 is also available, use SHA1 instead. Of course, if the - user intentionally chose MD5 (by putting it in their personal - prefs), then we should do what they say. */ - - if(preftype==PREFTYPE_HASH && - i==DIGEST_ALGO_MD5 && (bits[0] & (1<<DIGEST_ALGO_SHA1))) - { - i=DIGEST_ALGO_SHA1; - - if(opt.personal_digest_prefs) - for(j=0; prefs[j].type; j++ ) - if(opt.personal_digest_prefs[j].type==PREFTYPE_HASH && - opt.personal_digest_prefs[j].value==DIGEST_ALGO_MD5) - { - i=DIGEST_ALGO_MD5; - break; - } - } - - return i; -} - -/* - * Select the MDC flag from the pk_list. We can only use MDC if all recipients - * support this feature - */ -int -select_mdc_from_pklist (PK_LIST pk_list) -{ - PK_LIST pkr; - - if( !pk_list ) - return 0; - - for (pkr = pk_list; pkr; pkr = pkr->next) { - int mdc; - - if (pkr->pk->user_id) /* selected by user ID */ - mdc = pkr->pk->user_id->mdc_feature; - else - mdc = pkr->pk->mdc_feature; - if (!mdc) - return 0; /* at least one recipient does not support it */ - } - return 1; /* can be used */ -} diff --git a/g10/pkglue.c b/g10/pkglue.c deleted file mode 100644 index f062d8366..000000000 --- a/g10/pkglue.c +++ /dev/null @@ -1,342 +0,0 @@ -/* pkglue.c - public key operations glue code - * Copyright (C) 2000, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "pkglue.h" - - -static gcry_mpi_t -mpi_from_sexp (gcry_sexp_t sexp, const char * item) -{ - gcry_sexp_t list; - gcry_mpi_t data; - - list = gcry_sexp_find_token (sexp, item, 0); - assert (list); - data = gcry_sexp_nth_mpi (list, 1, 0); - assert (data); - gcry_sexp_release (list); - return data; -} - - -/**************** - * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. - */ -int -pk_sign (int algo, gcry_mpi_t * data, gcry_mpi_t hash, gcry_mpi_t * skey) -{ - gcry_sexp_t s_sig, s_hash, s_skey; - int rc; - - /* make a sexp from skey */ - if (algo == GCRY_PK_DSA) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4]); - } - else if (algo == GCRY_PK_RSA) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4], - skey[5]); - } - else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3]); - } - else - return GPG_ERR_PUBKEY_ALGO; - - if (rc) - BUG (); - - /* put hash into a S-Exp s_hash */ - if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) - BUG (); - - rc = gcry_pk_sign (&s_sig, s_hash, s_skey); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_skey); - - if (rc) - ; - else if (algo == GCRY_PK_RSA) - data[0] = mpi_from_sexp (s_sig, "s"); - else - { - data[0] = mpi_from_sexp (s_sig, "r"); - data[1] = mpi_from_sexp (s_sig, "s"); - } - - gcry_sexp_release (s_sig); - return rc; -} - -/**************** - * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. - */ -int -pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) -{ - gcry_sexp_t s_sig, s_hash, s_pkey; - int rc; - - /* make a sexp from pkey */ - if (algo == GCRY_PK_DSA) - { - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", - pkey[0], pkey[1], pkey[2], pkey[3]); - } - else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(elg(p%m)(g%m)(y%m)))", - pkey[0], pkey[1], pkey[2]); - } - else if (algo == GCRY_PK_RSA) - { - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]); - } - else - return GPG_ERR_PUBKEY_ALGO; - - if (rc) - BUG (); - - /* put hash into a S-Exp s_hash */ - if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) - BUG (); - - /* put data into a S-Exp s_sig */ - if (algo == GCRY_PK_DSA) - { - if (!data[0] || !data[1]) - rc = gpg_error (GPG_ERR_BAD_MPI); - else - rc = gcry_sexp_build (&s_sig, NULL, - "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]); - } - else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - if (!data[0] || !data[1]) - rc = gpg_error (GPG_ERR_BAD_MPI); - else - rc = gcry_sexp_build (&s_sig, NULL, - "(sig-val(elg(r%m)(s%m)))", data[0], data[1]); - } - else if (algo == GCRY_PK_RSA) - { - if (!data[0]) - rc = gpg_error (GPG_ERR_BAD_MPI); - else - rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%m)))", data[0]); - } - else - BUG (); - - if (rc) - BUG (); - - - rc = gcry_pk_verify (s_sig, s_hash, s_pkey); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_pkey); - return rc; -} - - - - -/**************** - * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. - */ -int -pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey) -{ - gcry_sexp_t s_ciph, s_data, s_pkey; - int rc; - - /* make a sexp from pkey */ - if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(elg(p%m)(g%m)(y%m)))", - pkey[0], pkey[1], pkey[2]); - } - else if (algo == GCRY_PK_RSA) - { - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(rsa(n%m)(e%m)))", - pkey[0], pkey[1]); - } - else - return GPG_ERR_PUBKEY_ALGO; - - if (rc) - BUG (); - - /* put the data into a simple list */ - if (gcry_sexp_build (&s_data, NULL, "%m", data)) - BUG (); - - /* pass it to libgcrypt */ - rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); - gcry_sexp_release (s_data); - gcry_sexp_release (s_pkey); - - if (rc) - ; - else - { /* add better error handling or make gnupg use S-Exp directly */ - resarr[0] = mpi_from_sexp (s_ciph, "a"); - if (algo != GCRY_PK_RSA) - resarr[1] = mpi_from_sexp (s_ciph, "b"); - } - - gcry_sexp_release (s_ciph); - return rc; -} - - - -/**************** - * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. - */ -int -pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data, - gcry_mpi_t * skey) -{ - gcry_sexp_t s_skey, s_data, s_plain; - int rc; - - *result = NULL; - /* make a sexp from skey */ - if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3]); - } - else if (algo == GCRY_PK_RSA) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4], - skey[5]); - } - else - return GPG_ERR_PUBKEY_ALGO; - - if (rc) - BUG (); - - /* put data into a S-Exp s_data */ - if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - if (!data[0] || !data[1]) - rc = gpg_error (GPG_ERR_BAD_MPI); - else - rc = gcry_sexp_build (&s_data, NULL, - "(enc-val(elg(a%m)(b%m)))", data[0], data[1]); - } - else if (algo == GCRY_PK_RSA) - { - if (!data[0]) - rc = gpg_error (GPG_ERR_BAD_MPI); - else - rc = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data[0]); - } - else - BUG (); - - if (rc) - BUG (); - - rc = gcry_pk_decrypt (&s_plain, s_data, s_skey); - gcry_sexp_release (s_skey); - gcry_sexp_release (s_data); - if (rc) - return rc; - - *result = gcry_sexp_nth_mpi (s_plain, 0, 0); - gcry_sexp_release (s_plain); - if (!*result) - return -1; /* oops */ - - return 0; -} - - -/* Check whether SKEY is a suitable secret key. */ -int -pk_check_secret_key (int algo, gcry_mpi_t *skey) -{ - gcry_sexp_t s_skey; - int rc; - - if (algo == GCRY_PK_DSA) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4]); - } - else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3]); - } - else if (algo == GCRY_PK_RSA) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4], - skey[5]); - } - else - return GPG_ERR_PUBKEY_ALGO; - - if (!rc) - { - rc = gcry_pk_testkey (s_skey); - gcry_sexp_release (s_skey); - } - return rc; -} diff --git a/g10/pkglue.h b/g10/pkglue.h deleted file mode 100644 index 43b82785b..000000000 --- a/g10/pkglue.h +++ /dev/null @@ -1,35 +0,0 @@ -/* pkglue.h - public key operations definitions - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_G10_PKGLUE_H -#define GNUPG_G10_PKGLUE_H - -int pk_sign (int algo, gcry_mpi_t *data, gcry_mpi_t hash, - gcry_mpi_t *skey); -int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, - gcry_mpi_t *pkey); -int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, - gcry_mpi_t *pkey); -int pk_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data, - gcry_mpi_t *skey); -int pk_check_secret_key (int algo, gcry_mpi_t *skey); - - -#endif /*GNUPG_G10_PKGLUE_H*/ diff --git a/g10/plaintext.c b/g10/plaintext.c deleted file mode 100644 index d84a523fe..000000000 --- a/g10/plaintext.c +++ /dev/null @@ -1,458 +0,0 @@ -/* plaintext.c - process plaintext packets - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#ifdef HAVE_DOSISH_SYSTEM -#include <fcntl.h> /* for setmode() */ -#endif - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "options.h" -#include "packet.h" -#include "ttyio.h" -#include "filter.h" -#include "main.h" -#include "status.h" -#include "i18n.h" - - - -/**************** - * Handle a plaintext packet. If MFX is not NULL, update the MDs - * Note: we should use the filter stuff here, but we have to add some - * easy mimic to set a read limit, so we calculate only the - * bytes from the plaintext. - */ -int -handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, - int nooutput, int clearsig, int *create_failed ) -{ - char *fname = NULL; - FILE *fp = NULL; - int rc = 0; - int c; - int convert = pt->mode == 't'; -#ifdef __riscos__ - int filetype = 0xfff; -#endif - int dummy_create_failed; - - if (!create_failed) - create_failed = &dummy_create_failed; - *create_failed = 0; - - /* create the filename as C string */ - if( nooutput ) - ; - else if( opt.outfile ) { - fname = xmalloc ( strlen( opt.outfile ) + 1); - strcpy(fname, opt.outfile ); - } - else if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) ) { - log_info(_("data not saved; use option \"--output\" to save it\n")); - nooutput = 1; - } - else if( !opt.use_embedded_filename ) { - fname = make_outfile_name( iobuf_get_real_fname(pt->buf) ); - if( !fname ) - fname = ask_outfile_name( pt->name, pt->namelen ); - if( !fname ) { - *create_failed = 1; - rc = GPG_ERR_GENERAL; - goto leave; - } - } - else { - fname = make_printable_string( pt->name, pt->namelen, 0 ); - } - - if( nooutput ) - ; - else if( !*fname || (*fname=='-' && !fname[1])) { - /* no filename or "-" given; write to stdout */ - fp = stdout; -#ifdef HAVE_DOSISH_SYSTEM - setmode ( fileno(fp) , O_BINARY ); -#endif - } - else { - while( !overwrite_filep (fname) ) { - char *tmp = ask_outfile_name (NULL, 0); - if ( !tmp || !*tmp ) { - xfree (tmp); - *create_failed = 1; - rc = GPG_ERR_GENERAL; - goto leave; - } - xfree (fname); - fname = tmp; - } - } - -#ifndef __riscos__ - if( fp || nooutput ) - ; - else if( !(fp = fopen(fname,"wb")) ) { - rc = gpg_error_from_errno (errno); - log_error(_("error creating `%s': %s\n"), fname, strerror(errno) ); - *create_failed = 1; - goto leave; - } -#else /* __riscos__ */ - /* Convert all '.' in fname to '/' -- we don't create directories! */ - for( c=0; fname[c]; ++c ) - if( fname[c] == '.' ) - fname[c] = '/'; - - if( fp || nooutput ) - ; - else { - fp = fopen(fname,"wb"); - if( !fp ) { - rc == gpg_error_from_errno (errno); - log_error(_("error creating `%s': %s\n"), fname, strerror(errno) ); - *create_failed = 1; - if (errno == 106) - log_info("Do output file and input file have the same name?\n"); - goto leave; - } - - /* If there's a ,xxx extension in the embedded filename, - use that, else check whether the user input (in fname) - has a ,xxx appended, then use that in preference */ - if( (c = riscos_get_filetype_from_string( pt->name, - pt->namelen )) != -1 ) - filetype = c; - if( (c = riscos_get_filetype_from_string( fname, - strlen(fname) )) != -1 ) - filetype = c; - riscos_set_filetype_by_number(fname, filetype); - } -#endif /* __riscos__ */ - - if( !pt->is_partial ) { - /* we have an actual length (which might be zero). */ - assert( !clearsig ); - if( convert ) { /* text mode */ - for( ; pt->len; pt->len-- ) { - if( (c = iobuf_get(pt->buf)) == -1 ) { - rc = gpg_error_from_errno (errno); - log_error("Problem reading source (%u bytes remaining)\n", - (unsigned)pt->len); - goto leave; - } - if( mfx->md ) - gcry_md_putc (mfx->md, c ); -#ifndef HAVE_DOSISH_SYSTEM - if( c == '\r' ) /* convert to native line ending */ - continue; /* fixme: this hack might be too simple */ -#endif - if( fp ) { - if( putc( c, fp ) == EOF ) { - rc = gpg_error_from_errno (errno); - log_error("Error writing to `%s': %s\n", - fname, strerror(errno) ); - goto leave; - } - } - } - } - else { /* binary mode */ - byte *buffer = xmalloc ( 32768 ); - while( pt->len ) { - int len = pt->len > 32768 ? 32768 : pt->len; - len = iobuf_read( pt->buf, buffer, len ); - if( len == -1 ) { - rc = gpg_error_from_errno (errno); - log_error("Problem reading source (%u bytes remaining)\n", - (unsigned)pt->len); - xfree ( buffer ); - goto leave; - } - if( mfx->md ) - gcry_md_write( mfx->md, buffer, len ); - if( fp ) { - if( fwrite( buffer, 1, len, fp ) != len ) { - rc = gpg_error_from_errno (errno); - log_error("Error writing to `%s': %s\n", - fname, strerror(errno) ); - xfree ( buffer ); - goto leave; - } - } - pt->len -= len; - } - xfree ( buffer ); - } - } - else if( !clearsig ) { - if( convert ) { /* text mode */ - while( (c = iobuf_get(pt->buf)) != -1 ) { - if( mfx->md ) - gcry_md_putc (mfx->md, c ); -#ifndef HAVE_DOSISH_SYSTEM - if( convert && c == '\r' ) - continue; /* fixme: this hack might be too simple */ -#endif - if( fp ) { - if( putc( c, fp ) == EOF ) { - rc = gpg_error_from_errno (errno); - log_error("Error writing to `%s': %s\n", - fname, strerror(errno) ); - goto leave; - } - } - } - } - else { /* binary mode */ - byte *buffer = xmalloc ( 32768 ); - int eof; - for( eof=0; !eof; ) { - /* Why do we check for len < 32768: - * If we won't, we would practically read 2 EOFs but - * the first one has already popped the block_filter - * off and therefore we don't catch the boundary. - * So, always assume EOF if iobuf_read returns less bytes - * then requested */ - int len = iobuf_read( pt->buf, buffer, 32768 ); - if( len == -1 ) - break; - if( len < 32768 ) - eof = 1; - if( mfx->md ) - gcry_md_write( mfx->md, buffer, len ); - if( fp ) { - if( fwrite( buffer, 1, len, fp ) != len ) { - rc = gpg_error_from_errno (errno); - log_error("Error writing to `%s': %s\n", - fname, strerror(errno) ); - xfree ( buffer ); - goto leave; - } - } - } - xfree ( buffer ); - } - pt->buf = NULL; - } - else { /* clear text signature - don't hash the last cr,lf */ - int state = 0; - - while( (c = iobuf_get(pt->buf)) != -1 ) { - if( fp ) { - if( putc( c, fp ) == EOF ) { - rc = gpg_error_from_errno (errno); - log_error("Error writing to `%s': %s\n", - fname, strerror(errno) ); - goto leave; - } - } - if( !mfx->md ) - continue; - if( state == 2 ) { - gcry_md_putc (mfx->md, '\r' ); - gcry_md_putc (mfx->md, '\n' ); - state = 0; - } - if( !state ) { - if( c == '\r' ) - state = 1; - else if( c == '\n' ) - state = 2; - else - gcry_md_putc (mfx->md, c ); - } - else if( state == 1 ) { - if( c == '\n' ) - state = 2; - else { - gcry_md_putc (mfx->md, '\r' ); - if( c == '\r' ) - state = 1; - else { - state = 0; - gcry_md_putc (mfx->md, c ); - } - } - } - } - pt->buf = NULL; - } - - if( fp && fp != stdout && fclose(fp) ) { - rc = gpg_error_from_errno (errno); - log_error("Error closing `%s': %s\n", fname, strerror(errno) ); - fp = NULL; - goto leave; - } - fp = NULL; - - leave: - if( fp && fp != stdout ) - fclose(fp); - xfree (fname); - return rc; -} - -static void -do_hash( MD_HANDLE md, MD_HANDLE md2, iobuf_t fp, int textmode ) -{ - text_filter_context_t tfx; - int c; - - if( textmode ) { - memset( &tfx, 0, sizeof tfx); - iobuf_push_filter( fp, text_filter, &tfx ); - } - if( md2 ) { /* work around a strange behaviour in pgp2 */ - /* It seems that at least PGP5 converts a single CR to a CR,LF too */ - int lc = -1; - while( (c = iobuf_get(fp)) != -1 ) { - if( c == '\n' && lc == '\r' ) - gcry_md_putc (md2, c); - else if( c == '\n' ) { - gcry_md_putc (md2, '\r'); - gcry_md_putc (md2, c); - } - else if( c != '\n' && lc == '\r' ) { - gcry_md_putc (md2, '\n'); - gcry_md_putc (md2, c); - } - else - gcry_md_putc (md2, c); - - if( md ) - gcry_md_putc (md, c ); - lc = c; - } - } - else { - while( (c = iobuf_get(fp)) != -1 ) { - if( md ) - gcry_md_putc (md, c ); - } - } -} - - -/**************** - * Ask for the detached datafile and calculate the digest from it. - * INFILE is the name of the input file. - */ -int -ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2, - const char *inname, int textmode ) -{ - progress_filter_context_t pfx; - char *answer = NULL; - iobuf_t fp; - int rc = 0; - - fp = open_sigfile( inname, &pfx ); /* open default file */ - - if( !fp && !opt.batch ) { - int any=0; - tty_printf(_("Detached signature.\n")); - do { - xfree (answer); - answer = cpr_get("detached_signature.filename", - _("Please enter name of data file: ")); - cpr_kill_prompt(); - if( any && !*answer ) { - rc = GPG_ERR_GENERAL; - goto leave; - } - fp = iobuf_open(answer); - if( !fp && errno == ENOENT ) { - tty_printf("No such file, try again or hit enter to quit.\n"); - any++; - } - else if( !fp ) { - rc = gpg_error_from_errno (errno); - log_error("can't open `%s': %s\n", answer, strerror(errno) ); - goto leave; - } - } while( !fp ); - } - - if( !fp ) { - if( opt.verbose ) - log_info(_("reading stdin ...\n")); - fp = iobuf_open( NULL ); - assert(fp); - } - do_hash( md, md2, fp, textmode ); - iobuf_close(fp); - - leave: - xfree (answer); - return rc; -} - - - -/**************** - * Hash the given files and append the hash to hash context md. - * If FILES is NULL, hash stdin. - */ -int -hash_datafiles( MD_HANDLE md, MD_HANDLE md2, STRLIST files, - const char *sigfilename, int textmode ) -{ - progress_filter_context_t pfx; - iobuf_t fp; - STRLIST sl; - - if( !files ) { - /* check whether we can open the signed material */ - fp = open_sigfile( sigfilename, &pfx ); - if( fp ) { - do_hash( md, md2, fp, textmode ); - iobuf_close(fp); - return 0; - } - log_error (_("no signed data\n")); - return GPG_ERR_NO_DATA; - } - - - for (sl=files; sl; sl = sl->next ) { - fp = iobuf_open( sl->d ); - if( !fp ) { - int tmperr = gpg_error_from_errno (errno); - log_error(_("can't open signed data `%s'\n"), - print_fname_stdin(sl->d)); - return tmperr; - } - handle_progress (&pfx, fp, sl->d); - do_hash( md, md2, fp, textmode ); - iobuf_close(fp); - } - - return 0; -} diff --git a/g10/progress.c b/g10/progress.c deleted file mode 100644 index 9d9805065..000000000 --- a/g10/progress.c +++ /dev/null @@ -1,118 +0,0 @@ -/* progress.c - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> - -#include "gpg.h" -#include "iobuf.h" -#include "filter.h" -#include "status.h" -#include "util.h" -#include "options.h" - -/**************** - * The filter is used to report progress to the user. - */ -int -progress_filter (void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - int rc = 0; - progress_filter_context_t *pfx = opaque; - - if (control == IOBUFCTRL_INIT) - { - char buffer[50]; - - pfx->last = 0; - pfx->offset = 0; - pfx->last_time = make_timestamp (); - - sprintf (buffer, "%.20s ? %lu %lu", - pfx->what? pfx->what : "?", - pfx->offset, - pfx->total); - write_status_text (STATUS_PROGRESS, buffer); - } - else if (control == IOBUFCTRL_UNDERFLOW) - { - u32 timestamp = make_timestamp (); - int len = iobuf_read (a, buf, *ret_len); - - if (len >= 0) - { - pfx->offset += len; - *ret_len = len; - } - else - { - *ret_len = 0; - rc = -1; - } - if ((len == -1 && pfx->offset != pfx->last) - || timestamp - pfx->last_time > 0) - { - char buffer[50]; - - sprintf (buffer, "%.20s ? %lu %lu", - pfx->what? pfx->what : "?", - pfx->offset, - pfx->total); - write_status_text (STATUS_PROGRESS, buffer); - - pfx->last = pfx->offset; - pfx->last_time = timestamp; - } - } - else if (control == IOBUFCTRL_FREE) - { - /* Note, that we must always dealloc resources of a filter - within the filter handler and not anywhere else. (We set it - to NULL and check all uses just in case.) */ - xfree (pfx->what); - pfx->what = NULL; - } - else if (control == IOBUFCTRL_DESC) - *(char**)buf = "progress_filter"; - return rc; -} - -void -handle_progress (progress_filter_context_t *pfx, iobuf_t inp, const char *name) -{ - off_t filesize = 0; - - if (!opt.enable_progress_filter) - return; - - if (!is_status_enabled ()) - return; - - if (name && *name && !(*name == '-' && !name[1])) - filesize = iobuf_get_filelength (inp); - else if (opt.set_filesize) - filesize = opt.set_filesize; - - /* register the progress filter */ - pfx->what = xstrdup (name ? name : "stdin"); - pfx->total = filesize; - iobuf_push_filter (inp, progress_filter, pfx); -} diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c deleted file mode 100644 index 4b45b9f5c..000000000 --- a/g10/pubkey-enc.c +++ /dev/null @@ -1,345 +0,0 @@ -/* pubkey-enc.c - public key encoded packet handling - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "packet.h" -#include "mpi.h" -#include "keydb.h" -#include "trustdb.h" -#include "cipher.h" -#include "status.h" -#include "options.h" -#include "main.h" -#include "i18n.h" -#include "pkglue.h" -#include "call-agent.h" - -static int get_it( PKT_pubkey_enc *k, - DEK *dek, PKT_secret_key *sk, u32 *keyid ); - - -/* check that the given algo is mentioned in one of the valid user IDs */ -static int -is_algo_in_prefs ( KBNODE keyblock, preftype_t type, int algo ) -{ - KBNODE k; - - for (k=keyblock; k; k=k->next) { - if (k->pkt->pkttype == PKT_USER_ID) { - PKT_user_id *uid = k->pkt->pkt.user_id; - prefitem_t *prefs = uid->prefs; - - if (uid->created && prefs && - !uid->is_revoked && !uid->is_expired ) { - for (; prefs->type; prefs++ ) - if (prefs->type == type && prefs->value == algo) - return 1; - } - } - } - return 0; -} - - -/**************** - * Get the session key from a pubkey enc packet and return - * it in DEK, which should have been allocated in secure memory. - */ -int -get_session_key( PKT_pubkey_enc *k, DEK *dek ) -{ - PKT_secret_key *sk = NULL; - int rc; - - rc = openpgp_pk_test_algo (k->pubkey_algo, PUBKEY_USAGE_ENC); - if( rc ) - goto leave; - - if( (k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets ) { - sk = xcalloc (1, sizeof *sk ); - sk->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/ - if( !(rc = get_seckey( sk, k->keyid )) ) - rc = get_it( k, dek, sk, k->keyid ); - } - else { /* anonymous receiver: Try all available secret keys */ - void *enum_context = NULL; - u32 keyid[2]; - char *p; - - for(;;) { - if( sk ) - free_secret_key( sk ); - sk = xcalloc (1, sizeof *sk ); - rc=enum_secret_keys( &enum_context, sk, 1, 0); - if( rc ) { - rc = GPG_ERR_NO_SECKEY; - break; - } - if( sk->pubkey_algo != k->pubkey_algo ) - continue; - keyid_from_sk( sk, keyid ); - log_info(_("anonymous recipient; trying secret key %08lX ...\n"), - (ulong)keyid[1] ); - - if(!opt.try_all_secrets && !is_status_enabled()) - { - p=get_last_passphrase(); - set_next_passphrase(p); - xfree (p); - } - - rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /* ask - only - once */ - if( !rc ) - rc = get_it( k, dek, sk, keyid ); - if( !rc ) { - log_info(_("okay, we are the anonymous recipient.\n") ); - break; - } - } - enum_secret_keys( &enum_context, NULL, 0, 0 ); /* free context */ - } - - leave: - if( sk ) - free_secret_key( sk ); - return rc; -} - - -static int -get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid ) -{ - int rc; - gcry_mpi_t plain_dek = NULL; - byte *frame = NULL; - unsigned n, nframe; - u16 csum, csum2; - int card = 0; - - if (sk->is_protected && sk->protect.s2k.mode == 1002) - { /* FIXME: Note that we do only support RSA for now. */ - char *rbuf; - size_t rbuflen; - char *snbuf; - unsigned char *indata = NULL; - unsigned int indatalen; - - snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk); - - if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen, - enc->data[0])) - BUG(); - - rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen); - xfree (snbuf); - xfree (indata); - if (rc) - goto leave; - - frame = rbuf; - nframe = rbuflen; - card = 1; - } - else - { - rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey); - if( rc ) - goto leave; - if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, plain_dek)) - BUG(); - gcry_mpi_release (plain_dek); plain_dek = NULL; - } - - - /* Now get the DEK (data encryption key) from the frame - * - * Old versions encode the DEK in in this format (msb is left): - * - * 0 1 DEK(16 bytes) CSUM(2 bytes) 0 RND(n bytes) 2 - * - * Later versions encode the DEK like this: - * - * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) - * - * (mpi_get_buffer already removed the leading zero). - * - * RND are non-zero randow bytes. - * A is the cipher algorithm - * DEK is the encryption key (session key) with length k - * CSUM - */ - if( DBG_CIPHER ) - log_printhex ("DEK frame:", frame, nframe ); - n=0; - if (!card) - { - if( n + 7 > nframe ) - { rc = GPG_ERR_WRONG_SECKEY; goto leave; } - if( frame[n] == 1 && frame[nframe-1] == 2 ) { - log_info(_("old encoding of the DEK is not supported\n")); - rc = GPG_ERR_CIPHER_ALGO; - goto leave; - } - if( frame[n] != 2 ) /* somethink is wrong */ - { rc = GPG_ERR_WRONG_SECKEY; goto leave; } - for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */ - ; - n++; /* and the zero byte */ - } - - if( n + 4 > nframe ) - { rc = GPG_ERR_WRONG_SECKEY; goto leave; } - dek->keylen = nframe - (n+1) - 2; - dek->algo = frame[n++]; - if( dek->algo == CIPHER_ALGO_IDEA ) - write_status(STATUS_RSA_OR_IDEA); - rc = openpgp_cipher_test_algo (dek->algo); - if( rc ) { - if( !opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO ) { - log_info(_("cipher algorithm %d%s is unknown or disabled\n"), - dek->algo, dek->algo == CIPHER_ALGO_IDEA? " (IDEA)":""); - if(dek->algo==CIPHER_ALGO_IDEA) - idea_cipher_warn(0); - } - dek->algo = 0; - goto leave; - } - if( dek->keylen != gcry_cipher_get_algo_keylen (dek->algo) ) { - rc = GPG_ERR_WRONG_SECKEY; - goto leave; - } - - /* copy the key to DEK and compare the checksum */ - csum = frame[nframe-2] << 8; - csum |= frame[nframe-1]; - memcpy( dek->key, frame+n, dek->keylen ); - for( csum2=0, n=0; n < dek->keylen; n++ ) - csum2 += dek->key[n]; - if( csum != csum2 ) { - rc = GPG_ERR_WRONG_SECKEY; - goto leave; - } - if( DBG_CIPHER ) - log_printhex ("DEK is:", dek->key, dek->keylen ); - /* check that the algo is in the preferences and whether it has expired */ - { - PKT_public_key *pk = NULL; - KBNODE pkb = get_pubkeyblock (keyid); - - if( !pkb ) { - rc = -1; - log_error("oops: public key not found for preference check\n"); - } - else if( pkb->pkt->pkt.public_key->selfsigversion > 3 - && dek->algo != CIPHER_ALGO_3DES - && !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo ) ) { - /* Don't print a note while we are not on verbose mode, - * the cipher is blowfish and the preferences have twofish - * listed */ - if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH - || !is_algo_in_prefs( pkb, PREFTYPE_SYM, CIPHER_ALGO_TWOFISH)) - log_info(_( - "NOTE: cipher algorithm %d not found in preferences\n"), - dek->algo ); - } - - if (!rc) { - KBNODE k; - - for (k=pkb; k; k = k->next) { - if (k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY){ - u32 aki[2]; - keyid_from_pk(k->pkt->pkt.public_key, aki); - - if (aki[0]==keyid[0] && aki[1]==keyid[1]) { - pk = k->pkt->pkt.public_key; - break; - } - } - } - if (!pk) - BUG (); - if ( pk->expiredate && pk->expiredate <= make_timestamp() ) { - log_info(_("NOTE: secret key %08lX expired at %s\n"), - (ulong)keyid[1], asctimestamp( pk->expiredate) ); - } - } - - if ( pk && pk->is_revoked ) { - log_info( _("NOTE: key has been revoked") ); - putc( '\n', log_get_stream() ); - show_revocation_reason( pk, 1 ); - } - - release_kbnode (pkb); - rc = 0; - } - - - leave: - gcry_mpi_release (plain_dek); - xfree (frame); - return rc; -} - - -/**************** - * Get the session key from the given string. - * String is supposed to be formatted as this: - * <algo-id>:<even-number-of-hex-digits> - */ -int -get_override_session_key( DEK *dek, const char *string ) -{ - const char *s; - int i; - - if ( !string ) - return GPG_ERR_BAD_KEY; - dek->algo = atoi(string); - if ( dek->algo < 1 ) - return GPG_ERR_BAD_KEY; - if ( !(s = strchr ( string, ':' )) ) - return GPG_ERR_BAD_KEY; - s++; - for(i=0; i < DIM(dek->key) && *s; i++, s +=2 ) { - int c = hextobyte ( s ); - if (c == -1) - return GPG_ERR_BAD_KEY; - dek->key[i] = c; - } - if ( *s ) - return GPG_ERR_BAD_KEY; - dek->keylen = i; - return 0; -} - diff --git a/g10/pubring.asc b/g10/pubring.asc deleted file mode 100644 index 09b099bfe..000000000 --- a/g10/pubring.asc +++ /dev/null @@ -1,458 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.0.0e (GNU/Linux) -Comment: For info see http://www.gnupg.org - -mQGiBDVBlNMRBADeX96LvyNiop30YPeeCBJZzeqQuQ3yQ+SK3AHoXLQ1qsGHrdoi -HfHbVV2GfulRq+H/z97vUtA3APE2NZ7HuvBJzhXZCOE93wT59OZV8Pp5ir6TAEYm -dvPCgvjYmwQvKgvaF0hG4eyvQst7SaevFUGV+jEz5DQhniy+/a2/W7nC/QCg/2SE -nBeZNJnZauf9cXQ34GnXV68D/1BspMcbrpY/YFXsdLUSbroG0EXGma4jY9UlcRV8 -8cIftxl2jh04l91bvzzCFgSGvFdxVbHWnIgbQ+PQ1cme7SsS3ZFFI3B3zykXGOi8 -shhOT/Gip1Tk4O6MwTyOWdTdnEGSjk+qoVwEMxhY/ZZDd3bbUkymrPK5jtfumreB -JjqwA/wL5fOdCzLWBev4/Xks2YENg0HVwN3a3iypNNGZOYCWTZKnFX5yel/mqiT0 -uEn1CJ5w29GKxRax/Ua9kr7ftMhpQ8lZdyy4Z/Br0NiU9fgvmWF/2WvOMx+hHf/k -LRUYewxzOSLfapiM1SOQs/L+29tnu4wfAsezSuFfKjKVZHlx4rQnQnJpYW4gV2Fy -bmVyIChob21lKSA8d2FybmVyQGxvdGhhci5jb20+iF0EExECAB0FAjZYxf4FCQPf -GysDCwQDBRUDAgYBAxYCAQIXgAAKCRCQOaC/0TnMTJJUAKC0jAhA3fXI2UCbfZ6J -Ti3CL0bcMQCgpA7pEUYM7edUlxqFJfWYtBblS5u5Ag0ENUGU1BAIAPZCV7cIfwgX -cqK61qlC8wXo+VMROU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyD -vWXpF9Sh01D49Vlf3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5 -u/2RXscBqtNbno2gpXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98 -iLMcfFstjvbzySPAQ/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlA -GBGNfISnCnLWhsQDGcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqr -ol7DVekyCzsAAgIH/AlcnP6QSKd67ad/1lQpzMEBNyIX0X7//lns6XAGl/+U5Iqx -i+8sd+oJikFlgVH+n0JD6vq4dO8XCBzUgIi3xV2cuJqj16zVp7JdMXKqIxkDu5Q/ -By3/IL7WWkc06FxyDraigP1Hu3W78l0lySK8yEW+fVlkyzK6irkJ7EFWkSDaZqT2 -IrPd94hoGFEyQOIgkYdy2DHoK00nUd9FzIbhrrz2ZDJIfCMVp2go4oCu6Zk0LxJX -qTFU7K3SxVNN5jWsOCsPzWLyhKNrgnv8WzVaPKgqgMNdmdykAvC0iSTNat51p8Ad -4mGtY1nW0aOAiufjBTMUtILfHKsknItj/P2D4seITAQYEQIADAUCNljGDQUJA98b -OQAKCRCQOaC/0TnMTHKtAJsHojLJup9Niwsutt68U02uyl13BwCgpovl3ebeH41a -k2Kp37si/9RsdICZAaIENt243BEEAOCNfiVnzetemJ2DpFA51QnnGUihYs0beBQ2 -ptJP47uLlxsZbix2Gg3wDCP7HNgcEWlXc29vrd2oiA9nanKLcJzLYVL0lBBbPVX4 -8PGvRFKvJVHI17LWqpq3aOF8kOSf/4QyRIafWdGzxvAFycAiq2Bs1/B7BeUqmhWO -3FXs6VNLAKDqqMUc7apbVRFSV6/kbQ8PLTYw0QP/dRwVX9NtBEogFNoSU4jw1sRg -+nqGQplE9OXESMQO3fiszBkCWghsKk+/O+HcFrIiSAxRPR3y8nXCsaLQEf4WfrD7 -nKFeGWDIqPvi3KJOzuaqZP3DMf4LdfltmM/zHifZo4aBkkIQd6703vBFAYA0lONH -+W5qyx0ZnYr7XunDqkMD/2JC3cogap2H6IzaHl9oQegGKGwrCErBuJxCeL9i7h/+ -5Wg8ou6TE8kAGf1oMeeWwrWOBxub4xsUqfYk+mKM//O2OkCMfVFQgQQtjy5CtFQx -X5AErQ4Ukoy8XmNGOAi9ipWpL0450XwNvusaeff4D1ztJbCb+LMkqI9gYEQWSwxF -tCNKLiBNaWNoYWVsIEFzaGxleSA8amFzaGxleUBhY20ub3JnPohVBBMRAgAVBQI3 -RcCEAwsKAwMVAwIDFgIBAheAAAoJEAcDKpaJBMjiiuQAni3iUNjDvqvOQOlIgz1d -5ibjHrA8AKDWPy7kZN+W3Leptp3FYTIMTbDpU7kBDQQ23bjuEAQAl1Txo5tRemsP -8mNmoBlGQx/4EmN61ga/V8iBS7u7MvzI1zktNuHaK7rJItE4ilyGeivXitZ74eGV -7P2/rbNhWnOo1fMlvLvl8mDNmLD2nJovu4LVFXGhoYdGb75d2YbCCBN5Q/BSYh+l -b2wd6VewnqMy6A9iGULaAWz10G2IOYMAAwYD/iooRihzfIC6rw6K2kASGRiy/dts -3w0L9Iu5DsxLFH2tHUpv8fPVDuvGkRfwPuKaTHAvq90/I46/3BBTOOneMaW1+RAL -hM5f4ytsYNlDDerhRiuGyEjoGtXVjXye/3SwIxISrg0EO7UHNtr4rObQEfF69RcT -gjzKdO2n2WlP+7/qiEwEGBECAAwFAjdVLZwFCQHwga4ACgkQBwMqlokEyOIEvwCe -IHFkUaLTPmaZhAOs3yfwDtAC33gAn3f2BoDALaHL1uqu/unWQA1JZRTYmQGiBDfj -Y5kRBADMfdIcB6LbzfMZAe9+3GMqLgx5fUEhX9GVZIxb3w+ZBGbJGrERMtEigd+S -Y2xR9TWyhd/eVh80qcgGzA9Fyb6IOdVwN6HxtYdIz4CZP6ZmtSM8jecfbbKsf/Ol -BJQ6RZlAWNjE6F2r1D/gHpw1ZEl+lSlW3ObCEkeXBC/er/fIowCgwia77SmSgm3b -GgHEqfFQ8MID6lsD/0h45kDwi3K8WhI6lnZP0zpnNfA6753QaA9NqB8MY36YCVtx -OhBm7GUCgKyfh9zrTpZWwcBcAQyyB8Ld3K7cWi0uLy+gO2169cRApR0S1l6BlkbO -9wlv1zoRR1VT2gQCMGw6mjyne99v4Hst7UXV/nXvOsdrxdS5tTkAEL7Alzz0BACc -imFIsBD1CKqqN0fTdZooVrBZzpn6ZjTgzX1hKr61fuFyPgMkhzutN2jXy8tweCZw -FmN5XZ9cu7mxAdN9Xmwk7Kl0EGChwZdm7Sx9UTvu9kJnGOQvqtOkWB86Ts+r4fVb -w65BqcrZZzuMQrUqliM/YVUGazN/w2uyApNPByJUzbQ4TWljaGFlbCBSb3RoIChV -c2VkIGZvciBrZXkgc2lnbmF0dXJlcykgPG1yb3RoQGdudXBnLm9yZz6IVQQTEQIA -FQUCN+NjmQMLCgMDFQMCAxYCAQIXgAAKCRDKFfq6GxOtQUZWAJ40vGK1b1f2KN7u -BHOHLDAHvnuPLwCfXHyq3wGapWGDw6txlP9LMec1jf2JAJQDBRA342hqcwhlf6d9 -2r0BAenKA/d9luNiVpPciTyfM9W4GybmWSlLt0qxrY34WSNL5IOG6P2H335skdAC -xSUlwBSkD2IzoaQ0LAyGw0jsk8yWhfQqgjWxjZ0zcmKHZJZsMLwtvA4FeOSQuscf -kYsbA3vZWotYO1o9jyfAZTj0MeALzGEmxBeGUNiKUEnbBU0Lg+c8iEYEEBECAAYF -AjfjadIACgkQAJxC28xc8YI7iQCfboS4b2tqYvml31ouMT6XPHhTsYMAnRGQId+W -7mOHlWHvrddjwu8JHms6mQGiBDbYl60RBACxaonXMHpbmyzoQyxn7wYXGpEJZnKc -IWRc/sE++XSebUZMJOk09qkKhtg1TQ8D0Siv1/EjuqjoKP2f9+EOIW55+55vQsti -XwevF6pJBFYGGRluQPoFbUilDzCDmismFv0xwIEoOLftxvyvlmmw4Upx3/8TY83f -dQGzxSDvNbPEtwCguK4ARxZub/SQgLMy6S9/7itEfHcD/RXRVGmz3dDxXtgdAqwV -mY7RI+FOPQdn+DiFaaTjmqgP+NR6w5v72+jE5cdn/OnYmXQcERXc/4nZgWHdKmso -eLvLs0hpk9zFhgHkSufCWlo0ZYemaWRYrRI5mukGFIMbPdPEaySNQEqC78Rgj2wm -FJ2ttbAQlSRi332xTwFbzY4XA/9RppZOE9hGCh+2P4FgtHMgf7L8JUJVgR9tIKUv -GXjDkSWEqIMeyKeXFoPk5QdxNVM5sRYf6gmV6U3zHUOfEzlOf5GUJyPkmwl9RADE -6uyk4ySlW2d6+glsM0/Fd9Pyyzb0v6xfAPDFyTYU1X6vUDp0FyzPUijhbrdj4Fwm -fAVf3LQeTWljaGFlbCBSb3RoIDxtcm90aEBnbnVwZy5vcmc+iFsEExECABsFAjfi -yIQFCQlnNJ8DCwoDAxUDAgMWAgECF4AACgkQAJxC28xc8YKnHACeMFOdlg4xjXgE -FzyA7MQFxyXmyuoAnRCcbQ4bvEm/fxaaBFRnJgavm25LiQCVAwUQN+NpSnMIZX+n -fdq9AQF72gP7ByZG6W8yTz+1nv+CMvGIGLa4otN812X5lXvvIpH7bNgoWWD70xvH -5GP/Q5e3yUh4aGGN59uOVVQ5uoa3VFYl1ufWt2LvxaSW2q7f0FcvEref/5biu3gx -2O296DWENYPP3xZtaD+htaDP4h18RFBIvbZz9Ryp9C8myGEPQGcOxw+IRgQQEQIA -BgUCN+NqjQAKCRDKFfq6GxOtQfhaAJ9bMyNoYhAf3jkeMy1cnXoyr9ZbwQCfeWjK -xnAa+++nbYVEnuPP2gUdume0Hk1pY2hhZWwgUm90aCA8bXJvdGhAbmVzc2llLmRl -PohbBBMRAgAbBQI34siUBQkJZzSfAwsKAwMVAwIDFgIBAheAAAoJEACcQtvMXPGC -iF4AniaC76L0oLBvc0jA40NCXMDz4PX2AJ9RGPnHKf0XmaRXcTOlR8MiH1CeoLkB -zQQ22JgDEAcAqtpFls8cnLDIh1r6gSRf8sYiv5qd+a8CDd/LWHveWeGCeuBiVbwv -SG0q9ci13ZRIEtHXi0BVWLBpz/YqQCHJX4Vk2iV6yY7rCo0rFOEzyco+Glssjg1G -/ZCuVkGo4rpLKqOn6oXq92ojwBNjdYeBOOoZ78jp65gJ3OC0ckYanrRUe3J9bc0W -lAA+to/Dus91Ivkggu/iH5DEPrf/PQY14t7jxCcxBJCa8XaC04LrXVphPuuRziVe -gINTU02fdyrZlAyWf+0KZq5rMza1N+NwSxjkxBOzM+lbhA5PSekqHp8AAwUG/12f -DRpOtZ/GrKoUgkML8urMjxKFD4Hh6l1Wb5NCEe4tIm38yI+C/AwMCY5cDlf03YOZ -0ThTVjpvQfYT8EJuPbZ+2dGYEroY3OBLetcg6DDh4saKsVU2XSLHyCh2xPzOiusB -xNPrmvqd63S7JnRSSsEfgwYpKpA/GNMSJyyFpT4vtvK3jOON0v7uobYOBTLRuwj3 -OJMJfyQDa6WyiTJxUvsuQL0MK5cZG7oLUWTK9ZrFPuqzLeZAcpIgJ/QMJ/PnrRnZ -gUnXEbsnCVZ33NVBtiK/ktS2RTQKcvCNPtnimRqsiEwEGBECAAwFAjbYmAMFCQlm -AYAACgkQAJxC28xc8YJTTACgmUYdFZGR8pk9NbB4lpnKnum15WUAoIgDLWQA+qb1 -EPtpywwRBvqGOVUPmQGiBDgf7uARBADdNye00iQMSe4RULS0hDKVGNl1CFGzeol+ -AoNkW9bqXD3f9KNrWD11r9tef6C4OMN2fILO7cpD+YZwuHjXv6xSDAoZ31bmsxQn -N51YhwFhZRh8K/XheaULO9gedCZaXndQ8dvXGC/doKKOo/CNGK8gct+cPPr0N6cu -FztlgRpbqwCgm8u3ylalEvlWhXOjVYoTnEs04aMEAJVK0ZcYjHUdXWXi+TaDZCJq -ktk/r2E4M4/EsBTIkuAuy6RvPediVShRQ/CZl0MCQHM17ywdC+PXgOmQLeGbR8m8 -flK9HROJQebHB23/MK2knm/yKgqSJbtoDv23QRfZjNd1aox50uFLvv36CDMhAMQ4 -ENHrBzuj5bMZo8nMELVaBACPlGKAcAO2FP6DpmcJIXDnO+oVHvs4QMzADn+/aBQp -H3UQASAbu7aH/84SLBUH0h1Z9QNkKLuMtpC0rVHqRsw4d4FmOxoxvOF8hQnICiQr -2XRMDKZwR/+gH9Vh2XFRi4j/xHH2h787C6bKoOPd6UPJM1HdxNPQlG89fb4hgv/e -WbQ+TmlpYmUgWXV0YWthIChHTlUvTGludXggb24gU3VwZXJIIFByb2plY3QpIDxn -bmlpYmVAY2hyb290Lm9yZz6IWwQTEQIAGwUCOB/u4AUJA8JnAAMLCgMDFQMCAxYC -AQIXgAAKCRDj8lhUEo8OeTsQAJ96XKYFFJuwup2Mce9mDk6EOnEEdACdFp6gwm6x -T6Hm1FD53oKNgrnafhqIRgQQEQIABgUCOB/w/QAKCRC+6Lh52/bl/+myAJ0UubvN -9ydWvrdgkKbfokKJTrOC0wCgooxVzceD44Oo/C1kaHjXv5yFQeKIRgQQEQIABgUC -OClPHgAKCRBd4kmWWwNYol/nAJ0YXC3/sGqBaddoLqoLpo1kapcthACglrEi6n5z -6OcQO+II4Fe6wFOisYu5AQ0EOB/u8RAEALec6/ux2Py+0Wv/w5J/VmDzUNDOHQJM -kxTEQbp+vZ80Quf8FoMy8i9PciekoDl+oB8/zQDs92SgqGVD0+y8K9UPIEvmifjr -oPn+EsIrXf8M7dGGotCtwaiEwDxwmetlQMYLd84XqLj0LgGzdT3/7dMurhUiGZH7 -dpWMfUZAVNjHAAMFA/9iLg3F0Bqi1dVDeCMqOVCOcWKhulFG80il3TwS9Q7SpvJX -/4yZyoEdyJ/VYm4PakvDUyiy4MuhsvGSwCEyXD4IskEkmlf97jDoBiiktexkjlKI -vmp7P0XNQMURXFLqDilI9YY2jVAu4XNw+G0G1ImGgzbadbraUl1J1uJtvg+NOYhM -BBgRAgAMBQI4H+7xBQkDwmcAAAoJEOPyWFQSjw55J58An1UbKjszsK+9Awtz3a+5 -gNiuzdo5AKCE5Pv3w56DMeZLH8GyZkVqo1QsrZkBogQ3KcaNEQQAsRxnSrRpASl8 -e0lOtR3C7I1MoCuivlawh48JzC9WXgA/Pgn+VOLiDDob/zjQoNbBEoG+BHrwq+AC -CVBQFAiMMNur8u7qY+R4eLWD/KDKaNcydchdKehw0eiy7d9mv0hTHSmkUIgIpy4k -d+XvsbozP40+/G+yNjGEHvJf3tsO8ocAoP4wWPnUPNwWkuKn41tR3cb2m+ZlA/0Q -lIn4E3Na3o0AhhuLC3YrJ4X4rHJmUJg+i2mS3lJCM3HPJRCdz/eIlU4WiaBpNPve -PMEeg5KSluqdYOsCvBa6XsAGm8gxQ2Wzf6ZqsXdBxztjwXqcLeuBKFfuDUlwloYI -Rie+naIgPasYwu3ABG4peRJmc8aRXJCg39rE8MK4BAP+Pt+NqJQw9S9ykLDDIXDD -ucH7YOBxfvUo18lPr+iNuPcbXh3fQQoibk4qK0w699YLGD25KizP+FTiCrD2fy9i -knUplevJkGDTdeDLrAPYVYTM2hryLPcisSP55Yf0GW6SnkFbE5LKYHo5YQF+9rvp -yUCR4xXm6CXo9m9FKBuuk5i0Hk5pa2xhcyBIZXJuYWV1cyA8bmhAZGYubHRoLnNl -PohbBBMRAgAbBQI3KcaNBQklmAYAAwsKAwMVAwIDFgIBAheAAAoJEHUPZJXInZM+ -i40AoIykcWzV7PpBoEG4MbTXTNpKBeTIAJ9tJcXW7S/ox+iJGOrBXgSlB7bXnIhG -BBARAgAGBQI3NDnLAAoJEF3iSZZbA1iipZEAoKm4vkXn0/4KC0aZp5o2U5zyErZe -AKDF3mdMyHEumx4xSWJyX4TvDZ+3ybkCDQQ3Kc4MEAgAsgkRCXJQLlHgk4Fu1Jk+ -UKEDdMZYufSOGR0D57WxbRtArPqDMox1NqFHGi8Sg88TtDwH6/BnGkYCOuBQidaE -BPQtl7jeU6fQhXL4kRY3KB50/ChzzUB/G+LsT8COCUIsNDiBQxwEiLTEOMFAqbRA -ugQhZnUKrf0auZKnB53RPhAuIdGozC+k9+vJl0l76e+JcVr8AL6wWBQO00UbKgp+ -MKiWjFDSYIFtMNrXO9rfHW1n3jW79bvAVyFl9rwEbL0gbSWmaZKXIWI7D11J8aYF -3ppDk5UsCc0Cs70okV9d58s0PjnTqwAcVxZcyoO81qJVOPesRVJ4jURdGeSBTqNM -rwADBwgArjJRLMSTveaC2tELGSr7qBioUJ9FbFk0A5D8vH3Xcr34E/m0sgNGJSD3 -qWQNXN0OpH7hKdeiwEPLE8gR/Tnxwgb+r3S0dBViktQPMajdW5S/dJfusTdqBzo2 -LgdZ24lVl1O0ZKci+6SVWt5SBxbAYYtgSEjiGhbWUDdQoC52yNGUQvG9wL5OD1BK -y94wzKQZi9WV/NdNfJPMjZv+tx3pezfGYTPDnUpP1CoLXY/gre+APwr9yHAg46Hz -F+DQT+KAWQDTxahEUk9OE86nR3gO0zNN2KzGKb297ikcLWYusW9QQ46X3uIBTYmK -PZP9l/bR7322tj88GPaKPesZE8rR2ohMBBgRAgAMBQI3Kc4MBQklmAYAAAoJEHUP -ZJXInZM+GUwAn2qcZ8hOcrD1Bw7zZofZ+xm8wDL/AJ9DJQbxAae5kKnBDG1O28B4 -J0wF45kBogQ14HkWEQQA1qRbEQxVQzxv1QAvAgFoW3nT+BbWAs5fenhmvkWIMunk -xhB8cIeYaImzmdDK0YioSgQ03ER5O4x5AcVKXiUJKUWqIermAqSCk6W0z8iWD0Vu -boP8JrAJ6hd5WCWPpzb41OJumi5Xy3RzWdYWq2IOXOVZM2Wt1gnXA7p2PxS+ZqMA -oKLnKFiDGdQPqKH5zwG488A95X9lA/4mkc0LBxfBIipWEE3HzgkcmNRb0zdxzUGY -TGrHIYK3i7TZrfq09+jTA1dMbs2tX/nbUdd1oMaKefCqBw3hD50E685bla17TPFh -NXhBRCCGhH8IGGAg0o6P3B0+QQHJsp7eof/VKgIFN6NeXga+621vkal5eU6jHQ44 -sHHkkkk0fQQAu8a0B2kf4VFHIE4kDraDPgIkhWV2r7efsLJj671NOKBHOMzWB+PK -0eh0b6Tc34n44lyH6Cmc2F9xUzk7POa/uEi8aPB1z2/NdYeFg6nKTrkN4nYnQtYr -GG4oPgeX0+DoNHmlRJto+pYMU8PwJA9fCT1K+szRr5p072LImZ7lsk20LlBldGVy -IEdlcndpbnNraSAoRWxHL0RTQSkgPHBldGVyQGdlcndpbnNraS5kZT6IVwQTEQIA -FwUCNmGXiwMLBAMFFQMCBgEDFgIBAheAAAoJEJg0ZdshQ5Qir60An1Zl/jBAU7Cx -XINEaZupk1TmkdiDAKCFGR9orHjfKgw+xEA+idd/Ls0lDohGBBARAgAGBQI3pyH0 -AAoJEF3iSZZbA1iiXRAAnRCydbPV/ipvi0NfEzV9+RC8lBxNAJ9jQwXwCKt0HVc8 -/Y3OVY/WI1LnTbkCDQQ14Hp8EAgAoz58r9ogDLeyaL8NoMXoMhJ0ogHqC0jzt6xa -zw/h6t0AJE1He5tMF1yVkenXo+sah2oTjrm38fRVXODbACvmn1oP+WLcK7/bG82V -Ol4Zv0Iu+8X1KzXz2JGae+h0ogNcwyW7CXfPSEVhrCBTY7i7mdnAoyGFoW0yFSvt -8YcRXdN7GU16tdATfruMV276MuStGwNIWYYfjFtqwFBdaVOpwMfJs2golT7PLEIj -O2l1u1ZtAI6WvuEzQH4ftzzihmHQXMf4YsvtL5g/8TSJfmfUEFbbKFbU5bIbHzG4 -yj/O8uEBBj7u01oGpu/5UVFTgslvTIEAWx54sfT/oA06PvhsDwADBQf/VWZUn/wC -/gktKZfh6Aq7RRI2K5bJEXhXE5p0rPWLMQy+v4DPGcuDF3nLg1IZT5mbLUGEh+7n -zEgUsmLGPqBz54DgjhBxO1DfAfV3HVnYYpL7DO1u4ceCUh2O9PwLnp1+4W2XmND5 -nFrQ6gGChCgwb79/PxQdLEgj9dlf+vrv5SfajmTydiFCZ0+0GZRFDytdIda08TWv -DabV/41F3T0TSbCMGPWr/TgrfQ6yeyOUpO9lmVbS0u9gKWGAedVOofMYi7Lqp+Pt -zNQTwd9PKCP/HSjUxmm4xX3yVZuUxUV97ckucB8TOlr9deNnq32jnMuP9DeWpBz4 -05uwoBLYvOGNAYhGBBgRAgAGBQI14Hp8AAoJEJg0ZdshQ5QitJcAn0sn+TIAlbNC -3YS5YxlYbExg6UnxAJwM+TJoHjFG8+rZ0nW7/vVq6+hHl5kBogQ3zBNgEQQA7vY0 -FBndb1BOSmisOzqCtcqwzP7iMKF+hwEKDqRKrO/oZ7zqMXigROEDb+ar95oSh2EX -7tETk2b8ga9LA0UxT8nZ8e4eCOOchNggLyX4ZpsyrVTMGwahnjf8KsepIaKqfEnQ -lzE4KsnLsuC+LKodhDUoInZIn/9bC6cRrCfe/xMAoJdLRTMDNe0+ruy2LtnwQg14 -vRp7BADm9fBrVW89COBepWr/xVQ89mDA23oiAaLrKjiJb8LQg9NpmGa5AFuWBym2 -Y5MzjremPeqmjMfXGyXIu5o+9e1k5DQ72NB/m24FdrYkCW38sinIVVghDtvzLniG -fOwBL+c0iA0BweBCNuouoJjJegPQbzaliTgcV8ZjuCq4juyp4AQApBN45mj8JIwZ -wbsNnAmZ4mtv3gR03k20Tk4uCurktNjd0HvU28HOyg/ZehxeoKMd14R/8NZBE39W -vzJHnAVzfcsmNV1SQS7fSxD2f0FsWYxfF2ErBhwhK3GIuKAujPnlzjT57ZnhzBuH -cALohJ1izyVOcBwFIAc+mwZSBRAKILq0OFJpY2hhcmQgR3V5IEJyaWdncyAoZ3Bn -LWxhcCkgPHJnYkBjb25zY29vcC5vdHRhd2Eub24uY2E+iFsEExECABsFAjfME2AF -CQPCZwADCwoDAxUDAgMWAgECF4AACgkQNmdg8X0u14ixOACfcmzB1f4YZ2yC0jyX -efVFtbIZ/fMAn35OwFji+uU6/BFLYXnsMlsJMsOMuQENBDfME3QQBADQcXxUkW/f -6s6S7RXOUIIV9CgHiZpHPV7T23wQhQOOtVjO2akFLryNI6Z6a66JRhS6fRa3+eiL -9TB0umC8e297dHrzObs43bf5h7sTJB8xHTUI9v4rlMwC8Bk3oghnoCJ820MADttR -p+CUWMkPaBQoDTJJhyfju66lgxZoycLVMwADBgQApLUhOmpHB+zGMvluBUJgBEja -Z553bU/gLzRsTCvt1gnIXLjxYXkiKjLyXfym47mXNaGUGWC7b7yaMVjhfnF3bJ5t -xeIiL7/p3ei17aYOlzXx3MhmuPRhS1IJbXfXChPc7toCqDeSFmnGmVWJZ+zuleTm -OITYkgt5Lshp/N1NZXKITAQYEQIADAUCN8wTdAUJA8JnAAAKCRA2Z2DxfS7XiApb -AJ94BeAKtqsshjVPWijCZ/8SBcJogwCggQjLX5KwZzhHASEXQ/oMvAgS6OKZAaIE -Nuv2vBEEAJttf93iMoIaranZOJ8AR0V0ax+4bTo61nQ392tjaRiPv+9lWuY1O3rv -pHTzTtXP5Qtz1Uw51jn5rDAA43mwz0+cR93g873ecb41/9LRKF8I9CbmZO6N70Re -mLdGb4R1FQ2gMHAwIz+Z54esABLQgq1qUZ66k1+TL/3EZRLnRSk3AKD8fayzCfyw -Vxgy8C67Z35FdBsVGwP9HLfVXrDoAkl3St52A9cIqYKCjWk7Hbv3mdNZIz8pEuhY -7BlpPeMwP9p5cEqlTMjaQHfefHwm1K7GthihkGAHyWM2iZLZSQzIFPG1ER+feTCA -VjSSbvoDGyhHbW+uhGYaNwSLQC36+NrC6ULoTq6Uh86Klpa7mJzLAq+b/6XKhR8D -/jzTElA97kUJEzdpbm5YtqDsu9H16Zdlf+jO59MNi2rcElt3w+thNfucNHVo8fm0 -FGgTpXwNss0Ej4cBXKc8m1ujAWG/hC9s9MMaa1uUgbqngGhZrOvcXXFCJZwoWteW -K4rqucRx7BAl3hyQwl3KK8TY60Te329VBIcKJyVvb7TFtDFVbHJpayBEaWNrb3cg -KG9ubGluZSBHbnVQRyB0ZXN0KSA8dWtkQGthbXBzYXguZGs+iQCVAwUQNuwRdSDu -hu1tZgc9AQEAzwP9HnvIc9zYRmjQEsB44Aik6/pQvrBsSpLNzAWelEaMw6bFHaQT -1PtMnpFmGxbJR6MBBsWku2armlC8G4EUVn9AR07BtXGVGfn8xsHs4MK77QPO7C/I -eqOdotrEYr/OmpXMjBHTfB3B/9vu1p4+ubA8jrY/9DKxRLeWtoJcT19Pe/+JARUD -BRA2744i2gTMWm1DVDsBAQohCACL7/fi/RR7eZc6c0aXEqdytMmAoIg/056jdhwe -OiJITmXxDwNzaDbofOMWGm2IbDb3XfAU52WmKRsnlUFZFWEmHQurUaApx6xGqQiG -wJC38sBS+CfbMmhbvWBeu0XI4V/F/wfzpxYCbELULEHsAeDMXCa4TLhKfmZdrde5 -1RJgK+bNZx/HVCwwU5YtGHbyJ/lYDlg8FxxRCPAAb31mSviRJLLrdEwPWWdi9lGr -G8kp10nnDsfl3mxlItWKAa7ey7ntYi/1glIxSdqgXhfKiXCgZLRC98cQMyj0J3fY -HXF19fkugPCCx5itawmWLeS7sKAkMKBmsqcWKaYp3oy8WnR7iFsEExECABsFAjbr -9rwFCQF+UwADCwoDAxUDAgMWAgECF4AACgkQ9u7fIBhLxNmwfgCg6vEPiWfYZ4Bt -tUvCbLqw7qxl354AoMzEob55S7m8YjrkDP0iimJfHsKliEYEEBECAAYFAjc0ONQA -CgkQXeJJllsDWKKeoACbB7pifCZOprEAEwLyaJmaSvYOvUkAn1CaMjj9cxhwQxLg -7X1Db3FTm3PbuQINBDbr92cQCACHpMcXbJWET55YL4vcHhgZnlzdthEHunAp0EG4 -RznS4ESJX7D2Ll2jO74fD25XFQ/6HsvZl+ITZhMMDW5p8lTfniVBPRWRQaVSzjzw -A0UykQVSf093unT7bSIsGZAMmUymD1ucG5Jh0eHGQq4REmBuvSm6CKh6JRmAJbyk -TKWhfagX5TN0+mHD+CcFKzsgorYRh7KNlFLB6idtAZxFqdhHXkI64kysMVFt6ZlA -2CV5LCQy8m1lLc0WuXM58tWDZ84UeBCJfO+5N8EwkS1S4dRWouOxFWx8nJpje0NP -tb/vyZRQ+JMClVaKOLjmC017k4F8XxVYNqZ7Y5TWmr6sl2WnAAQLB/9iaLQ3eGPG -9GWv9pp/wAYIYzMiDsokdHXf7gOifZXG1DT3Gn1gXqgJmYP3DQN1l6b7NboH+ekB -Ua4D1Y9glIf4/HbdCtv6fGFGv2JWDwNWkU1H88ZrDmwAxcOS9vu9D78ElnACrV46 -OOfmc0PnDseZCgGSuAscXU8YM/zLIGFMvmeALzHxPVOLrLp/Ep0+kGNKdEEDV5ht -5F81uOpTMNkacASAdUqS5iseSjITYbo1sk4j5Fn8pTTn0U9445b/KjKiEH+jbn4x -fPcC03FaXvMnFP+1nAqLbgFmVJ2ljjgEBbgkDPumsrjIuU2ZgSN9CZZ4tQke/FU0 -7RttYHde48eziEwEGBECAAwFAjbr92cFCQF+UwAACgkQ9u7fIBhLxNmnUACgrtAG -GLWPUQbGR/6OQa9AZ6xLhnMAn0SZudBARwp97yCM3Wcm433S6xVDmQGiBDWiHh4R -BAD+l0rg5p9rW4M3sKvmeyzhs2mDxhRKDTVVUnTwpMIR2kIA9pT43No/coPajDvh -ZTaDM/vSz25IZDZWJ7gEu86RpoEdtr/eK8GuDcgsWvFs5+YpCDwWG2dx39ME7DN+ -SRvEE1xUm4E9G2Nnd2UNtLgg82wgi/ZK4Ih9CYDyo0a9awCgisn3RvZ/MREJmQq1 -+SjJgDx+c2sEAOEnxGYisqIKcOTdPOTTie7o7x+nem2uac7uOW68N+wRWxhGPIxs -OdueMIa7U94Wg/Ydn4f2WngJpBvKNaHYmW8j1Q5zvZXXpIWRXSvyTR641BceGHNd -YiR/PiDBJsGQ3ac7n7pwhV4qex3IViRDJWz5Dzr88x+Oju63KtxYurUIBACi7d1r -UlHr4ok7iBRlWHYXU2hpUIQ8C+UOE1XXT+HB7mZLSRONQnWMyXnqbAAW+EUUX2xp -b54CevAg4eOilt0es8GZMmU6c0wdUsnMWWqOKHBFFlDIvyI27aZ9quf0yvby63kF -CanQKc0QnqGXQKzuXbFqBYW2UQrYgjXji8rd8bQnV2VybmVyIEtvY2ggKGdudXBn -IHNpZykgPGRkOWpuQGdudS5vcmc+iF0EExECAB0FAjZVoKYFCQhtDIgDCwQDBRUD -AgYBAxYCAQIXgAAKCRBot6uJV1SNzS4+AKCHdeYHMmKQV9mC7REE5Vz6d5rRBgCf -VMcyRP7dxBwhytmwCDpAcCFvCLSJAV8DBRA1oh5DA28RuP8+qgsQA2MyBR0eiPUo -vYMz0DUXBbNs5606eaVeTJOn9WqkYGcS9xOKlGd8Xj0IcAKN30st5AsC5hRqr82r -rUjB5/CuVdbvk+Qkh6ixWCqo+RRrbgf8cKCg1x+lDj9PpeSD/B9UU45ntxYamoXn -PszxtzU+e73Nkbtrej5rgMK8tgTLkhTAbO8M15Mgtw2yOeDFfiCj4xzDkYryvLiP -I5p2vYXTVcgYnwpNRnMZBwUghb1PMSXj7AP0P/8wnpb656yIjH2OAkE5is5HvTEs -2wGUCEXXYKxgLIl9bRPGd2DHfJQ6broxy1RHVmaOrOeDibspx67RRTm3WqbtLiK0 -/nRF0gEjFGxLjQiy92gp6xLRiQsMQdkz0Lwgr0dgSs6JejBlsQPp5nXXkIm9q/hl -6Cly3Zx3KbAIwO5ZF5NyBciezCxSurg64xmxibNhSknblI0vyG+IRgQQEQIABgUC -NaInPAAKCRBsfuG4YhzAE37WAJ9Xzmig1DrfnUt/KwfgidkPohJViQCg0T6afKuR -spWzPAz5TKQpVjd02KmIRgQQEQIABgUCNu1ObAAKCRBd4kmWWwNYomq2AJ9+alN2 -TpVRAhCxP91eqvfEN9HgGgCgrTvpWnB9EKtROr+AT//cujKCyIaZAaIENaIg8xEE -ALYPe0XNsPjx+inTQ+Izz527ZJnoc6BhWik/4a2bZYENSOQXAMKTDQMv2lLeI0i6 -ceB967MNubhHeVdNeOWYHFSM1UGRfhmZERISho3bp+wVZvVG8GBVwpw34PJjgYU/ -0tDwnJaJ8BzX6j0ecTSTjQPnaUEtdJ/u/gmG9j0218TzAKDihdNoKJEU9IKUiSjd -GomSuem/VwQArHfaucSiDmY8+zyZbVLLnK6UJMqtsIv1LvAg20xwXoUk2bY8H3tX -L4UZ8YcoSXYozwALq3cIo5UZJ0q9Of71mI8WLK2iFSYVplpTX0WMClAdkGt3HgVb -7xtOhGt1mEKeRQjNZ2LteUQrRDD9MTQ+XxcvEN0IpAj4kBJe9bR6HzAD/iecCmGw -SlHUZZrgqWzv78o79XxDdcuLdl4i2fL7kwEOf9jsDe7hGs27yrdJEmAG9QF9TOF9 -LJFmE1CqkgW+EpKxsY01Wjm0BFJB1R7iPUaUtFRZxYqfgXarmPjql2iBi+cVjLzG -u+4BSojVAPgP/hhcnIowf4M4edPiICMP1GVjtCFXZXJuZXIgS29jaCA8d2VybmVy -LmtvY2hAZ3V1Zy5kZT6IWwQTEQIAGwUCNs8JNwUJCCCxRAMLCgMDFQMCAxYCAQIX -gAAKCRBsfuG4YhzAE2kgAJ92JKU+YcYHoRhX51+4s3fnPIyNEgCfaiWeoyb15xgd -O6etGiD2MYCWy5mJAHUDBRA1o3cUHRn0wQyYV6UBAT3zAv9HMaPuMWFQKZRTtJyG -Mo0ID+w/DtLn8z7CMBd5L2+2+RTTY36fgwITehtBziIJC9xrFrQnx+VB2pYvprTR -SCg6U7a/hf5T6WT9zj887C2UuIWE6pjLNTvwAqvGsSoAIpWJAV8DBRA1oicOA28R -uP8+qgsQAwfcBR9Iuppp+q1mChXqSYV8oROMFqkTyQJ736IllJ7Q6eGiEMrOpTkY -oFVyFqOJOEivxR+fWJ8xe+e/Kq02Vv0XANGyKias6mqrDnU2BBWuPXAo7y5wVuDn -myZS01LP555lNBVilvDsMC/qQrvHe3y0kp4IAbK1EMG3qbsNHCaHLRTwM+U9Z0CY -nkClbB2gjcC9nbtF3nzoBebowdYytat6eFMrBfYRHAUfZbRN0x6/or+I7WV5gtT+ -GrfVuSxVrGLsK9FN8iXGikiqdL/8BhFntif4BUGdIQdft+UawmT4IlrBL/Owh2hu -l7UPtx4YqwQibGIZjopFSqBGp+j4VFUdapVxMraQLd/PUwZ78nHgF/IXBzhN3Yrh -ryCxIGHrN4MN7OWZjO21F945tga1/FnIXsVBVECLiltnC9+/TBV0fE28aVca7EWB -P+Ix2QWIRgQQEQIABgUCNu1OCwAKCRBd4kmWWwNYonyaAKCxLBsteoVfwn5g5Lug -9QgVCMV76QCfRgQKXQv9zl4oO7Aa1Qljm9zEM3C5AY0ENs8HCBAGAPc1hCpuXmaT -DAUbIqS9CFHkihMnilIwAV+L2Dbq5eOPtoemPKx5+6xtZfzzY9/VCVwZCxY9Y5PE -N9r/twUA478L/FOXv5E4BpX+4R91klt/EZGcNfDl2Ar56FpGJ3iLg4+vxx9m1TV5 -k2nNOUZAVD1L+MoapWhaZFXLMChrhDUcbo7/1Fr1Rfv9j/LkkIJJhqf3G8HzE5Av -CQVSywUayYZdbmqdiY2bklZJVFAXs1X9zSTGoFc8eOxz6i1ZeMq+GwADBgX/T7o5 -R+SOTlJ72ac/g121f1kFX1dbRkQq2pCI95qTehp1AxdSwG3ur2slFCfi8ZDNUqkF -XJrsv5mh1yfqq7zS5T6lGT5lOXCDZbAO2wqNZY1VKeeCdcvD2VMeh8XxJfy8y1ZK -/iE1p8qnokYpA3nFH+JIsdrXk5ceiN3nKk+aDamUkV1sJzeEm5F7QHe60oBKbVGI -UF4EhGq6daVyeCeK4KhWuPYyiEgyaq5/xJZbR3uRcdW6X5AiGJWJOOQoGvWziEwE -GBECAAwFAjbPBwgFCQbzyQAACgkQbH7huGIcwBN5FQCggakIOYzLX3lNq2WWgcAk -SNm7kpoAnA69b3z2E5vxyD3bhggVUDX7j8hruQGNBDWiITwUBgCRCYCU5eLFvzCt -rzesTWLssIQ0vOW8FlYoFc3g416VkCeeQ6bsipGMyG0pEk3vnOpXIpRpTAMqOl/0 -nkra3vmZLEG2ds1Govdeh2Mcr3c5wBSTPdyLuK4L9vbgkjarhd5Ab+/hhHVWh0zT -MRDUgLQkKrg+Xf1BnJcl1kKtQW8xxermu41KV3O0GpMUVSIVuTDUW6D9nJcm97YV -VxuxFcWsHsQS7L6KJT+Rn81WIqTQvhPopEdWwSKuI2UKKJtbX18AAwUF/1Nu/rso -UwOsupBqf/ShJKh2MNAoMaq2iHspBggo9ep+pPxx533J3kwsXA8p/e3sBYbW5xbb -HXXwA1iQ9JTXbZROd0+xrHRxjheRofFo3Ck0UKi0ZDRRFKHEo2lypt1+/L7V3ymk -Rq+A7LGdXUk6QuNkkvArxuDEV1s9ZywkmeO64fc/DPzsLNOA5JhDEw+cjBBzHlu5 -khXk14Qsm1xtt3dFW5or8ZCG3xAmm5dKOLw2XUWKFgOMAJHxNpGUCHnQaYhGBCgR -AgAGBQI4K/uDAAoJEGx+4bhiHMAT2FMAn1xEe77uraGTGkV+eiTiZGKyh8JOAKDO -g+M0i5iKJXr7AsHmjXXsw1Y9kIhMBBgRAgAMBQI1oiE8BQkHhM4AAAoJEGx+4bhi -HMATDfUAoLstR8cg5QtHwSQ3nFCOKEREUFIwAKDID3K3hM+b6jW1o+tNX9dnjb+Y -MZkAbQIwbYOUAAABAwC7ltmO5vdKssohwzXEZeYvDW2ll3CYD2I+ruiNq0ybxkfF -Bopq9cxta0OvVML4LK/TH+60f/Fqx9wg2yk9APXyaomdLrXfWyfZ91YtNCfj3ElC -4XB4qqm0HRn0wQyYV6UABRG0IVdlcm5lciBLb2NoIDx3ZXJuZXIua29jaEBndXVn -LmRlPokAlQMFEDRfoOmOB31Gi6BmjQEBzwgD/2fHcdDXuRRY+SHvIVESweijstB+ -2/sVRp+FCDjR74Kg576sJHfTJCxtSSmzpaVpelb5z4URGJ/Byi5L9AU7hC75S1Zn -J+MjBT6VePyk/r0uBrMkU/lMG7lk/y2By3Hll+edjzJsdwn6aoNPiyen4Ch4UGTE -guxYsLq0HES/UvojiQEVAwUTNECE2gnp+QqKck5FAQH+1Af/QMlYPlLG+5E19qP6 -AilKQUzNkd1TWMenXTS66hGIVwkLVQDi6RCimhnLMq/F7ENA8bSbyyMuncaBz5dH -4kjfiDp1o64LULcTmN1LW9ctpTAIeLLJZnwxoJLkUbLUYKADKqIBXHMt2B0zRmhF -OqEjRN+PhI7XCcHeHWHiDeUB58QKMyeoJ/QG/7zLwnNgDN2PVqq2E72C3ye5FOkY -LcHfWKyBRrn6BdUphAB0LxZujSGk8ohZFbia+zxpWdE8xSBhZbjVGlwLurmS2UTj -jxByBNiheUD6IC3u5P6psld0OfqnpriZofP0CBP2oTk65r529f/1lsy2kfWrVPYI -FJXEnIkAlQMFEDQyneGkWMS9SnJfMQEBMBMD/1ADuhhuY9kyN7Oj6DPrDt5SpPQD -GS0Jtw3yuIPoed+xyzlrEuL2HeaOj1O9urpn8XLN7V21ajkzlqsxnGkOuifbE9UT -67o2b2vCldCcY4nV5n+U1snMDwNv+RkcEgNa8ANiWkm03UItd7/FpHDQP0FIgbPE -PwRoBN87I4gaebfRiQCVAwUQNDUSwxRNm5Suj3z1AQGMTAP/UaXXMhPzcjjLxBW0 -AccTdHUtLi+K+rS5PNxxef2nnasEhCdK4GkM9nwJgsP0EZxCG3ZSAIlWIgQ3MK3Z -AV1Au5pLKolRjFyEZF420wAtiE7V+4lw3FCqNoXDJEFC3BW431kx1wAhDk9VaIHH -adYcof4ddmMLQOW2cJ7LDEEBW/WJAJUDBRA0M/VQImbGhU33abUBARcoA/9eerDB -ZGPCuGyEmQBcr24KPJHWv/EZIKl5DM/Ynz1YZZbzLcvEFww34mvY0jCfoVcCKIeF -FBMKiSKrOMtoVC6cQMKpmhE9hYRStw4E0bcf0BD/stepdVtpwRnG8SDP2Zbmtgyj -YT/7T4Yt6/0f6N/0NC7E9qfq4ZlpU3uCGGu/44kAlQMFEDQz8kp2sPVxuCQEdQEB -c5YD/RixvFcLTO1HznbblrO0WMzQc+R4qQ50CmCpWcFMwvVeQHo/bxoxGggNMmuV -T0bqf7MolZDSJNS96IAN32uf25tYHgERnQaMhmi1aSHvRDh4jxFu8gGVgL6lWit/ -vBDW/BiFBCH6sZJJrGSuSdpecTtaWC8OJGDoKTO9PqAA/HQRiQB1AwUQNDJSx011 -eFs7VOAZAQGdKQL/ea3qD2OP3wVTzXvfjQL1CosX4wyKusBBhdt9u2vOT+KWkiRk -1o35nIOGuZLHtSFQDY8CVDOkqg6g4sVbOcTl8QUwHA+A4AVDInwTm1m4Bk4oeCIw -k4Bp6mDdW11g28k/iQEVAgUSNDIWPm/Y4wPDeaMxAQGvBQgAqGhzA/21K7oL/L5S -5Xz//eO7J8hgvqqGXWd13drNy3bHbKPn7TxilkA3ca24st+6YPZDdSUHLMCqg16Y -OMyQF8gEkX7ZHWPacVoUpCmSz1uQ3p6W3+u5UCkRpgQN8wBbJx5ZpBBqeq5q/31o -kaoNjzA2ghEWyR5Ll+U0C87MY7pc7PlNHGCr0ZNOhhtf1jU+H9ag5UyT6exIYim3 -QqWYruiCLSUcim0l3wK7LMW1w/7Q6cWfAFQvl3rGjt3rg6OWg9J4H2h5ukf5JNiR -ybkupmatUM+OVMRkf93jzU62kbyZpJBHiQZuxxJaLkhpv2RgWib9pbkftwEy/Znm -jkxlIIkAlQMFEDQvWjh4313xYR8/NQEB37QEAIi9vR9h9ennz8Vi7RNU413h1ZoZ -jxfEbOpkQAjE/LrZ/L5WiWdoStSiyqCLPoyPpQafiU8nTOr1KmY4RgceJNgxIW4O -iSMoSvrhc2kqP+skb8A2B4+47Aqjr5fSAVfVfrDMqDGireOguhQ/hf9BOYsM0gs+ -ROdtyLWPtMjRnFlviD8DBRAz8qQSj6lRT5YOKXIRAntSAJ9StSEMBoFvk8iRWpXb -6+LDNLUWzACfT8iY3IxwvMF6jjCHrbuxQkL7chSJARUDBRA0MMO7569NIyeqD3EB -ATIAB/4tCPZ1sLWO07g2ZCpiP1HlYpf5PENaXtaasFvhWch7eUe3DksuMEPzB5Gn -auoQZAkuhEGkoEfrfL3AXtXH+WMm2t7dIcTBD4p3XkeZ+PgJpKiASXDyul9rumXX -vMxSL4KV7ar+F1ZJ0ycCx2r2au0prPao70hDAzLTy16hrWgvdHSK7+wwaYO5TPCL -5JDmcB+dHKW72qNUOD0pxbe0uCkkb+gDxeVX28pZEkIIOMMV/eAs5bs/smV+eJqW -T/EyfVBDo7heF2aeyJj5ecxNOODr88xKF7qEpqazCQ4xhvFY+Yn6+vNCcYfkoZbO -n0XQAvqfa2Vab9woVIVSaDji/mlPiQB1AwUQNDC233FfeD4HYGBJAQFh6QL/XCgm -5O3q9kWpgts1MHKoHoh7vxSSQGSP2k7flNP1UB2nv4sKvyGM8eJKApuROIodcTkc -cM4qXaBuXunMr5kJlvDJPm+NLzKyhtQP2fWI7xGYwiCiB29gm1GFMjdur4amiQEV -AwUQNDBR9fjDdqGixRdJAQE+mAf+JyqJZEVFwNwZ2hSIMewekC1r7N97p924nqfZ -Knzn6weFpE80KIJSWtEVzI0XvHlVCOnS+WRxn7zxwrOTbrcEOy0goVbNgUsP5ypZ -a2/EM546uyyJTvgD0nwA45Q4bP5sGhjh0G63r9Vwov7itFe4RDBGM8ibGnZTr9hH -o469jpomHSNeavcaUYyEqcr4GbpQmdpJTnn/H0A+fMl7ZHRoaclNx9ZksxihuCRr -kQvUOb3uRD9lFIhCvNwEardN62dKOKJXmn1TOtyanZvnmWigU5AmGuk6FpsClm3p -5vvlid64i49fZt9vW5krs2XfUevR4oL0IyUl+qW2HN0DIlDiAYkAlQMFEDQvbv2w -cgJwUPMhJQEBVBID/iOtS8CQfMxtG0EmrfaeVUU8R/pegBmVWDBULAp8CLTtdfxj -Vzs/6DXw0RogXMRRl2aFfu1Yp0xhBYjII6Kque/FzAFXY9VNF1peqnPt7ADdeptY -MppZa8sGn9BBRu9Fsw69z6JkyqvMiVxGcKy3XEpVGr0JHx8Xt6BYdrULiKr2iQB1 -AwUQNC68n6jZR/ntlUftAQFaYgL+NUYEj/sX9M5xq1ORX0SsVPMpNamHO3JBSmZS -Izjiox5MAqoFOCigAkonuzk5aBy/bRHy1cmDBOxf4mNhzrH8N6IkGvPE70cimDnb -Fvr+hoZSjIqxtELNZsLuLVavLPAXiQCVAwUQNC6vWocCuHlnLQXBAQHb1gQAugp6 -2aVzDCuz4ntfXsmlGbLY7o5oZXYIKdPP4riOj4imcJh6cSgYFL6OMzeIp9VW/PHo -2mk8kkdkz5uif5LqOkEuIxgra7p1Yq/LL4YVhWGQeD8hwpmu+ulYoPOw40dVYS36 -PwrHIH9afNhl8Or5O2VIHIWnoQ++9r6gwngFQOyJAJUDBRAzHnkh1sNKtX1rroUB -AWphBACdhuqm7GHoiXptQ/Y5F6BivCjxr9ch+gPSjaLMhq0kBHVO+TbXyVefVVGV -gCYvFPjozM8PEVykQAtY//eJ475aGXjF+BOAhl2z0IMkQKCJMExoEDHbcj0jIIMZ -2/+ptgtbFSyJ2DQ3vvCdbw/1kyPHTPfP+L2u40GWMIYVBbyouokAlQMFEDMe7+UZ -symln7HG2QEBzMED/3L0DyPK/u6PyAd1AdpjUODTkWTZjZ6XA2ubc6IXXsZWpmCg -B/24v8jsJ3DIsvUD3Ke55kTr6xV+au+mAkwOQqWUTUWfQCkSrSDlbUJ1VPBzhyTp -uzjBopte7o3R6XXfcLiC5jY6eCX0QtLGhKpLjTr5uRhf1fYODGsAGXmCByDviQB1 -AgUQMy6UMB0Z9MEMmFelAQHV4AMAjdFUIyFtpTr5jkyZSd3y//0JGO0z9U9hLVxe -BBCwvdEQxsrpeTtVdqpeKZxHN1GhPCYvgLFZAQlcPh/Gc8u9uO7wVSgJc3zYKFTh -KpQevdF/rzjTCHfgigf5Iui0qiqBiQCVAwUQMx22bAtzgG/ED06dAQFi0gQAkosq -TMWy+1eUXbi2azFK3RX5ERf9wlN7mqh7TvwcPXvVWzUARnwRv+4kk3uOWI18q5UP -is7KH3KYOVeRrPd8bbp6SjhBh82ourTEQUXLBDQiI1V1cZZmwwEdlnAnhFnkXgMB -NM2q7oBefRHADfYDfGo90wXyrVVL+GihDNpzUwOJAJUDBRAzHUFnOWvfULwOR3EB -AbOYA/90JIrKmxhwP6quaheFOjjPoxDGEZpGJEOwejEByYj+AgONCRmQS3Bydtub -A+nm/32DFeG8pe/dnFvGc+QgNW560hK21C2KJj72mhjRlg/na7jz4/MmBAv5k61Q -7roWi0rwx+R9NSHxpshC8A92zmvo8w/XzVSogC8pJ04jcnY6YokAlQMFEDMdPtta -9LwlvuSC3QEBvPMD/3TJGroHhHYjHhiEpDZZVszeRQ0cvVI/uLLi5yq3W4F6Jy47 -DF8VckA7mw0bXrOMNACN7Je7uyaU85qvJC2wgoQpFGdFlkjmkAwDAjR+koEysiE8 -FomiOHhvEpEY/SjSS4jj4IPmgV8Vq66XjPw+i7Z0RsPLOIf67yZHxypNiBiYiQCV -AwUQMxxwpKrq6G7/78D5AQHo2QQAjnp6KxOl6Vvv5rLQ/4rj3OemvF7IUUq34xb2 -5i/BSvGBUpDQVUmhv/qIfWvDqWGZedyM+AlNSfUWPWnP41S8OH+lcERH2g2dGKGl -7kH1F2BxByZlqREHm2q624wPPA35RLXtXIx06yYjLtJ7b+FCAX6PUgZktZYk5gwj -doAGrC2JAJUDBRAzGvcCKC6c7f53PGUBAUozA/9l/qKmcqbi8RtLsKQSh3vHds9d -22zcbkuJPBSoOv2D7i2VLshaQFjq+62uYZGE6nU1WP5sZcBDuWjoX4t4NrffnOG/ -1R9D0t1t9F47D77HJzjvo+J52SN520YHcbT8VoHdPRoEOXPN4tzhvn2GapVVdaAl -WM0MLlohNH3I9jap9okAdQMFEDMZlUAnyXglSykrxQEBnuwC/jXbFL+jzs2HQCuo -4gyVrPlUksQCLYZjNnZtw1ca697GV3NhBhSXR9WHLQH+ZWnpTzg2iL3WYSdi9tbP -s78iY1FSd4EG8H9V700oQG8dlICF5W2VjzR7fByNosKM70WSXYkBFQMFEDMWBsGC -y1t9eckWHQEBHzMH/jmrsHwSPrA5R055VCTuDzdS0AJ+tuWkqIyqQQpqbost89Hx -per3MmjLJas/VJv8EheuU3vQ9a8sG2SnlWKLtzFqpk7TCkyq/H3blub0agREbNnY -hHHTGQFCYJb4lWjWvMjfP+N5jvlLcnDqQPloXfAOgy7W90POoqFrsvhxdpnXgoLr -zyNNja1O1NRj+Cdv/GmJYNi6sQe43zmXWeA7syLKMw6058joDqEJFKndgSp3Zy/y -XmObOZ/HC2OJwA3gzEaAu8Pqd1svwGIGznqtTNCn9k1+rMvJPaxglg7PXIJS282h -mBl9AcJlwmh2GUCswl9/sj+REWTb8SgJUbkFcp6JAJUDBRAwdboVMPfsgxioXMEB -AQ/LA/9BFTZ9T95P/TtsxeC7lm9imk2mpNQCBEvXk286FQnGFtDodGfBfcH5SeKH -aUNxFaXr39rDGUtoTE98iAX3qgCElf4V2rzgoHLpuQzCg3U35dfs1rIxlpcSDk5i -vaHpPV3Sv+mlqWL049y+3bGaZeAnwM6kvGMP2uccS9U6cbhpw4hGBBARAgAGBQI3 -GtRfAAoJEF3iSZZbA1iikWUAoIpSuXzuN/CI63dZtT7RL7c/KtWUAJ929SAtTr9S -lpSgxMC8Vk1T1i5/SYkBFQMFEzccnFnSJilEzmrGwQEBJxwH/2oauG+JlUC3zBUs -oWhRQwqo7DdqaPl7sH5oCGDKS4x4CRA23U15NicDI7ox6EizkwCjk0dRr1EeRK+R -qL1b/2T42B6nynOLhRG2A0BPHRRJLcoL4nKfoPSo/6dIC+3iVliGEl90KZZD5bnO -NrVJQkRjZL8Ao+9IpmoYh8XjS5xMLEF9oAQqAkA93nVBm56lKmaL1kl+M3dJFtNK -tVB8de1ZXifDs8HykD42qYVtcseCKxZXhC3UTG5YLNhPvgZKH8WBCr3zcR13hFDx -uecUmu0MVhvEzoKyBYYt0rrqnyWrxwbv4gSTUWH5ZbgsTjc1SYKZxz6hrPQnfYWz -NkznlFWJARUDBRM0xL43CdxwOTnzf10BATOCB/0Q6WrpzwPMofjHj54MiGLKVP++ -YfwzdvnsHxVpTZLZ5Ux8ErDsnLmvUGphnLVELZwEkEGRjln7a19h9oL8UYZaV+Ic -R6tQ06Fb1ldR+q+3nXtBYzGhleXdgJQSKLJkzPF72tvY0DHUB//GUV9IBLQMvfG8 -If/AFsih4iXi96DOtUAbeuIhnMlWwLJFeGjLLsX1u6HSX33xy4bGX6v/UcHbTSSY -axzb92GR/xpP2Xt332hOFRkDZL52g27HS0UrEJWdAVZbh25KbZEl7C6zX/82OZ5n -TEziHo20eOS6Nrt2+gLSeA9X5h/+qUx30kTPz2LUPBQyIqLCJkHM8+0q5j9ciQCi -AwUTNMS+HZFeTizbCJMJAQFrGgRlEAkG1FYU4ufTxsaxhFZy7xv18527Yxpls6mS -Ci1HL55nJoce6TI+Z34MrLOaiZljeQP3EUgzA+cs1sFRago4qz2wS8McmQ9w0FNQ -QMz4vVg9CVi1JUVd4EWYvJpA8swDd5b9+AodYFEsfxt9Z3aP+AcWFb10RlVVsNw9 -EhObc6IMnwAOHCEI9vp5FzzFiQCVAwUQNxyr6UyjTSyISdw9AQHf+wP+K+q6hIQ0 -9tkgaYaDLlWKLbuxePXqM4oO72qi70Gkg0PV5nU4l368R6W5xgR8ZkxlQlg85sJ0 -bL6wW/SjMz7pP9hkhNwk0x3IFkGMTYG8i6Gt8Nm7x70dzJoiC+A496PryYC0rvGV -f+Om8j5uTexBBjb/jpJhAQ/SGqeDeCHheOC0Lldlcm5lciBLb2NoIChtZWluIGFs -dGVyIGtleSkgPHdrQGNvbXB1dGVyLm9yZz6JAHUDBRM2G2MyHRn0wQyYV6UBASKK -Av4wzmK7a9Z+g0KH+6W8ffIhzrQo8wDAU9X1WJKzJjS205tx4mmdnAt58yReBc/+ -5HXTI8IKR8IgF+LVXKWAGv5P5AqGhnPMeQSCs1JYdf9MPvbe34jD8wA1LTWFXn9e -/cWIRgQQEQIABgUCNxrUaQAKCRBd4kmWWwNYovRiAJ9dJBVfjx9lGARoFXmAieYr -MGDrmwCZAQyO4Wo0ntQ+iq4do9M3/FTFjiCZAaIENu1I6REEAJRGEqcYgXJch5fr -UYBj2EkDkWAbhRqVXnmiF3PjCEGAPMMYsTddiU7wcKfiCAqKWWXow7BjTJl6Do8R -T1jdKpPOlBJXqqPYzsyBxLzE6mLps0K7SLJlSKTQqSVRcx0jx78JWYGlAlP0Kh9s -PV2w/rPh0LrPeOKXT7lZt/DrIhfPAKDL/sVqCrmY3QfvrT8kSKJcgtLWfQP/cfbq -VNrGjW8am631N3UVA3tWfpgM/T9OjmKmw44NE5XfPJTAXlCV5j7zNMUkDeoPkrFF -8DvbpYQs4XWYHozDjhR2Q+eI6gZ0wfmhLHqqc2eVVkEG7dT57Wp9DAtCMe7RZfhn -arTQMqlYtOEa/suiHk0qLo59NsyF8eh68IDNCeYD/Apzonwaq2EQ1OEpfFlp6LcS -nS34+UGZtTO4BgJdmEjr/QrIPp6bJDstgho+/2oR8yQwuHGJwbS/8ADA4IFEpLdu -SpzrABho7RuNQcm96bceRY+7Hza3zf7pg/JGdWOb+bC3S4TIpK+3sx3YNWs7eURw -pGREeJi5/Seic+GXlGzltBpXZXJuZXIgS29jaCA8d2tAZ251cGcub3JnPohbBBMR -AgAbBQI3Gs+QBQkMyXyAAwsKAwMVAwIDFgIBAheAAAoJEF3iSZZbA1iiXcIAnjv7 -ON5AiwzCLBwm9h9ywufXJQuVAJ9RMq6lpPqnDly6UCKz+kGt0EplyIhGBBARAgAG -BQI3GtE9AAoJEGx+4bhiHMAThfQAnjcDvBthtHotN89IP590GSKY287xAJ0WhKl9 -j7gWwpVqCD+ofcq0ZQBG1IkAdQMFEDca0WMdGfTBDJhXpQEB0a4C/0AzSj1eSYFs -4ss2x7xCn0yMPxML+hJdjGnVb0CPJGzzeKpD69pmVsD87nPa53gj0NXi/ADnQvPm -csVs8dr7K5PxXFOXaJzDm72tnLeJKiTesZfMY7MQ0yYQUhUWogSY8YhGBBARAgAG -BQI3GtGjAAoJEGi3q4lXVI3NLfgAoISt+x9r02Hl14njSfGmZIjyUrXuAJ9FhxTq -LUHU1uDZmSSvlKpOcG1pYIhGBBARAgAGBQI3Tx9dAAoJEPbu3yAYS8TZLb4Ani50 -OXjsQCc/gr5G+xZy/yqOqnOWAJ44VlluXNaN6J7yhB9iXtsEGvE+oohGBBARAgAG -BQI3pyb+AAoJEJg0ZdshQ5QifskAn0stcy37RHy7iB2bFB4rPVNDJaizAJ9hCH+0 -yNTOTisrEHLhS0QufAn3H4hFBBARAgAGBQI34UEzAAoJEDZnYPF9LteIeecAn3eT -mQldy/AIYuEFvyaF1FPmQdDNAJj3trsO1mAyzs7+PB++rZunMveeiEYEEBECAAYF -AjgqYg8ACgkQ4/JYVBKPDnkbHQCfRR7qUYmwTxtrf+Fw6hfsYjCy//AAn1eRdkkd -CExOJPwvrHEtZydSmVA1tAtXZXJuZXIgS29jaIhbBBMRAgAbBQI27UjqBQkMyXyA -AwsKAwMVAwIDFgIBAheAAAoJEF3iSZZbA1iitdYAn1IJbSJ46kvsBjq8X44hoybD -ZlbWAKCS2jR5Z+CmMC5WDqNepHXAe3alA4kCHgQQFAMABgUCNy9Z1AAKCRBsTDGl -sdUVZw3FB/9uDXhYYnQZYw1K6445HRZjNRo23NimItJXIuut5e2jwsE3DNuDOPat -qZbtGL61gkAcuG25rxmBJ6JuaAG5lqwXx1vWbk03VlwcFcZPKwCOn4qeJxNn06uP -vkP2jehKYzJFyKwSGv6CSPS1WEZ84A4Lp4pu59W7JgUNUjI7JQEaVbsCl6bMDNh6 -Z+zcN2MefzuWSMcxURI7h8zmu0u5JztwF8v97qWNpZBzlbxLSAgO/RW0vf2kxbgG -WkprbmvXignLC5Sm9YJm6y8Obtkmepn9aaA4dBSzJi51NE6kYhuWw2DyKoLqG5ak -ZIFF27ehFBGGSql9V2zPPoEH+cDHTWrbB/9D5T1ch3WPLPFQvVIaBpgx/pB3KMdD -WjG4Us3HMzoL8zTr23Bs2BcnvVGwMNdXEVl9JONKIfXTQA/372FvmbJxpctQ5dgO -85IXMcF38uyMU1WusVsOzlfD5wsZUc4iBHkhYB+C7l3U8BlT25BWB0adB+ZmDfzd -FI/G9Hd+dnPWsc1QaZLrDvHoVVvFrVBTa3fyA1pwjAcBMA9wGnIkt9ejOdumDcAN -uAIbIOMHCe49ARCRjBFqRtzNGuB7who9lu3Ydg+hSx25cxnIkjzPm2+7ulQPCznW -dXURfXkFw3f75pjmlTIDUi1poPKZBWagVtALQE0zMw7nd0ycWSjiLjaSiEYEEBEC -AAYFAjc6+aMACgkQdQ9klcidkz6GiwCdGe0KSP/vSyEZM/GClQXvjMD4RvMAoJwy -TIdcjPZbQizDeAO3btn2CCwTiEYEEBECAAYFAjc3I8UACgkQ9u7fIBhLxNmHZQCg -lWbPDznIcnOxdDW+k7YgA9+/n00An1ZjSiJipverUxLEFHAbSBWI0IntiQEVAwUQ -N0Pe01KAV0R2U0AdAQHIcQf/Ykx+DvUaCLIYlMrEIDKZ3J/aPbJ8frAjvzYkrgFZ -XhzQT9Xfyr6OkhiyWKFX23yzzDVcrmeIxovCUI7IFY6QM/d5yHr4Y8+18HdyaUva -FLz3o9ZnVp1AeAJ5CkHzfufnrKPRpOzgvXFqttJVPbaVTAyJTo/Bh0fZGHyeHwW8 -3QhmxuWfac6PveoA1DM1+Wax5QoXVeHhyTzIutF3ivpqaHEBUB9xgVEk3jN0svdy -aGCS3QANmXMDBecSPB0cfLtK8AmTV5w04D2kWw4lu+fO593Vp+z8Jsbvwj7QkOGD -vlnY3Crx4qOwqqI7TPP+8bnJZKd1m9aRNbPcPdvXGvUh3YhGBBARAgAGBQI4KmIe -AAoJEOPyWFQSjw55D5AAoJs5OxzJSdYdKsOjh8jLQxOESOE6AJ4vgpvtNaR384dB -JxUE7yxNTPT7aA== -=gKwz ------END PGP PUBLIC KEY BLOCK----- diff --git a/g10/revoke.c b/g10/revoke.c deleted file mode 100644 index 161bd2b82..000000000 --- a/g10/revoke.c +++ /dev/null @@ -1,690 +0,0 @@ -/* revoke.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <ctype.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "ttyio.h" -#include "status.h" -#include "i18n.h" - - -struct revocation_reason_info { - int code; - char *desc; -}; - - -int -revocation_reason_build_cb( PKT_signature *sig, void *opaque ) -{ - struct revocation_reason_info *reason = opaque; - char *ud = NULL; - byte *buffer; - size_t buflen = 1; - - if(!reason) - return 0; - - if( reason->desc ) { - ud = native_to_utf8( reason->desc ); - buflen += strlen(ud); - } - buffer = xmalloc ( buflen ); - *buffer = reason->code; - if( ud ) { - memcpy(buffer+1, ud, strlen(ud) ); - xfree ( ud ); - } - - build_sig_subpkt( sig, SIGSUBPKT_REVOC_REASON, buffer, buflen ); - xfree ( buffer ); - return 0; -} - -/* Outputs a minimal pk (as defined by 2440) from a keyblock. A - minimal pk consists of the public key packet and a user ID. We try - and pick a user ID that has a uid signature, and include it if - possible. */ -static int -export_minimal_pk(iobuf_t out,KBNODE keyblock, - PKT_signature *revsig,PKT_signature *revkey) -{ - KBNODE node; - PACKET pkt; - PKT_user_id *uid=NULL; - PKT_signature *selfsig=NULL; - u32 keyid[2]; - int rc; - - node=find_kbnode(keyblock,PKT_PUBLIC_KEY); - if(!node) - { - log_error(_("key incomplete\n")); - return GPG_ERR_GENERAL; - } - - keyid_from_pk(node->pkt->pkt.public_key,keyid); - - pkt=*node->pkt; - rc=build_packet(out,&pkt); - if(rc) - { - log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) ); - return rc; - } - - init_packet(&pkt); - pkt.pkttype=PKT_SIGNATURE; - - /* the revocation itself, if any. 2440 likes this to come first. */ - if(revsig) - { - pkt.pkt.signature=revsig; - rc=build_packet(out,&pkt); - if(rc) - { - log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) ); - return rc; - } - } - - /* If a revkey in a 1F sig is present, include it too */ - if(revkey) - { - pkt.pkt.signature=revkey; - rc=build_packet(out,&pkt); - if(rc) - { - log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) ); - return rc; - } - } - - while(!selfsig) - { - KBNODE signode; - - node=find_next_kbnode(node,PKT_USER_ID); - if(!node) - { - /* We're out of user IDs - none were self-signed. */ - if(uid) - break; - else - { - log_error(_("key %08lX incomplete\n"),(ulong)keyid[1]); - return GPG_ERR_GENERAL; - } - } - - if(node->pkt->pkt.user_id->attrib_data) - continue; - - uid=node->pkt->pkt.user_id; - signode=node; - - while((signode=find_next_kbnode(signode,PKT_SIGNATURE))) - { - if(keyid[0]==signode->pkt->pkt.signature->keyid[0] && - keyid[1]==signode->pkt->pkt.signature->keyid[1] && - IS_UID_SIG(signode->pkt->pkt.signature)) - { - selfsig=signode->pkt->pkt.signature; - break; - } - } - } - - pkt.pkttype=PKT_USER_ID; - pkt.pkt.user_id=uid; - - rc=build_packet(out,&pkt); - if(rc) - { - log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) ); - return rc; - } - - if(selfsig) - { - pkt.pkttype=PKT_SIGNATURE; - pkt.pkt.signature=selfsig; - - rc=build_packet(out,&pkt); - if(rc) - { - log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) ); - return rc; - } - } - - return 0; -} - -/**************** - * Generate a revocation certificate for UNAME via a designated revoker - */ -int -gen_desig_revoke( const char *uname ) -{ - int rc = 0; - armor_filter_context_t afx; - PKT_public_key *pk = NULL; - PKT_secret_key *sk = NULL; - PKT_signature *sig = NULL; - iobuf_t out = NULL; - struct revocation_reason_info *reason = NULL; - KEYDB_HANDLE kdbhd; - KEYDB_SEARCH_DESC desc; - KBNODE keyblock=NULL,node; - u32 keyid[2]; - int i,any=0; - - if( opt.batch ) { - log_error(_("sorry, can't do this in batch mode\n")); - return GPG_ERR_GENERAL; - } - - memset( &afx, 0, sizeof afx); - - kdbhd = keydb_new (0); - classify_user_id (uname, &desc); - rc = desc.mode? keydb_search (kdbhd, &desc, 1) : GPG_ERR_INV_USER_ID; - if (rc) { - log_error (_("key `%s' not found: %s\n"),uname, gpg_strerror (rc)); - goto leave; - } - - rc = keydb_get_keyblock (kdbhd, &keyblock ); - if( rc ) { - log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - /* To parse the revkeys */ - merge_keys_and_selfsig(keyblock); - - /* get the key from the keyblock */ - node = find_kbnode( keyblock, PKT_PUBLIC_KEY ); - if( !node ) - BUG (); - - pk=node->pkt->pkt.public_key; - - keyid_from_pk(pk,keyid); - - /* Are we a designated revoker for this key? */ - - if(!pk->revkey && pk->numrevkeys) - BUG(); - - for(i=0;i<pk->numrevkeys;i++) - { - if(sk) - free_secret_key(sk); - - sk=xcalloc (1,sizeof(*sk)); - - rc=get_seckey_byfprint(sk,pk->revkey[i].fpr,MAX_FINGERPRINT_LEN); - - /* We have the revocation key */ - if(!rc) - { - PKT_signature *revkey = NULL; - - any = 1; - - print_pubkey_info (NULL, pk); - tty_printf ("\n"); - - tty_printf (_("To be revoked by:\n")); - print_seckey_info (sk); - - if(pk->revkey[i].class&0x40) - tty_printf(_("(This is a sensitive revocation key)\n")); - tty_printf("\n"); - - if( !cpr_get_answer_is_yes("gen_desig_revoke.okay", - _("Create a revocation certificate for this key? ")) ) - continue; - - /* get the reason for the revocation (this is always v4) */ - reason = ask_revocation_reason( 1, 0, 1 ); - if( !reason ) - continue; - - rc = check_secret_key( sk, 0 ); - if( rc ) - continue; - - if( !opt.armor ) - tty_printf(_("ASCII armored output forced.\n")); - - if( (rc = open_outfile( NULL, 0, &out )) ) - goto leave; - - afx.what = 1; - afx.hdrlines = "Comment: A revocation certificate should follow\n"; - iobuf_push_filter( out, armor_filter, &afx ); - - /* create it */ - rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0, - 0, 0, 0, - revocation_reason_build_cb, reason ); - if( rc ) { - log_error(_("make_keysig_packet failed: %s\n"), gpg_strerror (rc)); - goto leave; - } - - /* Spit out a minimal pk as well, since otherwise there is - no way to know which key to attach this revocation to. - Also include the direct key signature that contains - this revocation key. We're allowed to include - sensitive revocation keys along with a revocation, as - this may be the only time the recipient has seen it. - Note that this means that if we have multiple different - sensitive revocation keys in a given direct key - signature, we're going to include them all here. This - is annoying, but the good outweighs the bad, since - without including this a sensitive revoker can't really - do their job. People should not include multiple - sensitive revocation keys in one signature: 2440 says - "Note that it may be appropriate to isolate this - subpacket within a separate signature so that it is not - combined with other subpackets that need to be - exported." -dms */ - - while(!revkey) - { - KBNODE signode; - - signode=find_next_kbnode(node,PKT_SIGNATURE); - if(!signode) - break; - - node=signode; - - if(keyid[0]==signode->pkt->pkt.signature->keyid[0] && - keyid[1]==signode->pkt->pkt.signature->keyid[1] && - IS_KEY_SIG(signode->pkt->pkt.signature)) - { - int j; - - for(j=0;j<signode->pkt->pkt.signature->numrevkeys;j++) - { - if(pk->revkey[i].class== - signode->pkt->pkt.signature->revkey[j]->class && - pk->revkey[i].algid== - signode->pkt->pkt.signature->revkey[j]->algid && - memcmp(pk->revkey[i].fpr, - signode->pkt->pkt.signature->revkey[j]->fpr, - MAX_FINGERPRINT_LEN)==0) - { - revkey=signode->pkt->pkt.signature; - break; - } - } - } - } - - if(!revkey) - BUG(); - - rc=export_minimal_pk(out,keyblock,sig,revkey); - if(rc) - goto leave; - - /* and issue a usage notice */ - tty_printf(_("Revocation certificate created.\n")); - break; - } - } - - if(!any) - log_error(_("no revocation keys found for `%s'\n"),uname); - - leave: - if( pk ) - free_public_key( pk ); - if( sk ) - free_secret_key( sk ); - if( sig ) - free_seckey_enc( sig ); - - if( rc ) - iobuf_cancel(out); - else - iobuf_close(out); - release_revocation_reason_info( reason ); - return rc; -} - - -/**************** - * Generate a revocation certificate for UNAME - */ -int -gen_revoke( const char *uname ) -{ - int rc = 0; - armor_filter_context_t afx; - PACKET pkt; - PKT_secret_key *sk; /* used as pointer into a kbnode */ - PKT_public_key *pk = NULL; - PKT_signature *sig = NULL; - u32 sk_keyid[2]; - iobuf_t out = NULL; - KBNODE keyblock = NULL, pub_keyblock = NULL; - KBNODE node; - KEYDB_HANDLE kdbhd; - struct revocation_reason_info *reason = NULL; - KEYDB_SEARCH_DESC desc; - - if( opt.batch ) { - log_error(_("sorry, can't do this in batch mode\n")); - return GPG_ERR_GENERAL; - } - - memset( &afx, 0, sizeof afx); - init_packet( &pkt ); - - /* search the userid: - * We don't want the whole getkey stuff here but the entire keyblock - */ - kdbhd = keydb_new (1); - classify_user_id (uname, &desc); - rc = desc.mode? keydb_search (kdbhd, &desc, 1) : GPG_ERR_INV_USER_ID; - if (rc) { - log_error (_("secret key `%s' not found: %s\n"), - uname, gpg_strerror (rc)); - goto leave; - } - - rc = keydb_get_keyblock (kdbhd, &keyblock ); - if( rc ) { - log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - /* get the keyid from the keyblock */ - node = find_kbnode( keyblock, PKT_SECRET_KEY ); - if( !node ) - BUG (); - - /* fixme: should make a function out of this stuff, - * it's used all over the source */ - sk = node->pkt->pkt.secret_key; - keyid_from_sk( sk, sk_keyid ); - print_seckey_info (sk); - - pk = xcalloc (1, sizeof *pk ); - - /* FIXME: We should get the public key direct from the secret one */ - - pub_keyblock=get_pubkeyblock(sk_keyid); - if(!pub_keyblock) - { - log_error(_("no corresponding public key: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - node=find_kbnode(pub_keyblock,PKT_PUBLIC_KEY); - if(!node) - BUG(); - - pk=node->pkt->pkt.public_key; - - if( cmp_public_secret_key( pk, sk ) ) { - log_error(_("public key does not match secret key!\n") ); - rc = GPG_ERR_GENERAL; - goto leave; - } - - tty_printf("\n"); - if( !cpr_get_answer_is_yes("gen_revoke.okay", - _("Create a revocation certificate for this key? ")) ){ - rc = 0; - goto leave; - } - - if(sk->version>=4 || opt.force_v4_certs) { - /* get the reason for the revocation */ - reason = ask_revocation_reason( 1, 0, 1 ); - if( !reason ) { /* user decided to cancel */ - rc = 0; - goto leave; - } - } - - switch( is_secret_key_protected( sk ) ) { - case -1: - log_error(_("unknown protection algorithm\n")); - rc = GPG_ERR_PUBKEY_ALGO; - break; - case 0: - tty_printf(_("NOTE: This key is not protected!\n")); - break; - default: - rc = check_secret_key( sk, 0 ); - break; - } - if( rc ) - goto leave; - - - if( !opt.armor ) - tty_printf(_("ASCII armored output forced.\n")); - - if( (rc = open_outfile( NULL, 0, &out )) ) - goto leave; - - afx.what = 1; - afx.hdrlines = "Comment: A revocation certificate should follow\n"; - iobuf_push_filter( out, armor_filter, &afx ); - - /* create it */ - rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0, - opt.force_v4_certs?4:0, 0, 0, - revocation_reason_build_cb, reason ); - if( rc ) { - log_error(_("make_keysig_packet failed: %s\n"), gpg_strerror (rc)); - goto leave; - } - - if(PGP2 || PGP6 || PGP7 || PGP8) - { - /* Use a minimal pk for PGPx mode, since PGP can't import bare - revocation certificates. */ - rc=export_minimal_pk(out,pub_keyblock,sig,NULL); - if(rc) - goto leave; - } - else - { - init_packet( &pkt ); - pkt.pkttype = PKT_SIGNATURE; - pkt.pkt.signature = sig; - - rc = build_packet( out, &pkt ); - if( rc ) { - log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) ); - goto leave; - } - } - - /* and issue a usage notice */ - tty_printf(_("Revocation certificate created.\n\n" -"Please move it to a medium which you can hide away; if Mallory gets\n" -"access to this certificate he can use it to make your key unusable.\n" -"It is smart to print this certificate and store it away, just in case\n" -"your media become unreadable. But have some caution: The print system of\n" -"your machine might store the data and make it available to others!\n")); - - leave: - if( sig ) - free_seckey_enc( sig ); - release_kbnode( keyblock ); - release_kbnode( pub_keyblock ); - keydb_release (kdbhd); - if( rc ) - iobuf_cancel(out); - else - iobuf_close(out); - release_revocation_reason_info( reason ); - return rc; -} - - - -struct revocation_reason_info * -ask_revocation_reason( int key_rev, int cert_rev, int hint ) -{ - int code=-1; - char *description = NULL; - struct revocation_reason_info *reason; - const char *text_0 = _("No reason specified"); - const char *text_1 = _("Key has been compromised"); - const char *text_2 = _("Key is superseded"); - const char *text_3 = _("Key is no longer used"); - const char *text_4 = _("User ID is no longer valid"); - const char *code_text = NULL; - - do { - code=-1; - xfree (description); - description = NULL; - - tty_printf(_("Please select the reason for the revocation:\n")); - tty_printf( " 0 = %s\n", text_0 ); - if( key_rev ) - tty_printf(" 1 = %s\n", text_1 ); - if( key_rev ) - tty_printf(" 2 = %s\n", text_2 ); - if( key_rev ) - tty_printf(" 3 = %s\n", text_3 ); - if( cert_rev ) - tty_printf(" 4 = %s\n", text_4 ); - tty_printf( " Q = %s\n", _("Cancel") ); - if( hint ) - tty_printf(_("(Probably you want to select %d here)\n"), hint ); - - while(code==-1) { - int n; - char *answer = cpr_get("ask_revocation_reason.code", - _("Your decision? ")); - trim_spaces( answer ); - cpr_kill_prompt(); - if( *answer == 'q' || *answer == 'Q') - return NULL; /* cancel */ - if( hint && !*answer ) - n = hint; - else if(!digitp( answer ) ) - n = -1; - else - n = atoi(answer); - xfree (answer); - if( n == 0 ) { - code = 0x00; /* no particular reason */ - code_text = text_0; - } - else if( key_rev && n == 1 ) { - code = 0x02; /* key has been compromised */ - code_text = text_1; - } - else if( key_rev && n == 2 ) { - code = 0x01; /* key is superseded */ - code_text = text_2; - } - else if( key_rev && n == 3 ) { - code = 0x03; /* key is no longer used */ - code_text = text_3; - } - else if( cert_rev && n == 4 ) { - code = 0x20; /* uid is no longer valid */ - code_text = text_4; - } - else - tty_printf(_("Invalid selection.\n")); - } - - tty_printf(_("Enter an optional description; " - "end it with an empty line:\n") ); - for(;;) { - char *answer = cpr_get("ask_revocation_reason.text", "> " ); - trim_trailing_ws( answer, strlen(answer) ); - cpr_kill_prompt(); - if( !*answer ) { - xfree (answer); - break; - } - - { - char *p = make_printable_string( answer, strlen(answer), 0 ); - xfree (answer); - answer = p; - } - - if( !description ) - description = xstrdup (answer); - else { - char *p = xmalloc ( strlen(description) + strlen(answer) + 2 ); - strcpy(stpcpy(stpcpy( p, description),"\n"),answer); - xfree (description); - description = p; - } - xfree (answer); - } - - tty_printf(_("Reason for revocation: %s\n"), code_text ); - if( !description ) - tty_printf(_("(No description given)\n") ); - else - tty_printf("%s\n", description ); - - } while( !cpr_get_answer_is_yes("ask_revocation_reason.okay", - _("Is this okay? ")) ); - - reason = xmalloc ( sizeof *reason ); - reason->code = code; - reason->desc = description; - return reason; -} - -void -release_revocation_reason_info( struct revocation_reason_info *reason ) -{ - if( reason ) { - xfree ( reason->desc ); - xfree ( reason ); - } -} diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c deleted file mode 100644 index 7356cb224..000000000 --- a/g10/seckey-cert.c +++ /dev/null @@ -1,452 +0,0 @@ -/* seckey-cert.c - secret key certificate packet handling - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "packet.h" -#include "mpi.h" -#include "keydb.h" -#include "cipher.h" -#include "main.h" -#include "options.h" -#include "i18n.h" -#include "status.h" -#include "pkglue.h" - -static int -do_check( PKT_secret_key *sk, const char *tryagain_text, int mode, - int *canceled ) -{ - byte *buffer; - u16 csum=0; - int i, res; - unsigned nbytes; - gpg_error_t rc; - - if( sk->is_protected ) { /* remove the protection */ - DEK *dek = NULL; - u32 keyid[4]; /* 4! because we need two of them */ - CIPHER_HANDLE cipher_hd=NULL; - PKT_secret_key *save_sk; - - if( sk->protect.s2k.mode == 1001 ) { - log_info(_("secret key parts are not available\n")); - return GPG_ERR_GENERAL; - } - if( sk->protect.algo == CIPHER_ALGO_NONE ) - BUG(); - if( openpgp_cipher_test_algo( sk->protect.algo ) ) { - log_info(_("protection algorithm %d%s is not supported\n"), - sk->protect.algo,sk->protect.algo==1?" (IDEA)":"" ); - if (sk->protect.algo==CIPHER_ALGO_IDEA) - { - write_status (STATUS_RSA_OR_IDEA); - idea_cipher_warn (0); - } - return GPG_ERR_CIPHER_ALGO; - } - keyid_from_sk( sk, keyid ); - keyid[2] = keyid[3] = 0; - if( !sk->is_primary ) { - keyid[2] = sk->main_keyid[0]; - keyid[3] = sk->main_keyid[1]; - } - dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo, - &sk->protect.s2k, mode, - tryagain_text, canceled ); - if (!dek && canceled && *canceled) - return GPG_ERR_GENERAL; - - rc = gcry_cipher_open (&cipher_hd, sk->protect.algo, - GCRY_CIPHER_MODE_CFB, - GCRY_CIPHER_SECURE - | (sk->protect.algo >= 100 ? - 0 : GCRY_CIPHER_ENABLE_SYNC)); - if (rc) - log_fatal ("cipher open failed: %s\n", gpg_strerror (rc) ); - - rc = gcry_cipher_setkey (cipher_hd, dek->key, dek->keylen); - if (rc) - log_fatal ("set key failed: %s\n", gpg_strerror (rc) ); - - xfree (dek); - save_sk = copy_secret_key( NULL, sk ); - gcry_cipher_setiv (cipher_hd, sk->protect.iv, sk->protect.ivlen); - csum = 0; - if( sk->version >= 4 ) { - int ndata; - unsigned int ndatabits; - byte *p, *data; - u16 csumc = 0; - - i = pubkey_get_npkey(sk->pubkey_algo); - assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE )); - p = gcry_mpi_get_opaque( sk->skey[i], &ndatabits ); - ndata = (ndatabits+7)/8; - if ( ndata > 1 ) - csumc = p[ndata-2] << 8 | p[ndata-1]; - data = gcry_xmalloc_secure ( ndata ); - gcry_cipher_decrypt( cipher_hd, data, ndata, p, ndata ); - gcry_mpi_release ( sk->skey[i] ); sk->skey[i] = NULL ; - p = data; - if (sk->protect.sha1chk) { - /* This is the new SHA1 checksum method to detect - tampering with the key as used by the Klima/Rosa - attack */ - sk->csum = 0; - csum = 1; - if( ndata < 20 ) - log_error("not enough bytes for SHA-1 checksum\n"); - else { - gcry_md_hd_t h; - - if ( gcry_md_open (&h, DIGEST_ALGO_SHA1, 1)) - BUG(); /* algo not available */ - gcry_md_write (h, data, ndata - 20); - gcry_md_final (h); - if (!memcmp (gcry_md_read (h, DIGEST_ALGO_SHA1), - data + ndata - 20, 20) ) { - /* digest does match. We have to keep the old - style checksum in sk->csum, so that the - test used for unprotected keys does work. - This test gets used when we are adding new - keys. */ - sk->csum = csum = checksum (data, ndata-20); - } - gcry_md_close (h); - } - } - else { - if( ndata < 2 ) { - log_error("not enough bytes for checksum\n"); - sk->csum = 0; - csum = 1; - } - else { - csum = checksum( data, ndata-2); - sk->csum = data[ndata-2] << 8 | data[ndata-1]; - if ( sk->csum != csum ) { - /* This is a PGP 7.0.0 workaround */ - sk->csum = csumc; /* take the encrypted one */ - } - } - } - - /* must check it here otherwise the mpi_read_xx would fail - because the length may have an arbitrary value */ - if( sk->csum == csum ) { - for( ; i < pubkey_get_nskey(sk->pubkey_algo); i++ ) { - assert( gcry_is_secure( p ) ); - res = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP, - p, ndata, &nbytes); - if( res ) - log_bug ("gcry_mpi_scan failed in do_check: %s\n", - gpg_strerror (res)); - ndata -= nbytes; - p += nbytes; - } - /* Note: at this point ndata should be 2 for a simple - checksum or 20 for the sha1 digest */ - } - xfree (data); - } - else { - for(i=pubkey_get_npkey(sk->pubkey_algo); - i < pubkey_get_nskey(sk->pubkey_algo); i++ ) { - byte *p; - int ndata; - unsigned int ndatabits; - - assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE)); - p = gcry_mpi_get_opaque( sk->skey[i], &ndatabits ); - ndata = (ndatabits+7)/8; - assert (ndata >= 2); - assert (ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2); - buffer = gcry_xmalloc_secure (ndata); - gcry_cipher_sync (cipher_hd); - buffer[0] = p[0]; - buffer[1] = p[1]; - gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2, - p+2, ndata-2); - csum += checksum (buffer, ndata); - gcry_mpi_release (sk->skey[i]); - res = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_USG, - buffer, ndata, &ndata ); - if( res ) - log_bug ("gcry_mpi_scan failed in do_check: %s\n", - gpg_strerror (res)); - - assert (sk->skey[i]); - xfree (buffer); -/* csum += checksum_mpi (sk->skey[i]); */ - } - } - gcry_cipher_close (cipher_hd); - /* now let's see whether we have used the right passphrase */ - if( csum != sk->csum ) { - copy_secret_key( sk, save_sk ); - passphrase_clear_cache ( keyid, sk->pubkey_algo ); - free_secret_key( save_sk ); - return gpg_error (GPG_ERR_BAD_PASSPHRASE); - } - /* the checksum may fail, so we also check the key itself */ - res = pk_check_secret_key (sk->pubkey_algo, sk->skey); - if (res) { - copy_secret_key( sk, save_sk ); - passphrase_clear_cache ( keyid, sk->pubkey_algo ); - free_secret_key( save_sk ); - return gpg_error (GPG_ERR_BAD_PASSPHRASE); - } - free_secret_key( save_sk ); - sk->is_protected = 0; - } - else { /* not protected, assume it is okay if the checksum is okay */ - csum = 0; - for(i=pubkey_get_npkey(sk->pubkey_algo); - i < pubkey_get_nskey(sk->pubkey_algo); i++ ) { - csum += checksum_mpi( sk->skey[i] ); - } - if( csum != sk->csum ) - return GPG_ERR_CHECKSUM; - } - - return 0; -} - - - -/**************** - * Check the secret key - * Ask up to 3 (or n) times for a correct passphrase - * If n is negative, disable the key info prompt and make n=abs(n) - */ -int -check_secret_key( PKT_secret_key *sk, int n ) -{ - int rc = gpg_error (GPG_ERR_BAD_PASSPHRASE); - int i,mode; - - if (sk && sk->is_protected && sk->protect.s2k.mode == 1002) - return 0; /* Let the scdaemon handle it. */ - - if(n<0) - { - n=abs(n); - mode=1; - } - else - mode=0; - - if( n < 1 ) - n = (opt.batch && !opt.use_agent)? 1 : 3; /* use the default value */ - - for(i=0; i < n && gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE; i++ ) { - int canceled = 0; - const char *tryagain = NULL; - if (i) { - tryagain = N_("Invalid passphrase; please try again"); - log_info (_("%s ...\n"), _(tryagain)); - } - rc = do_check( sk, tryagain, mode, &canceled ); - if( gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE - && is_status_enabled() ) { - u32 kid[2]; - char buf[50]; - - keyid_from_sk( sk, kid ); - sprintf(buf, "%08lX%08lX", (ulong)kid[0], (ulong)kid[1]); - write_status_text( STATUS_BAD_PASSPHRASE, buf ); - } - if( have_static_passphrase() || canceled) - break; - } - - if( !rc ) - write_status( STATUS_GOOD_PASSPHRASE ); - - return rc; -} - -/**************** - * check whether the secret key is protected. - * Returns: 0 not protected, -1 on error or the protection algorithm - * -2 indicates a card stub. - */ -int -is_secret_key_protected( PKT_secret_key *sk ) -{ - return sk->is_protected? - sk->protect.s2k.mode == 1002? -2 - : sk->protect.algo : 0; -} - - - -/**************** - * Protect the secret key with the passphrase from DEK - */ -int -protect_secret_key( PKT_secret_key *sk, DEK *dek ) -{ - int i,j, rc = 0; - byte *buffer; - unsigned nbytes; - u16 csum; - - if( !dek ) - return 0; - - if( !sk->is_protected ) { /* okay, apply the protection */ - gcry_cipher_hd_t cipher_hd=NULL; - - if( openpgp_cipher_test_algo( sk->protect.algo ) ) - { - rc = gpg_error (GPG_ERR_CIPHER_ALGO); /* unsupport - protection - algorithm */ - } - else { - print_cipher_algo_note( sk->protect.algo ); - rc = gcry_cipher_open (&cipher_hd, sk->protect.algo, - GCRY_CIPHER_MODE_CFB, - GCRY_CIPHER_SECURE - | (sk->protect.algo >= 100 ? - 0 : GCRY_CIPHER_ENABLE_SYNC) ); - if (rc) - BUG(); - if( gcry_cipher_setkey( cipher_hd, dek->key, dek->keylen ) ) - log_info(_("WARNING: Weak key detected" - " - please change passphrase again.\n")); - sk->protect.ivlen = gcry_cipher_get_algo_blklen(sk->protect.algo); - assert( sk->protect.ivlen <= DIM(sk->protect.iv) ); - if( sk->protect.ivlen != 8 && sk->protect.ivlen != 16 ) - BUG(); /* yes, we are very careful */ - gcry_create_nonce (sk->protect.iv, sk->protect.ivlen); - gcry_cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen ); - if( sk->version >= 4 ) { - unsigned char *bufarr[PUBKEY_MAX_NSKEY]; - unsigned narr[PUBKEY_MAX_NSKEY]; - unsigned nbits[PUBKEY_MAX_NSKEY]; - int ndata=0; - byte *p, *data; - - for(j=0, i = pubkey_get_npkey(sk->pubkey_algo); - i < pubkey_get_nskey(sk->pubkey_algo); i++, j++ ) { - assert( !gcry_mpi_get_flag( sk->skey[i], - GCRYMPI_FLAG_OPAQUE )); - - if( gcry_mpi_aprint( GCRYMPI_FMT_USG, bufarr+j, - narr+j, sk->skey[i])) - BUG(); - - nbits[j] = gcry_mpi_get_nbits( sk->skey[i] ); - ndata += narr[j] + 2; - } - for( ; j < PUBKEY_MAX_NSKEY; j++ ) - bufarr[j] = NULL; - ndata += opt.simple_sk_checksum? 2 : 20; /* for checksum */ - - data = xmalloc_secure ( ndata ); - p = data; - for(j=0; j < PUBKEY_MAX_NSKEY && bufarr[j]; j++ ) { - p[0] = nbits[j] >> 8 ; - p[1] = nbits[j]; - p += 2; - memcpy(p, bufarr[j], narr[j] ); - p += narr[j]; - xfree (bufarr[j]); - } - - if (opt.simple_sk_checksum) { - log_info (_("generating the deprecated 16-bit checksum" - " for secret key protection\n")); - csum = checksum( data, ndata-2); - sk->csum = csum; - *p++ = csum >> 8; - *p++ = csum; - sk->protect.sha1chk = 0; - } - else { - gcry_md_hd_t h; - - if (gcry_md_open (&h, GCRY_MD_SHA1, 1)) - BUG(); /* algo not available */ - gcry_md_write (h, data, ndata - 20); - gcry_md_final (h); - memcpy (p, gcry_md_read (h, GCRY_MD_SHA1), 20); - p += 20; - gcry_md_close (h); - sk->csum = csum = 0; - sk->protect.sha1chk = 1; - } - assert( p == data+ndata ); - - gcry_cipher_encrypt( cipher_hd, data, ndata, NULL, 0 ); - for(i = pubkey_get_npkey(sk->pubkey_algo); - i < pubkey_get_nskey(sk->pubkey_algo); i++ ) { - gcry_mpi_release ( sk->skey[i] ); - sk->skey[i] = NULL; - } - i = pubkey_get_npkey(sk->pubkey_algo); - sk->skey[i] = gcry_mpi_set_opaque(NULL, data, ndata*8); - } - else { - csum = 0; - for(i=pubkey_get_npkey(sk->pubkey_algo); - i < pubkey_get_nskey(sk->pubkey_algo); i++ ) { - byte *data; - unsigned int nbits; - - csum += checksum_mpi (sk->skey[i]); - if( gcry_mpi_aprint( GCRYMPI_FMT_USG, &buffer, - &nbytes, sk->skey[i] ) ) - BUG(); - gcry_cipher_sync (cipher_hd); - assert (!gcry_mpi_get_flag( sk->skey[i], - GCRYMPI_FLAG_OPAQUE )); - data = xmalloc (nbytes+2); - nbits = gcry_mpi_get_nbits (sk->skey[i]); - assert (nbytes == (nbits + 7)/8); - data[0] = nbits >> 8; - data[1] = nbits; - gcry_cipher_encrypt (cipher_hd, data+2, nbytes, - buffer, nbytes); - xfree ( buffer ); - - gcry_mpi_release (sk->skey[i]); - sk->skey[i] = gcry_mpi_set_opaque (NULL, data, - (nbytes+2)*8); - } - sk->csum = csum; - } - sk->is_protected = 1; - gcry_cipher_close( cipher_hd ); - } - } - return rc; -} diff --git a/g10/seskey.c b/g10/seskey.c deleted file mode 100644 index be2535ace..000000000 --- a/g10/seskey.c +++ /dev/null @@ -1,244 +0,0 @@ -/* seskey.c - make sesssion keys etc. - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "cipher.h" -#include "mpi.h" -#include "main.h" -#include "i18n.h" -#include "options.h" - -/**************** - * Make a session key and put it into DEK - */ -void -make_session_key( DEK *dek ) -{ - gcry_cipher_hd_t chd; - int i, rc; - - dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); - - if (gcry_cipher_open (&chd, dek->algo, GCRY_CIPHER_MODE_CFB, - (GCRY_CIPHER_SECURE - | (dek->algo >= 100 ? - 0 : GCRY_CIPHER_ENABLE_SYNC))) ) - BUG(); - - gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM ); - for (i=0; i < 16; i++ ) - { - rc = gcry_cipher_setkey (chd, dek->key, dek->keylen); - if (!rc) - { - gcry_cipher_close (chd); - return; - } - if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY) - BUG(); - log_info (_("weak key created - retrying\n") ); - /* Renew the session key until we get a non-weak key. */ - gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM ); - } - - log_fatal (_("cannot avoid weak key for symmetric cipher; " - "tried %d times!\n"), i); -} - - -/**************** - * Encode the session key. NBITS is the number of bits which should be used - * for packing the session key. - * returns: A mpi with the session key (caller must free) - */ -gcry_mpi_t -encode_session_key (DEK *dek, unsigned int nbits) -{ - int nframe = (nbits+7) / 8; - byte *p; - byte *frame; - int i,n; - u16 csum; - gcry_mpi_t a; - - /* the current limitation is that we can only use a session key - * whose length is a multiple of BITS_PER_MPI_LIMB - * I think we can live with that. - */ - if( dek->keylen + 7 > nframe || !nframe ) - log_bug("can't encode a %d bit key in a %d bits frame\n", - dek->keylen*8, nbits ); - - /* We encode the session key in this way: - * - * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) - * - * (But how can we store the leading 0 - the external representaion - * of MPIs doesn't allow leading zeroes =:-) - * - * RND are non-zero random bytes. - * A is the cipher algorithm - * DEK is the encryption key (session key) length k depends on the - * cipher algorithm (20 is used with blowfish160). - * CSUM is the 16 bit checksum over the DEK - */ - csum = 0; - for( p = dek->key, i=0; i < dek->keylen; i++ ) - csum += *p++; - - frame = gcry_xmalloc_secure ( nframe ); - n = 0; - frame[n++] = 0; - frame[n++] = 2; - i = nframe - 6 - dek->keylen; - assert( i > 0 ); - p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM); - /* replace zero bytes by new values */ - for(;;) { - int j, k; - byte *pp; - - /* count the zero bytes */ - for(j=k=0; j < i; j++ ) - if( !p[j] ) - k++; - if( !k ) - break; /* okay: no zero bytes */ - k += k/128; /* better get some more */ - pp = gcry_random_bytes_secure( k, GCRY_STRONG_RANDOM); - for(j=0; j < i && k ; j++ ) - if( !p[j] ) - p[j] = pp[--k]; - xfree (pp); - } - memcpy( frame+n, p, i ); - xfree (p); - n += i; - frame[n++] = 0; - frame[n++] = dek->algo; - memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen; - frame[n++] = csum >>8; - frame[n++] = csum; - assert (n == nframe); - - if (DBG_CIPHER) - log_printhex ("encoded session key:", frame, nframe ); - - if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe)) - BUG(); - xfree (frame); - return a; -} - - -static gcry_mpi_t -do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits, - const byte *asn, size_t asnlen, int v3compathack ) -{ - int nframe = (nbits+7) / 8; - byte *frame; - int i,n; - gcry_mpi_t a; - - if( len + asnlen + 4 > nframe ) - log_bug("can't encode a %d bit MD into a %d bits frame\n", - (int)(len*8), (int)nbits); - - /* We encode the MD in this way: - * - * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes) - * - * PAD consists of FF bytes. - */ - frame = gcry_md_is_secure (md)? xmalloc_secure (nframe): xmalloc (nframe); - n = 0; - frame[n++] = 0; - frame[n++] = v3compathack? algo : 1; /* block type */ - i = nframe - len - asnlen -3 ; - assert( i > 1 ); - memset( frame+n, 0xff, i ); n += i; - frame[n++] = 0; - memcpy( frame+n, asn, asnlen ); n += asnlen; - memcpy( frame+n, gcry_md_read (md, algo), len ); n += len; - assert( n == nframe ); - if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe )) - BUG(); - xfree (frame); - return a; -} - - -/**************** - * Encode a message digest into an MPI. - * v3compathack is used to work around a bug in old GnuPG versions - * which did put the algo identifier inseatd of the block type 1 into - * the encoded value. Setting this flag forces the old behaviour. - */ -gcry_mpi_t -encode_md_value (int pubkey_algo, gcry_md_hd_t md, int hash_algo, - unsigned int nbits, int v3compathack ) -{ - int algo = hash_algo? hash_algo : gcry_md_get_algo (md); - gcry_mpi_t frame; - - if (pubkey_algo == GCRY_PK_DSA) - { - size_t n = gcry_md_get_algo_dlen(hash_algo); - if (n != 20) - { - log_error (_("DSA requires the use of a 160 bit hash algorithm\n")); - return NULL; - } - if (gcry_mpi_scan( &frame, GCRYMPI_FMT_USG, - gcry_md_read (md, hash_algo), n, &n ) ) - BUG(); - } - else - { - gpg_error_t rc; - byte *asn; - size_t asnlen; - - rc = gcry_md_algo_info( algo, GCRYCTL_GET_ASNOID, NULL, &asnlen); - if (rc) - log_fatal("can't get OID of algo %d: %s\n", - algo, gpg_strerror (rc)); - asn = xmalloc (asnlen); - if( gcry_md_algo_info( algo, GCRYCTL_GET_ASNOID, asn, &asnlen ) ) - BUG(); - frame = do_encode_md( md, algo, gcry_md_get_algo_dlen( algo ), - nbits, asn, asnlen, v3compathack ); - xfree (asn); - } - return frame; -} - - - - - - diff --git a/g10/sig-check.c b/g10/sig-check.c deleted file mode 100644 index b0c89cba3..000000000 --- a/g10/sig-check.c +++ /dev/null @@ -1,575 +0,0 @@ -/* sig-check.c - Check a signature - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "packet.h" -#include "memory.h" -#include "mpi.h" -#include "keydb.h" -#include "cipher.h" -#include "main.h" -#include "status.h" -#include "i18n.h" -#include "options.h" -#include "pkglue.h" - -struct cmp_help_context_s { - PKT_signature *sig; - MD_HANDLE md; -}; - - -static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest, - int *r_expired, int *r_revoked, PKT_public_key *ret_pk); - -/**************** - * Check the signature which is contained in SIG. - * The MD_HANDLE should be currently open, so that this function - * is able to append some data, before finalizing the digest. - */ -int -signature_check( PKT_signature *sig, MD_HANDLE digest ) -{ - return signature_check2( sig, digest, NULL, NULL, NULL, NULL ); -} - -int -signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate, - int *r_expired, int *r_revoked, PKT_public_key *ret_pk ) -{ - PKT_public_key *pk = xcalloc (1, sizeof *pk ); - int rc=0; - - /* Sanity check that the md has a context for the hash that the - sig is expecting. This can happen if a onepass sig header does - not match the actual sig, and also if the clearsign "Hash:" - header is missing or does not match the actual sig. */ - - if(!gcry_md_is_enabled (digest,sig->digest_algo)) { - log_info(_("WARNING: signature digest conflict in message\n")); - rc=GPG_ERR_GENERAL; - } - else if( get_pubkey( pk, sig->keyid ) ) - rc = GPG_ERR_NO_PUBKEY; - else if(!pk->is_valid && !pk->is_primary) - rc=GPG_ERR_BAD_PUBKEY; /* you cannot have a good sig from an - invalid subkey */ - else { - if (r_expiredate) - *r_expiredate = pk->expiredate; - rc = do_check( pk, sig, digest, r_expired, r_revoked, ret_pk ); - } - - free_public_key( pk ); - - if( !rc && sig->sig_class < 2 && is_status_enabled() ) { - /* This signature id works best with DLP algorithms because - * they use a random parameter for every signature. Instead of - * this sig-id we could have also used the hash of the document - * and the timestamp, but the drawback of this is, that it is - * not possible to sign more than one identical document within - * one second. Some remote batch processing applications might - * like this feature here */ - gcry_md_hd_t md; - u32 a = sig->timestamp; - int i, nsig = pubkey_get_nsig( sig->pubkey_algo ); - byte *p, *buffer; - - gcry_md_open (&md, GCRY_MD_RMD160, 0); - gcry_md_putc( digest, sig->pubkey_algo ); - gcry_md_putc( digest, sig->digest_algo ); - gcry_md_putc( digest, (a >> 24) & 0xff ); - gcry_md_putc( digest, (a >> 16) & 0xff ); - gcry_md_putc( digest, (a >> 8) & 0xff ); - gcry_md_putc( digest, a & 0xff ); - for(i=0; i < nsig; i++ ) { - size_t n; - unsigned char *tmp; - - if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &tmp, &n, sig->data[i])) - BUG(); - - gcry_md_write (md, tmp, n); - xfree (tmp); - } - gcry_md_final( md ); - p = make_radix64_string( gcry_md_read( md, 0 ), 20 ); - buffer = xmalloc ( strlen(p) + 60 ); - sprintf( buffer, "%s %s %lu", - p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp ); - write_status_text( STATUS_SIG_ID, buffer ); - xfree (buffer); - xfree (p); - gcry_md_close(md); - } - - return rc; -} - - -static int -do_check_messages( PKT_public_key *pk, PKT_signature *sig, - int *r_expired, int *r_revoked ) -{ - u32 cur_time; - - if (r_expired) - *r_expired = 0; - if (r_revoked) - *r_revoked = 0; - if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { - log_info(_("key %08lX: this is a PGP generated " - "ElGamal key which is NOT secure for signatures!\n"), - (ulong)keyid_from_pk(pk,NULL)); - return GPG_ERR_PUBKEY_ALGO; - } - - if( pk->timestamp > sig->timestamp ) { - ulong d = pk->timestamp - sig->timestamp; - log_info( d==1 - ? _("public key %08lX is %lu second newer than the signature\n") - : _("public key %08lX is %lu seconds newer than the signature\n"), - (ulong)keyid_from_pk(pk,NULL),d ); - if( !opt.ignore_time_conflict ) - return GPG_ERR_TIME_CONFLICT; /* pubkey newer than signature */ - } - - cur_time = make_timestamp(); - if( pk->timestamp > cur_time ) { - ulong d = pk->timestamp - cur_time; - log_info( d==1 ? _("key %08lX has been created %lu second " - "in future (time warp or clock problem)\n") - : _("key %08lX has been created %lu seconds " - "in future (time warp or clock problem)\n"), - (ulong)keyid_from_pk(pk,NULL),d ); - if( !opt.ignore_time_conflict ) - return GPG_ERR_TIME_CONFLICT; - } - - if( pk->expiredate && pk->expiredate < cur_time ) { - char buf[11]; - if (opt.verbose) { - u32 tmp_kid[2]; - - keyid_from_pk( pk, tmp_kid ); - log_info(_("NOTE: signature key %08lX expired %s\n"), - (ulong)tmp_kid[1], asctimestamp( pk->expiredate ) ); - } - /* SIGEXPIRED is deprecated. Use KEYEXPIRED. */ - sprintf(buf,"%lu",(ulong)pk->expiredate); - write_status_text(STATUS_KEYEXPIRED,buf); - write_status(STATUS_SIGEXPIRED); - if (r_expired) - *r_expired = 1; - } - - if(pk->is_revoked && r_revoked) - *r_revoked=1; - - return 0; -} - - -static int -do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest, - int *r_expired, int *r_revoked, PKT_public_key *ret_pk ) -{ - gcry_mpi_t result = NULL; - int rc=0; - struct cmp_help_context_s ctx; - - if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) ) - return rc; - if( (rc=gcry_md_test_algo(sig->digest_algo)) ) - return rc; - if( (rc=gcry_pk_test_algo(sig->pubkey_algo)) ) - return rc; - - /* make sure the digest algo is enabled (in case of a detached - signature)*/ - gcry_md_enable( digest, sig->digest_algo ); - - /* complete the digest */ - if( sig->version >= 4 ) - gcry_md_putc( digest, sig->version ); - gcry_md_putc( digest, sig->sig_class ); - if( sig->version < 4 ) { - u32 a = sig->timestamp; - gcry_md_putc( digest, (a >> 24) & 0xff ); - gcry_md_putc( digest, (a >> 16) & 0xff ); - gcry_md_putc( digest, (a >> 8) & 0xff ); - gcry_md_putc( digest, a & 0xff ); - } - else { - byte buf[6]; - size_t n; - gcry_md_putc( digest, sig->pubkey_algo ); - gcry_md_putc( digest, sig->digest_algo ); - if( sig->hashed ) { - n = sig->hashed->len; - gcry_md_putc (digest, (n >> 8) ); - gcry_md_putc (digest, n ); - gcry_md_write (digest, sig->hashed->data, n); - n += 6; - } - else { - /* Two octets for the (empty) length of the hashed - section. */ - gcry_md_putc (digest, 0); - gcry_md_putc (digest, 0); - n = 6; - } - /* add some magic */ - buf[0] = sig->version; - buf[1] = 0xff; - buf[2] = n >> 24; - buf[3] = n >> 16; - buf[4] = n >> 8; - buf[5] = n; - gcry_md_write( digest, buf, 6 ); - } - gcry_md_final (digest); - - result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo, - mpi_get_nbits(pk->pkey[0]), 0 ); - if (!result) - return GPG_ERR_GENERAL; - ctx.sig = sig; - ctx.md = digest; - rc = pk_verify ( pk->pubkey_algo, result, sig->data, pk->pkey); - gcry_mpi_release ( result ); - if( (opt.emulate_bugs & EMUBUG_MDENCODE) - && gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE - && is_ELGAMAL(pk->pubkey_algo) ) { - /* In this case we try again because old GnuPG versions didn't encode - * the hash right. There is no problem with DSA however */ - result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo, - mpi_get_nbits(pk->pkey[0]), (sig->version < 5) ); - if (!result) - rc = GPG_ERR_GENERAL; - else { - ctx.sig = sig; - ctx.md = digest; - rc = pk_verify (pk->pubkey_algo, result, sig->data, pk->pkey); - } - } - - if( !rc && sig->flags.unknown_critical ) { - log_info(_("assuming bad signature from key %08lX " - "due to an unknown critical bit\n"), - (ulong)keyid_from_pk(pk,NULL)); - rc = gpg_error (GPG_ERR_BAD_SIGNATURE); - } - - if(!rc && ret_pk) - copy_public_key(ret_pk,pk); - - return rc; -} - - -static void -hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig ) -{ - PKT_user_id *uid = unode->pkt->pkt.user_id; - - assert( unode->pkt->pkttype == PKT_USER_ID ); - if( uid->attrib_data ) { - if( sig->version >=4 ) { - byte buf[5]; - buf[0] = 0xd1; /* packet of type 17 */ - buf[1] = uid->attrib_len >> 24; /* always use 4 length bytes */ - buf[2] = uid->attrib_len >> 16; - buf[3] = uid->attrib_len >> 8; - buf[4] = uid->attrib_len; - gcry_md_write( md, buf, 5 ); - } - gcry_md_write( md, uid->attrib_data, uid->attrib_len ); - } - else { - if( sig->version >=4 ) { - byte buf[5]; - buf[0] = 0xb4; /* indicates a userid packet */ - buf[1] = uid->len >> 24; /* always use 4 length bytes */ - buf[2] = uid->len >> 16; - buf[3] = uid->len >> 8; - buf[4] = uid->len; - gcry_md_write( md, buf, 5 ); - } - gcry_md_write( md, uid->name, uid->len ); - } -} - -static void -cache_sig_result ( PKT_signature *sig, int result ) -{ - if ( !result ) { - sig->flags.checked = 1; - sig->flags.valid = 1; - } - else if ( gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE ) { - sig->flags.checked = 1; - sig->flags.valid = 0; - } - else { - sig->flags.checked = 0; - sig->flags.valid = 0; - } -} - - -/* Check the revocation keys to see if any of them have revoked our - pk. sig is the revocation sig. pk is the key it is on. This code - will need to be modified if gpg ever becomes multi-threaded. Note - that this guarantees that a designated revocation sig will never be - considered valid unless it is actually valid, as well as being - issued by a revocation key in a valid direct signature. Note that - this is written so that a revoked revoker can still issue - revocations: i.e. If A revokes B, but A is revoked, B is still - revoked. I'm not completely convinced this is the proper behavior, - but it matches how PGP does it. -dms */ - -/* Returns 0 if sig is valid (i.e. pk is revoked), non-0 if not - revoked */ -int -check_revocation_keys(PKT_public_key *pk,PKT_signature *sig) -{ - static int busy=0; - int i,rc=GPG_ERR_GENERAL; - - assert(IS_KEY_REV(sig)); - assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1])); - - if(busy) - { - /* return -1 (i.e. not revoked), but mark the pk as uncacheable - as we don't really know its revocation status until it is - checked directly. */ - - pk->dont_cache=1; - return rc; - } - - busy=1; - - /* printf("looking at %08lX with a sig from %08lX\n",(ulong)pk->keyid[1], - (ulong)sig->keyid[1]); */ - - /* is the issuer of the sig one of our revokers? */ - if( !pk->revkey && pk->numrevkeys ) - BUG(); - else - for(i=0;i<pk->numrevkeys;i++) - { - u32 keyid[2]; - - keyid_from_fingerprint(pk->revkey[i].fpr,MAX_FINGERPRINT_LEN,keyid); - - if(keyid[0]==sig->keyid[0] && keyid[1]==sig->keyid[1]) - { - gcry_md_hd_t md; - - gcry_md_open (&md, sig->digest_algo,0); - hash_public_key(md,pk); - rc=signature_check(sig,md); - cache_sig_result(sig,rc); - break; - } - } - - busy=0; - - return rc; -} - -/**************** - * check the signature pointed to by NODE. This is a key signature. - * If the function detects a self-signature, it uses the PK from - * ROOT and does not read any public key. - */ -int -check_key_signature( KBNODE root, KBNODE node, int *is_selfsig ) -{ - return check_key_signature2(root, node, NULL, NULL, is_selfsig, NULL, NULL); -} - -/* If check_pk is set, then use it to check the signature in node - rather than getting it from root or the keydb. If ret_pk is set, - fill in the public key that was used to verify the signature. - ret_pk is only meaningful when the verification was successful. */ -/* TODO: add r_revoked here as well. It has the same problems as - r_expiredate and r_expired and the cache. */ -int -check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk, - PKT_public_key *ret_pk, int *is_selfsig, - u32 *r_expiredate, int *r_expired ) -{ - MD_HANDLE md; - PKT_public_key *pk; - PKT_signature *sig; - int algo; - int rc; - - if( is_selfsig ) - *is_selfsig = 0; - if( r_expiredate ) - *r_expiredate = 0; - if( r_expired ) - *r_expired = 0; - assert( node->pkt->pkttype == PKT_SIGNATURE ); - assert( root->pkt->pkttype == PKT_PUBLIC_KEY ); - - pk = root->pkt->pkt.public_key; - sig = node->pkt->pkt.signature; - algo = sig->digest_algo; - - /* check whether we have cached the result of a previous signature check.*/ - if ( !opt.no_sig_cache ) { - if (sig->flags.checked) { /*cached status available*/ - if( is_selfsig ) { - u32 keyid[2]; - - keyid_from_pk( pk, keyid ); - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) - *is_selfsig = 1; - } - /* BUG: This is wrong for non-self-sigs. Needs to be the - actual pk */ - if((rc=do_check_messages(pk,sig,r_expired,NULL))) - return rc; - return sig->flags.valid? 0 : gpg_error (GPG_ERR_BAD_SIGNATURE); - } - } - - if( (rc=gcry_md_test_algo(algo)) ) - return rc; - - if( sig->sig_class == 0x20 ) { /* key revocation */ - u32 keyid[2]; - keyid_from_pk( pk, keyid ); - - /* is it a designated revoker? */ - if(keyid[0]!=sig->keyid[0] || keyid[1]!=sig->keyid[1]) - rc=check_revocation_keys(pk,sig); - else - { - gcry_md_open (&md, algo, 0 ); - hash_public_key( md, pk ); - rc = do_check( pk, sig, md, r_expired, NULL, ret_pk ); - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } - } - else if( sig->sig_class == 0x28 ) { /* subkey revocation */ - KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY ); - - if( snode ) { - gcry_md_open (&md, algo, 0 ); - hash_public_key( md, pk ); - hash_public_key( md, snode->pkt->pkt.public_key ); - rc = do_check( pk, sig, md, r_expired, NULL, ret_pk ); - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } - else { - if (opt.verbose) - log_info (_("key %08lX: no subkey for subkey " - "revocation signature\n"), - (ulong)keyid_from_pk (pk, NULL)); - rc = GPG_ERR_SIG_CLASS; - } - } - else if( sig->sig_class == 0x18 ) { /* key binding */ - KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY ); - - if( snode ) { - if( is_selfsig ) { /* does this make sense????? */ - u32 keyid[2]; /* it should always be a selfsig */ - - keyid_from_pk( pk, keyid ); - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) - *is_selfsig = 1; - } - gcry_md_open (&md, algo, 0 ); - hash_public_key( md, pk ); - hash_public_key( md, snode->pkt->pkt.public_key ); - rc = do_check( pk, sig, md, r_expired, NULL, ret_pk ); - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } - else { - if (opt.verbose) - log_info(_("key %08lX: no subkey for subkey " - "binding signature\n"), - (ulong)keyid_from_pk (pk, NULL)); - rc = GPG_ERR_SIG_CLASS; - } - } - else if( sig->sig_class == 0x1f ) { /* direct key signature */ - gcry_md_open (&md, algo, 0 ); - hash_public_key( md, pk ); - rc = do_check( pk, sig, md, r_expired, NULL, ret_pk ); - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } - else { /* all other classes */ - KBNODE unode = find_prev_kbnode( root, node, PKT_USER_ID ); - - if( unode ) { - u32 keyid[2]; - - keyid_from_pk( pk, keyid ); - gcry_md_open (&md, algo, 0 ); - hash_public_key( md, pk ); - hash_uid_node( unode, md, sig ); - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) - { - if( is_selfsig ) - *is_selfsig = 1; - rc = do_check( pk, sig, md, r_expired, NULL, ret_pk ); - } - else if (check_pk) - rc=do_check(check_pk,sig,md,r_expired, NULL, ret_pk); - else - rc = signature_check2( sig, md, r_expiredate, r_expired, - NULL, ret_pk); - - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } - else { - if (!opt.quiet) - log_info ("key %08lX: no user ID for key signature packet " - "of class %02x\n", - (ulong)keyid_from_pk (pk, NULL), sig->sig_class ); - rc = GPG_ERR_SIG_CLASS; - } - } - - return rc; -} diff --git a/g10/sign.c b/g10/sign.c deleted file mode 100644 index cd7615c00..000000000 --- a/g10/sign.c +++ /dev/null @@ -1,1412 +0,0 @@ -/* sign.c - sign data - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <unistd.h> /* need sleep() */ - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "filter.h" -#include "ttyio.h" -#include "trustdb.h" -#include "status.h" -#include "i18n.h" -#include "pkglue.h" -#include "call-agent.h" - - -#ifdef HAVE_DOSISH_SYSTEM -#define LF "\r\n" -void __stdcall Sleep(ulong); -#define sleep(a) Sleep((a)*1000) -#else -#define LF "\n" -#endif - -static int recipient_digest_algo=0; - -/**************** - * Create a notation. We assume thIt is assumed that the strings in - * the STRLISTs of the opt struct are already checked to contain only - * printable data and have a valid NAME=VALUE format. - */ -static void -mk_notation_policy_etc( PKT_signature *sig, - PKT_public_key *pk, PKT_secret_key *sk ) -{ - const char *string; - char *s=NULL; - byte *buf; - unsigned n1, n2; - STRLIST nd=NULL,pu=NULL; - struct expando_args args; - - memset(&args,0,sizeof(args)); - args.pk=pk; - args.sk=sk; - - /* It is actually impossible to get here when making a v3 key - signature since keyedit.c:sign_uids will automatically bump a - signature with a notation or policy url up to v4, but it is - good to do these checks anyway. */ - - /* notation data */ - if(IS_SIG(sig) && opt.sig_notation_data) - { - if(sig->version<4) - log_error(_("can't put notation data into v3 (PGP 2.x style) " - "signatures\n")); - else - nd=opt.sig_notation_data; - } - else if( IS_CERT(sig) && opt.cert_notation_data ) - { - if(sig->version<4) - log_error(_("can't put notation data into v3 (PGP 2.x style) " - "key signatures\n")); - else - nd=opt.cert_notation_data; - } - - for( ; nd; nd = nd->next ) { - char *expanded; - - string = nd->d; - s = strchr( string, '=' ); - if( !s ) - BUG(); /* we have already parsed this */ - n1 = s - string; - s++; - - expanded=pct_expando(s,&args); - if(!expanded) - { - log_error(_("WARNING: unable to %%-expand notation " - "(too large). Using unexpanded.\n")); - expanded=xstrdup (s); - } - - n2 = strlen(expanded); - buf = xmalloc ( 8 + n1 + n2 ); - buf[0] = 0x80; /* human readable */ - buf[1] = buf[2] = buf[3] = 0; - buf[4] = n1 >> 8; - buf[5] = n1; - buf[6] = n2 >> 8; - buf[7] = n2; - memcpy(buf+8, string, n1 ); - memcpy(buf+8+n1, expanded, n2 ); - build_sig_subpkt( sig, SIGSUBPKT_NOTATION - | ((nd->flags & 1)? SIGSUBPKT_FLAG_CRITICAL:0), - buf, 8+n1+n2 ); - xfree (expanded); - xfree (buf); - } - - /* set policy URL */ - if( IS_SIG(sig) && opt.sig_policy_url ) - { - if(sig->version<4) - log_error(_("can't put a policy URL into v3 (PGP 2.x style) " - "signatures\n")); - else - pu=opt.sig_policy_url; - } - else if( IS_CERT(sig) && opt.cert_policy_url ) - { - if(sig->version<4) - log_error(_("can't put a policy URL into v3 key (PGP 2.x style) " - "signatures\n")); - else - pu=opt.cert_policy_url; - } - - for(;pu;pu=pu->next) - { - string = pu->d; - - s=pct_expando(string,&args); - if(!s) - { - log_error(_("WARNING: unable to %%-expand policy url " - "(too large). Using unexpanded.\n")); - s=xstrdup (string); - } - - build_sig_subpkt(sig,SIGSUBPKT_POLICY| - ((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0), - s,strlen(s)); - - xfree (s); - } - - /* preferred keyserver URL */ - if( IS_SIG(sig) && opt.sig_keyserver_url ) - { - if(sig->version<4) - log_info (_("can't put a preferred keyserver URL " - "into v3 signatures\n")); - else - pu=opt.sig_keyserver_url; - } - - for(;pu;pu=pu->next) - { - string = pu->d; - - s=pct_expando(string,&args); - if(!s) - { - log_error(_("WARNING: unable to %%-expand preferred keyserver URL" - " (too large). Using unexpanded.\n")); - s=xstrdup(string); - } - - build_sig_subpkt(sig,SIGSUBPKT_PREF_KS| - ((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0), - s,strlen(s)); - - xfree(s); - } -} - - -/* - * Helper to hash a user ID packet. - */ -static void -hash_uid (MD_HANDLE md, int sigversion, const PKT_user_id *uid) -{ - if ( sigversion >= 4 ) { - byte buf[5]; - - if(uid->attrib_data) { - buf[0] = 0xd1; /* indicates an attribute packet */ - buf[1] = uid->attrib_len >> 24; /* always use 4 length bytes */ - buf[2] = uid->attrib_len >> 16; - buf[3] = uid->attrib_len >> 8; - buf[4] = uid->attrib_len; - } - else { - buf[0] = 0xb4; /* indicates a userid packet */ - buf[1] = uid->len >> 24; /* always use 4 length bytes */ - buf[2] = uid->len >> 16; - buf[3] = uid->len >> 8; - buf[4] = uid->len; - } - gcry_md_write( md, buf, 5 ); - } - - if(uid->attrib_data) - gcry_md_write (md, uid->attrib_data, uid->attrib_len ); - else - gcry_md_write (md, uid->name, uid->len ); -} - - -/* - * Helper to hash some parts from the signature - */ -static void -hash_sigversion_to_magic (MD_HANDLE md, const PKT_signature *sig) -{ - if (sig->version >= 4) - gcry_md_putc (md, sig->version); - gcry_md_putc (md, sig->sig_class); - if (sig->version < 4) { - u32 a = sig->timestamp; - gcry_md_putc (md, (a >> 24) & 0xff ); - gcry_md_putc (md, (a >> 16) & 0xff ); - gcry_md_putc (md, (a >> 8) & 0xff ); - gcry_md_putc (md, a & 0xff ); - } - else { - byte buf[6]; - size_t n; - - gcry_md_putc (md, sig->pubkey_algo); - gcry_md_putc (md, sig->digest_algo); - if (sig->hashed) { - n = sig->hashed->len; - gcry_md_putc (md, (n >> 8) ); - gcry_md_putc (md, n ); - gcry_md_write (md, sig->hashed->data, n ); - n += 6; - } - else { - gcry_md_putc (md, 0); /* always hash the length of the subpacket*/ - gcry_md_putc (md, 0); - n = 6; - } - /* add some magic */ - buf[0] = sig->version; - buf[1] = 0xff; - buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */ - buf[3] = n >> 16; - buf[4] = n >> 8; - buf[5] = n; - gcry_md_write (md, buf, 6); - } -} - - -static int -do_sign( PKT_secret_key *sk, PKT_signature *sig, - MD_HANDLE md, int digest_algo ) -{ - gcry_mpi_t frame; - byte *dp; - int rc; - - if( sk->timestamp > sig->timestamp ) { - ulong d = sk->timestamp - sig->timestamp; - log_info( d==1 ? _("key has been created %lu second " - "in future (time warp or clock problem)\n") - : _("key has been created %lu seconds " - "in future (time warp or clock problem)\n"), d ); - if( !opt.ignore_time_conflict ) - return GPG_ERR_TIME_CONFLICT; - } - - print_pubkey_algo_note(sk->pubkey_algo); - - if( !digest_algo ) - digest_algo = gcry_md_get_algo(md); - - print_digest_algo_note( digest_algo ); - dp = gcry_md_read ( md, digest_algo ); - sig->digest_algo = digest_algo; - sig->digest_start[0] = dp[0]; - sig->digest_start[1] = dp[1]; - if (sk->is_protected && sk->protect.s2k.mode == 1002) - { /* FIXME: Note that we do only support RSA for now. */ - char *rbuf; - size_t rbuflen; - char *snbuf; - - snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk); - rc = agent_scd_pksign (snbuf, digest_algo, - gcry_md_read (md, digest_algo), - gcry_md_get_algo_dlen (digest_algo), - &rbuf, &rbuflen); - xfree (snbuf); - if (!rc) - { - if (gcry_mpi_scan (&sig->data[0], GCRYMPI_FMT_USG, - rbuf, rbuflen, NULL)) - BUG (); - } - } - else - { - frame = encode_md_value( sk->pubkey_algo, md, - digest_algo, mpi_get_nbits(sk->skey[0]), 0 ); - if (!frame) - return GPG_ERR_GENERAL; - rc = pk_sign( sk->pubkey_algo, sig->data, frame, sk->skey ); - gcry_mpi_release (frame); - } - if (!rc && !opt.no_sig_create_check) { - /* check that the signature verification worked and nothing is - * fooling us e.g. by a bug in the signature create - * code or by deliberately introduced faults. */ - PKT_public_key *pk = xcalloc (1,sizeof *pk); - - if( get_pubkey( pk, sig->keyid ) ) - rc = GPG_ERR_NO_PUBKEY; - else { - frame = encode_md_value (pk->pubkey_algo, md, - sig->digest_algo, - mpi_get_nbits(pk->pkey[0]), 0); - if (!frame) - rc = GPG_ERR_GENERAL; - else - rc = pk_verify (pk->pubkey_algo, frame, - sig->data, pk->pkey); - gcry_mpi_release (frame); - } - if (rc) - log_error (_("checking created signature failed: %s\n"), - gpg_strerror (rc)); - free_public_key (pk); - } - if( rc ) - log_error(_("signing failed: %s\n"), gpg_strerror (rc) ); - else { - if( opt.verbose ) { - char *ustr = get_user_id_string_printable (sig->keyid); - log_info(_("%s/%s signature from: \"%s\"\n"), - gcry_pk_algo_name (sk->pubkey_algo), - gcry_md_algo_name (sig->digest_algo), - ustr ); - xfree (ustr); - } - } - return rc; -} - - - -int -complete_sig( PKT_signature *sig, PKT_secret_key *sk, MD_HANDLE md ) -{ - int rc=0; - - if( !(rc=check_secret_key( sk, 0 )) ) - rc = do_sign( sk, sig, md, 0 ); - return rc; -} - -static int -hash_for(int pubkey_algo, int packet_version ) -{ - if( opt.def_digest_algo ) - return opt.def_digest_algo; - else if( recipient_digest_algo ) - return recipient_digest_algo; - else if(PGP2 && pubkey_algo == PUBKEY_ALGO_RSA && packet_version < 4 ) - { - /* Old-style PGP only understands MD5 */ - return DIGEST_ALGO_MD5; - } - else if( pubkey_algo == PUBKEY_ALGO_DSA ) - { - /* We need a 160-bit hash for DSA, so we can't just take the first - in the pref list */ - - if(opt.personal_digest_prefs) - { - prefitem_t *prefs; - - for(prefs=opt.personal_digest_prefs;prefs->type;prefs++) - if(gcry_md_get_algo_dlen (prefs->value) == 20) - return prefs->value; - } - - return DIGEST_ALGO_SHA1; - } - else if( opt.personal_digest_prefs ) - { - /* It's not DSA, so we can use whatever the first hash algorithm - is in the pref list */ - return opt.personal_digest_prefs[0].value; - } - else - return DEFAULT_DIGEST_ALGO; -} - -static int -only_old_style( SK_LIST sk_list ) -{ - SK_LIST sk_rover = NULL; - int old_style = 0; - - /* if there are only old style capable key we use the old sytle */ - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - PKT_secret_key *sk = sk_rover->sk; - if( sk->pubkey_algo == PUBKEY_ALGO_RSA && sk->version < 4 ) - old_style = 1; - else - return 0; - } - return old_style; -} - - -static void -print_status_sig_created ( PKT_secret_key *sk, PKT_signature *sig, int what ) -{ - byte array[MAX_FINGERPRINT_LEN], *p; - char buf[100+MAX_FINGERPRINT_LEN*2]; - size_t i, n; - - sprintf(buf, "%c %d %d %02x %lu ", - what, sig->pubkey_algo, sig->digest_algo, sig->sig_class, - (ulong)sig->timestamp ); - - fingerprint_from_sk( sk, array, &n ); - p = buf + strlen(buf); - for(i=0; i < n ; i++ ) - sprintf(p+2*i, "%02X", array[i] ); - - write_status_text( STATUS_SIG_CREATED, buf ); -} - - -/* - * Loop over the secret certificates in SK_LIST and build the one pass - * signature packets. OpenPGP says that the data should be bracket by - * the onepass-sig and signature-packet; so we build these onepass - * packet here in reverse order - */ -static int -write_onepass_sig_packets (SK_LIST sk_list, iobuf_t out, int sigclass ) -{ - int skcount; - SK_LIST sk_rover; - - for (skcount=0, sk_rover=sk_list; sk_rover; sk_rover = sk_rover->next) - skcount++; - - for (; skcount; skcount--) { - PKT_secret_key *sk; - PKT_onepass_sig *ops; - PACKET pkt; - int i, rc; - - for (i=0, sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - if (++i == skcount) - break; - } - - sk = sk_rover->sk; - ops = xcalloc (1,sizeof *ops); - ops->sig_class = sigclass; - ops->digest_algo = hash_for (sk->pubkey_algo, sk->version); - ops->pubkey_algo = sk->pubkey_algo; - keyid_from_sk (sk, ops->keyid); - ops->last = (skcount == 1); - - init_packet(&pkt); - pkt.pkttype = PKT_ONEPASS_SIG; - pkt.pkt.onepass_sig = ops; - rc = build_packet (out, &pkt); - free_packet (&pkt); - if (rc) { - log_error ("build onepass_sig packet failed: %s\n", - gpg_strerror (rc)); - return rc; - } - } - - return 0; -} - -/* - * Helper to write the plaintext (literal data) packet - */ -static int -write_plaintext_packet (iobuf_t out, iobuf_t inp, const char *fname, int ptmode) -{ - PKT_plaintext *pt = NULL; - u32 filesize; - int rc = 0; - - if (!opt.no_literal) { - if (fname || opt.set_filename) { - char *s = make_basename (opt.set_filename? opt.set_filename - : fname - /*, iobuf_get_real_fname(inp)*/); - pt = xmalloc (sizeof *pt + strlen(s) - 1); - pt->namelen = strlen (s); - memcpy (pt->name, s, pt->namelen); - xfree (s); - } - else { /* no filename */ - pt = xmalloc (sizeof *pt - 1); - pt->namelen = 0; - } - } - - /* try to calculate the length of the data */ - if (fname && *fname && !(*fname=='-' && !fname[1])) { - if( !(filesize = iobuf_get_filelength(inp)) ) - log_info (_("WARNING: `%s' is an empty file\n"), fname); - - /* we can't yet encode the length of very large files, - * so we switch to partial length encoding in this case */ - if (filesize >= IOBUF_FILELENGTH_LIMIT) - filesize = 0; - - /* because the text_filter modifies the length of the - * data, it is not possible to know the used length - * without a double read of the file - to avoid that - * we simple use partial length packets. - */ - if ( ptmode == 't' ) - filesize = 0; - } - else { - filesize = opt.set_filesize? opt.set_filesize : 0; /* stdin */ - } - - if (!opt.no_literal) { - PACKET pkt; - - pt->timestamp = make_timestamp (); - pt->mode = ptmode; - pt->len = filesize; - pt->new_ctb = !pt->len && !RFC1991; - pt->buf = inp; - init_packet(&pkt); - pkt.pkttype = PKT_PLAINTEXT; - pkt.pkt.plaintext = pt; - /*cfx.datalen = filesize? calc_packet_length( &pkt ) : 0;*/ - if( (rc = build_packet (out, &pkt)) ) - log_error ("build_packet(PLAINTEXT) failed: %s\n", - gpg_strerror (rc) ); - pt->buf = NULL; - } - else { - byte copy_buffer[4096]; - int bytes_copied; - - while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1) - if ( (rc=iobuf_write(out, copy_buffer, bytes_copied) )) { - log_error ("copying input to output failed: %s\n", - gpg_strerror (rc)); - break; - } - wipememory(copy_buffer,4096); /* burn buffer */ - } - /* fixme: it seems that we never freed pt/pkt */ - - return rc; -} - -/* - * Write the signatures from the SK_LIST to OUT. HASH must be a non-finalized - * hash which will not be changes here. - */ -static int -write_signature_packets (SK_LIST sk_list, iobuf_t out, MD_HANDLE hash, - int sigclass, u32 timestamp, u32 duration, - int status_letter) -{ - SK_LIST sk_rover; - - /* loop over the secret certificates */ - for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) { - PKT_secret_key *sk; - PKT_signature *sig; - MD_HANDLE md; - int rc; - - sk = sk_rover->sk; - - /* build the signature packet */ - sig = xcalloc (1,sizeof *sig); - if(opt.force_v3_sigs || RFC1991) - sig->version=3; - else if(duration || opt.sig_policy_url - || opt.sig_notation_data || opt.sig_keyserver_url) - sig->version=4; - else - sig->version=sk->version; - keyid_from_sk (sk, sig->keyid); - sig->digest_algo = hash_for (sk->pubkey_algo, sk->version); - sig->pubkey_algo = sk->pubkey_algo; - if(timestamp) - sig->timestamp = timestamp; - else - sig->timestamp = make_timestamp(); - if(duration) - sig->expiredate = sig->timestamp+duration; - sig->sig_class = sigclass; - - gcry_md_copy (&md, hash); - - if (sig->version >= 4) - build_sig_subpkt_from_sig (sig); - mk_notation_policy_etc (sig, NULL, sk); - - hash_sigversion_to_magic (md, sig); - gcry_md_final (md); - - rc = do_sign( sk, sig, md, hash_for (sig->pubkey_algo, sk->version) ); - gcry_md_close (md); - - if( !rc ) { /* and write it */ - PACKET pkt; - - init_packet(&pkt); - pkt.pkttype = PKT_SIGNATURE; - pkt.pkt.signature = sig; - rc = build_packet (out, &pkt); - if (!rc && is_status_enabled()) { - print_status_sig_created ( sk, sig, status_letter); - } - free_packet (&pkt); - if (rc) - log_error ("build signature packet failed: %s\n", - gpg_strerror (rc) ); - } - if( rc ) - return rc;; - } - - return 0; -} - -/**************** - * Sign the files whose names are in FILENAME. - * If DETACHED has the value true, - * make a detached signature. If FILENAMES->d is NULL read from stdin - * and ignore the detached mode. Sign the file with all secret keys - * which can be taken from LOCUSR, if this is NULL, use the default one - * If ENCRYPTFLAG is true, use REMUSER (or ask if it is NULL) to encrypt the - * signed data for these users. - * If OUTFILE is not NULL; this file is used for output and the function - * does not ask for overwrite permission; output is then always - * uncompressed, non-armored and in binary mode. - */ -int -sign_file( STRLIST filenames, int detached, STRLIST locusr, - int encryptflag, STRLIST remusr, const char *outfile ) -{ - const char *fname; - armor_filter_context_t afx; - compress_filter_context_t zfx; - md_filter_context_t mfx; - text_filter_context_t tfx; - progress_filter_context_t pfx; - encrypt_filter_context_t efx; - iobuf_t inp = NULL, out = NULL; - PACKET pkt; - int rc = 0; - PK_LIST pk_list = NULL; - SK_LIST sk_list = NULL; - SK_LIST sk_rover = NULL; - int multifile = 0; - u32 duration=0; - - memset( &afx, 0, sizeof afx); - memset( &zfx, 0, sizeof zfx); - memset( &mfx, 0, sizeof mfx); - memset( &efx, 0, sizeof efx); - init_packet( &pkt ); - - if( filenames ) { - fname = filenames->d; - multifile = !!filenames->next; - } - else - fname = NULL; - - if( fname && filenames->next && (!detached || encryptflag) ) - log_bug("multiple files can only be detached signed"); - - if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991) - duration=ask_expire_interval(1); - - if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) ) - goto leave; - - if(PGP2 && !only_old_style(sk_list)) - { - log_info(_("you can only detach-sign with PGP 2.x style keys " - "while in --pgp2 mode\n")); - compliance_failure(); - } - - if(encryptflag && (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC ))) - goto leave; - - /* prepare iobufs */ - if( multifile ) /* have list of filenames */ - inp = NULL; /* we do it later */ - else { - if( !(inp = iobuf_open(fname)) ) { - rc = gpg_error_from_errno (errno); - log_error("can't open %s: %s\n", fname? fname: "[stdin]", - strerror(errno) ); - goto leave; - } - - handle_progress (&pfx, inp, fname); - } - - if( outfile ) { - if( !(out = iobuf_create( outfile )) ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't create %s: %s\n"), outfile, strerror(errno) ); - goto leave; - } - else if( opt.verbose ) - log_info(_("writing to `%s'\n"), outfile ); - } - else if( (rc = open_outfile( fname, opt.armor? 1: detached? 2:0, &out ))) - goto leave; - - /* prepare to calculate the MD over the input */ - if( opt.textmode && !outfile && !multifile ) - { - memset( &tfx, 0, sizeof tfx); - iobuf_push_filter( inp, text_filter, &tfx ); - } - - gcry_md_open (&mfx.md, 0, 0); - - /* If we're encrypting and signing, it is reasonable to pick the - hash algorithm to use out of the recepient key prefs. */ - if(pk_list) - { - if(opt.def_digest_algo) - { - if(!opt.expert && - select_algo_from_prefs(pk_list,PREFTYPE_HASH, - opt.def_digest_algo, - NULL)!=opt.def_digest_algo) - log_info(_("forcing digest algorithm %s (%d) " - "violates recipient preferences\n"), - gcry_md_algo_name (opt.def_digest_algo), - opt.def_digest_algo); - } - else - { - int hashlen=0,algo; - - /* Of course, if the recipient asks for something - unreasonable (like a non-160-bit hash for DSA, for - example), then don't do it. Check all sk's - if any - are DSA, then the hash must be 160-bit. In the future - this can be more complex with different hashes for each - sk, but so long as there is only one signing algorithm - with hash restrictions, this is ok. -dms */ - - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) - if(sk_rover->sk->pubkey_algo==PUBKEY_ALGO_DSA) - hashlen=20; - - if((algo= - select_algo_from_prefs(pk_list,PREFTYPE_HASH,-1, - hashlen?&hashlen:NULL))>0) - recipient_digest_algo=algo; - } - } - - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - PKT_secret_key *sk = sk_rover->sk; - gcry_md_enable (mfx.md, hash_for(sk->pubkey_algo, sk->version )); - } - - if( !multifile ) - iobuf_push_filter( inp, md_filter, &mfx ); - - if( detached && !encryptflag && !RFC1991 ) - afx.what = 2; - - if( opt.armor && !outfile ) - iobuf_push_filter( out, armor_filter, &afx ); - - if( encryptflag ) { - efx.pk_list = pk_list; - /* fixme: set efx.cfx.datalen if known */ - iobuf_push_filter( out, encrypt_filter, &efx ); - } - - if( opt.compress && !outfile && ( !detached || opt.compress_sigs) ) - { - int compr_algo=opt.def_compress_algo; - - /* If not forced by user */ - if(compr_algo==-1) - { - /* If we're not encrypting, then select_algo_from_prefs - will fail and we'll end up with the default. If we are - encrypting, select_algo_from_prefs cannot fail since - there is an assumed preference for uncompressed data. - Still, if it did fail, we'll also end up with the - default. */ - - if((compr_algo= - select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1) - compr_algo=default_compress_algo(); - } - else if(!opt.expert && pk_list - && select_algo_from_prefs(pk_list,PREFTYPE_ZIP, - compr_algo,NULL)!=compr_algo) - log_info(_("forcing compression algorithm %s (%d) " - "violates recipient preferences\n"), - compress_algo_to_string(compr_algo),compr_algo); - - /* algo 0 means no compression */ - if( compr_algo ) - { - zfx.algo = compr_algo; - iobuf_push_filter( out, compress_filter, &zfx ); - } - } - - /* Write the one-pass signature packets if needed */ - if (!detached && !RFC1991) { - rc = write_onepass_sig_packets (sk_list, out, - opt.textmode && !outfile ? 0x01:0x00); - if (rc) - goto leave; - } - - /* setup the inner packet */ - if( detached ) { - if( multifile ) { - STRLIST sl; - - if( opt.verbose ) - log_info(_("signing:") ); - /* must walk reverse trough this list */ - for( sl = strlist_last(filenames); sl; - sl = strlist_prev( filenames, sl ) ) { - if( !(inp = iobuf_open(sl->d)) ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't open %s: %s\n"), - sl->d, strerror(errno) ); - goto leave; - } - handle_progress (&pfx, inp, sl->d); - if( opt.verbose ) - fprintf(stderr, " `%s'", sl->d ); - if(opt.textmode) - { - memset( &tfx, 0, sizeof tfx); - iobuf_push_filter( inp, text_filter, &tfx ); - } - iobuf_push_filter( inp, md_filter, &mfx ); - while( iobuf_get(inp) != -1 ) - ; - iobuf_close(inp); inp = NULL; - } - if( opt.verbose ) - putc( '\n', stderr ); - } - else { - /* read, so that the filter can calculate the digest */ - while( iobuf_get(inp) != -1 ) - ; - } - } - else { - rc = write_plaintext_packet (out, inp, fname, - opt.textmode && !outfile ? 't':'b'); - } - - /* catch errors from above */ - if (rc) - goto leave; - - /* write the signatures */ - rc = write_signature_packets (sk_list, out, mfx.md, - opt.textmode && !outfile? 0x01 : 0x00, - 0, duration, detached ? 'D':'S'); - if( rc ) - goto leave; - - - leave: - if( rc ) - iobuf_cancel(out); - else { - iobuf_close(out); - if (encryptflag) - write_status( STATUS_END_ENCRYPTION ); - } - iobuf_close(inp); - gcry_md_close ( mfx.md ); - release_sk_list( sk_list ); - release_pk_list( pk_list ); - recipient_digest_algo=0; - return rc; -} - - - -/**************** - * make a clear signature. note that opt.armor is not needed - */ -int -clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) -{ - armor_filter_context_t afx; - progress_filter_context_t pfx; - MD_HANDLE textmd = NULL; - iobuf_t inp = NULL, out = NULL; - PACKET pkt; - int rc = 0; - SK_LIST sk_list = NULL; - SK_LIST sk_rover = NULL; - int old_style = RFC1991; - int only_md5 = 0; - u32 duration=0; - - memset( &afx, 0, sizeof afx); - init_packet( &pkt ); - - if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991) - duration=ask_expire_interval(1); - - if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) ) - goto leave; - - if( !old_style && !duration ) - old_style = only_old_style( sk_list ); - - if(PGP2 && !only_old_style(sk_list)) - { - log_info(_("you can only clearsign with PGP 2.x style keys " - "while in --pgp2 mode\n")); - compliance_failure(); - } - - /* prepare iobufs */ - if( !(inp = iobuf_open(fname)) ) { - rc = gpg_error_from_errno (errno); - log_error("can't open %s: %s\n", fname? fname: "[stdin]", - strerror(errno) ); - goto leave; - } - handle_progress (&pfx, inp, fname); - - if( outfile ) { - if( !(out = iobuf_create( outfile )) ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't create %s: %s\n"), outfile, strerror(errno) ); - goto leave; - } - else if( opt.verbose ) - log_info(_("writing to `%s'\n"), outfile ); - } - else if( (rc = open_outfile( fname, 1, &out )) ) - goto leave; - - iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----" LF ); - - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - PKT_secret_key *sk = sk_rover->sk; - if( hash_for(sk->pubkey_algo, sk->version) == DIGEST_ALGO_MD5 ) - only_md5 = 1; - else { - only_md5 = 0; - break; - } - } - - if( !(old_style && only_md5) ) { - const char *s; - int any = 0; - byte hashs_seen[256]; - - memset( hashs_seen, 0, sizeof hashs_seen ); - iobuf_writestr(out, "Hash: " ); - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - PKT_secret_key *sk = sk_rover->sk; - int i = hash_for(sk->pubkey_algo, sk->version); - - if( !hashs_seen[ i & 0xff ] ) { - s = gcry_md_algo_name (i); - if( s ) { - hashs_seen[ i & 0xff ] = 1; - if( any ) - iobuf_put(out, ',' ); - iobuf_writestr(out, s ); - any = 1; - } - } - } - assert(any); - iobuf_writestr(out, LF ); - } - - if( opt.not_dash_escaped ) - iobuf_writestr( out, - "NotDashEscaped: You need GnuPG to verify this message" LF ); - iobuf_writestr(out, LF ); - - gcry_md_open (&textmd, 0, 0); - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - PKT_secret_key *sk = sk_rover->sk; - gcry_md_enable (textmd, hash_for(sk->pubkey_algo, sk->version)); - } - if ( DBG_HASHING ) - gcry_md_start_debug ( textmd, "clearsign" ); - copy_clearsig_text( out, inp, textmd, !opt.not_dash_escaped, - opt.escape_from, (old_style && only_md5) ); - /* fixme: check for read errors */ - - /* now write the armor */ - afx.what = 2; - iobuf_push_filter( out, armor_filter, &afx ); - - /* write the signatures */ - rc=write_signature_packets (sk_list, out, textmd, 0x01, 0, duration, 'C'); - if( rc ) - goto leave; - - leave: - if( rc ) - iobuf_cancel(out); - else - iobuf_close(out); - iobuf_close(inp); - gcry_md_close ( textmd ); - release_sk_list( sk_list ); - return rc; -} - -/* - * Sign and conventionally encrypt the given file. - * FIXME: Far too much code is duplicated - revamp the whole file. - */ -int -sign_symencrypt_file (const char *fname, STRLIST locusr) -{ - armor_filter_context_t afx; - progress_filter_context_t pfx; - compress_filter_context_t zfx; - md_filter_context_t mfx; - text_filter_context_t tfx; - cipher_filter_context_t cfx; - iobuf_t inp = NULL, out = NULL; - PACKET pkt; - STRING2KEY *s2k = NULL; - int rc = 0; - SK_LIST sk_list = NULL; - SK_LIST sk_rover = NULL; - int algo; - u32 duration=0; - - memset( &afx, 0, sizeof afx); - memset( &zfx, 0, sizeof zfx); - memset( &mfx, 0, sizeof mfx); - memset( &tfx, 0, sizeof tfx); - memset( &cfx, 0, sizeof cfx); - init_packet( &pkt ); - - if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991) - duration=ask_expire_interval(1); - - rc = build_sk_list (locusr, &sk_list, 1, PUBKEY_USAGE_SIG); - if (rc) - goto leave; - - /* prepare iobufs */ - inp = iobuf_open(fname); - if( !inp ) { - rc = gpg_error_from_errno (errno); - log_error("can't open %s: %s\n", fname? fname: "[stdin]", - strerror(errno) ); - goto leave; - } - handle_progress (&pfx, inp, fname); - - /* prepare key */ - s2k = xcalloc (1, sizeof *s2k ); - s2k->mode = RFC1991? 0:opt.s2k_mode; - s2k->hash_algo = opt.s2k_digest_algo; - - algo = default_cipher_algo(); - if (!opt.quiet || !opt.batch) - log_info (_("%s encryption will be used\n"), - gcry_cipher_algo_name (algo) ); - cfx.dek = passphrase_to_dek( NULL, 0, algo, s2k, 2, NULL, NULL); - - if (!cfx.dek || !cfx.dek->keylen) { - rc = gpg_error (GPG_ERR_INV_PASSPHRASE); - log_error(_("error creating passphrase: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - /* now create the outfile */ - rc = open_outfile (fname, opt.armor? 1:0, &out); - if (rc) - goto leave; - - /* prepare to calculate the MD over the input */ - if (opt.textmode) - iobuf_push_filter (inp, text_filter, &tfx); - gcry_md_open (&mfx.md, 0, 0); - - for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) { - PKT_secret_key *sk = sk_rover->sk; - gcry_md_enable (mfx.md, hash_for (sk->pubkey_algo, sk->version )); - } - - iobuf_push_filter (inp, md_filter, &mfx); - - /* Push armor output filter */ - if (opt.armor) - iobuf_push_filter (out, armor_filter, &afx); - - /* Write the symmetric key packet */ - /*(current filters: armor)*/ - if (!RFC1991) { - PKT_symkey_enc *enc = xcalloc (1, sizeof *enc ); - enc->version = 4; - enc->cipher_algo = cfx.dek->algo; - enc->s2k = *s2k; - pkt.pkttype = PKT_SYMKEY_ENC; - pkt.pkt.symkey_enc = enc; - if( (rc = build_packet( out, &pkt )) ) - log_error("build symkey packet failed: %s\n", gpg_strerror (rc) ); - xfree (enc); - } - - /* Push the encryption filter */ - iobuf_push_filter( out, cipher_filter, &cfx ); - - /* Push the Zip filter */ - if (opt.compress && default_compress_algo()) - { - zfx.algo = default_compress_algo(); - iobuf_push_filter( out, compress_filter, &zfx ); - } - - /* Write the one-pass signature packets */ - /*(current filters: zip - encrypt - armor)*/ - if (!RFC1991) { - rc = write_onepass_sig_packets (sk_list, out, - opt.textmode? 0x01:0x00); - if (rc) - goto leave; - } - - /* Pipe data through all filters; i.e. write the signed stuff */ - /*(current filters: zip - encrypt - armor)*/ - rc = write_plaintext_packet (out, inp, fname, opt.textmode ? 't':'b'); - if (rc) - goto leave; - - /* Write the signatures */ - /*(current filters: zip - encrypt - armor)*/ - rc = write_signature_packets (sk_list, out, mfx.md, - opt.textmode? 0x01 : 0x00, - 0, duration, 'S'); - if( rc ) - goto leave; - - - leave: - if( rc ) - iobuf_cancel(out); - else { - iobuf_close(out); - write_status( STATUS_END_ENCRYPTION ); - } - iobuf_close(inp); - release_sk_list( sk_list ); - gcry_md_close ( mfx.md ); - xfree (cfx.dek); - xfree (s2k); - return rc; -} - - -/**************** - * Create a signature packet for the given public key certificate and - * the user id and return it in ret_sig. User signature class SIGCLASS - * user-id is not used (and may be NULL if sigclass is 0x20) If - * DIGEST_ALGO is 0 the function selects an appropriate one. - * SIGVERSION gives the minimal required signature packet version; - * this is needed so that special properties like local sign are not - * applied (actually: dropped) when a v3 key is used. TIMESTAMP is - * the timestamp to use for the signature. 0 means "now". */ -int -make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, - PKT_user_id *uid, PKT_public_key *subpk, - PKT_secret_key *sk, - int sigclass, int digest_algo, - int sigversion, u32 timestamp, u32 duration, - int (*mksubpkt)(PKT_signature *, void *), void *opaque - ) -{ - PKT_signature *sig; - int rc=0; - MD_HANDLE md; - - assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F - || sigclass == 0x20 || sigclass == 0x18 - || sigclass == 0x30 || sigclass == 0x28 ); - - if (opt.force_v4_certs) - sigversion = 4; - - if (sigversion < sk->version) - sigversion = sk->version; - - /* If you are making a signature on a v4 key using your v3 key, it - doesn't make sense to generate a v3 sig. After all, no v3-only - PGP implementation could understand the v4 key in the first - place. Note that this implies that a signature on an attribute - uid is usually going to be v4 as well, since they are not - generally found on v3 keys. */ - if (sigversion < pk->version) - sigversion = pk->version; - - if( !digest_algo ) - { - /* Basically, this means use SHA1 always unless it's a v3 RSA - key making a v3 cert (use MD5), or the user specified - something (use whatever they said). They still must use a - 160-bit hash with DSA, or the signature will fail. Note - that this still allows the caller of make_keysig_packet to - override the user setting if it must. */ - - if(opt.cert_digest_algo) - digest_algo=opt.cert_digest_algo; - else if((sk->pubkey_algo==PUBKEY_ALGO_RSA || - sk->pubkey_algo==PUBKEY_ALGO_RSA_S) && - pk->version<4 && sigversion < 4) - digest_algo = DIGEST_ALGO_MD5; - else - digest_algo = DIGEST_ALGO_SHA1; - } - - gcry_md_open (&md, digest_algo, 0 ); - - /* hash the public key certificate and the user id */ - hash_public_key( md, pk ); - if( sigclass == 0x18 || sigclass == 0x28 ) { /* subkey binding/revocation*/ - hash_public_key( md, subpk ); - } - else if( sigclass != 0x1F && sigclass != 0x20 ) { - hash_uid (md, sigversion, uid); - } - /* and make the signature packet */ - sig = xcalloc (1, sizeof *sig ); - sig->version = sigversion; - sig->flags.exportable=1; - sig->flags.revocable=1; - keyid_from_sk( sk, sig->keyid ); - sig->pubkey_algo = sk->pubkey_algo; - sig->digest_algo = digest_algo; - if(timestamp) - sig->timestamp=timestamp; - else - sig->timestamp=make_timestamp(); - if(duration) - sig->expiredate=sig->timestamp+duration; - sig->sig_class = sigclass; - if( sig->version >= 4 ) - build_sig_subpkt_from_sig( sig ); - mk_notation_policy_etc ( sig, pk, sk ); - - /* Crucial that the call to mksubpkt comes LAST before the calls - to finalize the sig as that makes it possible for the mksubpkt - function to get a reliable pointer to the subpacket area. */ - if( sig->version >= 4 && mksubpkt ) - rc = (*mksubpkt)( sig, opaque ); - - if( !rc ) { - hash_sigversion_to_magic (md, sig); - gcry_md_final (md); - - rc = complete_sig( sig, sk, md ); - } - - gcry_md_close ( md ); - if( rc ) - free_seckey_enc( sig ); - else - *ret_sig = sig; - return rc; -} - - - -/**************** - * Create a new signature packet based on an existing one. - * Only user ID signatures are supported for now. - * TODO: Merge this with make_keysig_packet. - */ -int -update_keysig_packet( PKT_signature **ret_sig, - PKT_signature *orig_sig, - PKT_public_key *pk, - PKT_user_id *uid, - PKT_public_key *subpk, - PKT_secret_key *sk, - int (*mksubpkt)(PKT_signature *, void *), - void *opaque - ) -{ - PKT_signature *sig; - int rc=0; - MD_HANDLE md; - - if ((!orig_sig || !pk || !sk) - || (orig_sig->sig_class >= 0x10 && orig_sig->sig_class <= 0x13 && !uid) - || (orig_sig->sig_class == 0x18 && !subpk)) - return GPG_ERR_GENERAL; - - gcry_md_open (&md, orig_sig->digest_algo, 0); - - /* hash the public key certificate and the user id */ - hash_public_key( md, pk ); - - if( orig_sig->sig_class == 0x18 ) - hash_public_key( md, subpk ); - else - hash_uid (md, orig_sig->version, uid); - - /* create a new signature packet */ - sig = copy_signature (NULL, orig_sig); - - /* We need to create a new timestamp so that new sig expiration - calculations are done correctly... */ - sig->timestamp=make_timestamp(); - - /* ... but we won't make a timestamp earlier than the existing - one. */ - while(sig->timestamp<=orig_sig->timestamp) - { - sleep(1); - sig->timestamp=make_timestamp(); - } - - /* Note that already expired sigs will remain expired (with a - duration of 0) since build-packet.c:build_sig_subpkt_from_sig - detects this case. */ - - if( sig->version >= 4 ) - { - /* Put the updated timestamp into the sig. Note that this - will automagically lower any sig expiration dates to - correctly correspond to the differences in the timestamps - (i.e. the duration will shrink). */ - build_sig_subpkt_from_sig( sig ); - - if (mksubpkt) - rc = (*mksubpkt)(sig, opaque); - } - - if (!rc) { - hash_sigversion_to_magic (md, sig); - gcry_md_final (md); - - rc = complete_sig( sig, sk, md ); - } - - gcry_md_close (md); - if( rc ) - free_seckey_enc (sig); - else - *ret_sig = sig; - return rc; -} diff --git a/g10/signal.c b/g10/signal.c deleted file mode 100644 index 9f50fbe3a..000000000 --- a/g10/signal.c +++ /dev/null @@ -1,226 +0,0 @@ -/* signal.c - signal handling - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "errors.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "ttyio.h" - - -static volatile int caught_fatal_sig = 0; -static volatile int caught_sigusr1 = 0; - -static void -init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign ) -{ -#ifndef HAVE_DOSISH_SYSTEM -#if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION) - struct sigaction oact, nact; - - if (check_ign) { - /* we don't want to change an IGN handler */ - sigaction (sig, NULL, &oact ); - if (oact.sa_handler == SIG_IGN ) - return; - } - - nact.sa_handler = handler; - sigemptyset (&nact.sa_mask); - nact.sa_flags = 0; - sigaction ( sig, &nact, NULL); -#else - RETSIGTYPE (*ohandler)(int); - - ohandler = signal (sig, handler); - if (check_ign && ohandler == SIG_IGN) { - /* Change it back if it was already set to IGN */ - signal (sig, SIG_IGN); - } -#endif -#endif /*!HAVE_DOSISH_SYSTEM*/ -} - -static const char * -get_signal_name( int signum ) -{ -#if defined(SYS_SIGLIST_DECLARED) && defined(NSIG) - return (signum >= 0 && signum < NSIG) ? sys_siglist[signum] : "?"; -#else - return "some signal"; -#endif -} - - -static RETSIGTYPE -got_fatal_signal( int sig ) -{ - const char *s; - - if( caught_fatal_sig ) - raise( sig ); - caught_fatal_sig = 1; - - gcry_control (GCRYCTL_TERM_SECMEM ); - /* better don't transtale these messages */ - write(2, "\n", 1 ); - s = "?" /* FIXME: log_get_name()*/; if( s ) write(2, s, strlen(s) ); - write(2, ": ", 2 ); - s = get_signal_name(sig); write(2, s, strlen(s) ); - write(2, " caught ... exiting\n", 20 ); - - /* reset action to default action and raise signal again */ - init_one_signal (sig, SIG_DFL, 0); - dotlock_remove_lockfiles (); -#ifdef __riscos__ - riscos_close_fds (); -#endif /* __riscos__ */ - raise( sig ); -} - - -static RETSIGTYPE -got_usr_signal( int sig ) -{ - caught_sigusr1 = 1; -} - - -void -init_signals() -{ -#ifndef HAVE_DOSISH_SYSTEM - init_one_signal (SIGINT, got_fatal_signal, 1 ); - init_one_signal (SIGHUP, got_fatal_signal, 1 ); - init_one_signal (SIGTERM, got_fatal_signal, 1 ); - init_one_signal (SIGQUIT, got_fatal_signal, 1 ); - init_one_signal (SIGSEGV, got_fatal_signal, 1 ); - init_one_signal (SIGUSR1, got_usr_signal, 0 ); - init_one_signal (SIGPIPE, SIG_IGN, 0 ); -#endif -} - - -void -pause_on_sigusr( int which ) -{ -#ifndef HAVE_DOSISH_SYSTEM -#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T) - sigset_t mask, oldmask; - - assert( which == 1 ); - sigemptyset( &mask ); - sigaddset( &mask, SIGUSR1 ); - - sigprocmask( SIG_BLOCK, &mask, &oldmask ); - while( !caught_sigusr1 ) - sigsuspend( &oldmask ); - caught_sigusr1 = 0; - sigprocmask( SIG_UNBLOCK, &mask, NULL ); -#else - assert (which == 1); - sighold (SIGUSR1); - while (!caught_sigusr1) - sigpause(SIGUSR1); - caught_sigusr1 = 0; - sigrelse(SIGUSR1); -#endif /*!HAVE_SIGPROCMASK && HAVE_SISET_T*/ -#endif -} - - -static void -do_block( int block ) -{ -#ifndef HAVE_DOSISH_SYSTEM - static int is_blocked; -#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T) - static sigset_t oldmask; - - if( block ) { - sigset_t newmask; - - if( is_blocked ) - log_bug("signals are already blocked\n"); - sigfillset( &newmask ); - sigprocmask( SIG_BLOCK, &newmask, &oldmask ); - is_blocked = 1; - } - else { - if( !is_blocked ) - log_bug("signals are not blocked\n"); - sigprocmask( SIG_SETMASK, &oldmask, NULL ); - is_blocked = 0; - } -#else /*!HAVE_SIGPROCMASK*/ - -#if defined(NSIG) -# define SIGSMAX (NSIG) -#elif defined(MAXSIG) -# define SIGSMAX (MAXSIG+1) -#else -# error "define SIGSMAX to the number of signals on your platform plus one" -#endif - - static void (*disposition[SIGSMAX])(int); - int sig; - - if( block ) { - if( is_blocked ) - log_bug("signals are already blocked\n"); - for (sig=1; sig < SIGSMAX; sig++) { - disposition[sig] = sigset (sig, SIG_HOLD); - } - is_blocked = 1; - } - else { - if( !is_blocked ) - log_bug("signals are not blocked\n"); - for (sig=1; sig < SIGSMAX; sig++) { - sigset (sig, disposition[sig]); - } - is_blocked = 0; - } -#endif /*!HAVE_SIGPROCMASK*/ -#endif /*HAVE_DOSISH_SYSTEM*/ -} - - -void -block_all_signals() -{ - do_block(1); -} - -void -unblock_all_signals() -{ - do_block(0); -} diff --git a/g10/skclist.c b/g10/skclist.c deleted file mode 100644 index 67d9eb2f9..000000000 --- a/g10/skclist.c +++ /dev/null @@ -1,176 +0,0 @@ -/* skclist.c - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "i18n.h" -#include "cipher.h" - - -void -release_sk_list( SK_LIST sk_list ) -{ - SK_LIST sk_rover; - - for( ; sk_list; sk_list = sk_rover ) { - sk_rover = sk_list->next; - free_secret_key( sk_list->sk ); - xfree ( sk_list ); - } -} - - - -static int -key_present_in_sk_list(SK_LIST sk_list, PKT_secret_key *sk) -{ - for (; sk_list; sk_list = sk_list->next) { - if ( !cmp_secret_keys(sk_list->sk, sk) ) - return 0; - } - return -1; -} - -static int -is_duplicated_entry (STRLIST list, STRLIST item) -{ - for(; list && list != item; list = list->next) { - if ( !strcmp (list->d, item->d) ) - return 1; - } - return 0; -} - - -int -build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, - int unlock, unsigned int use ) -{ - SK_LIST sk_list = NULL; - int rc; - - if( !locusr ) { /* use the default one */ - PKT_secret_key *sk; - - sk = xcalloc (1, sizeof *sk ); - sk->req_usage = use; - if( (rc = get_seckey_byname( sk, NULL, unlock )) ) { - free_secret_key( sk ); sk = NULL; - log_error("no default secret key: %s\n", gpg_strerror (rc) ); - } - else if( !(rc=openpgp_pk_test_algo (sk->pubkey_algo, use)) ) { - SK_LIST r; - - if( sk->version == 4 && (use & PUBKEY_USAGE_SIG) - && sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { - log_info("this is a PGP generated " - "ElGamal key which is NOT secure for signatures!\n"); - free_secret_key( sk ); sk = NULL; - } - else { - r = xmalloc ( sizeof *r ); - r->sk = sk; sk = NULL; - r->next = sk_list; - r->mark = 0; - sk_list = r; - } - } - else { - free_secret_key( sk ); sk = NULL; - log_error("invalid default secret key: %s\n", gpg_strerror (rc) ); - } - } - else { - STRLIST locusr_orig = locusr; - for(; locusr; locusr = locusr->next ) { - PKT_secret_key *sk; - - rc = 0; - /* Do an early check agains duplicated entries. However this - * won't catch all duplicates because the user IDs may be - * specified in different ways. - */ - if ( is_duplicated_entry ( locusr_orig, locusr ) ) { - log_error(_("skipped `%s': duplicated\n"), locusr->d ); - continue; - } - sk = xcalloc (1, sizeof *sk ); - sk->req_usage = use; - if( (rc = get_seckey_byname( sk, locusr->d, 0 )) ) { - free_secret_key( sk ); sk = NULL; - log_error(_("skipped `%s': %s\n"), locusr->d, gpg_strerror (rc) ); - } - else if ( key_present_in_sk_list(sk_list, sk) == 0) { - free_secret_key(sk); sk = NULL; - log_info(_("skipped: secret key already present\n")); - } - else if ( unlock && (rc = check_secret_key( sk, 0 )) ) { - free_secret_key( sk ); sk = NULL; - log_error(_("skipped `%s': %s\n"), locusr->d, gpg_strerror (rc) ); - } - else if( !(rc=openpgp_pk_test_algo (sk->pubkey_algo, use)) ) { - SK_LIST r; - - if( sk->version == 4 && (use & PUBKEY_USAGE_SIG) - && sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { - log_info(_("skipped `%s': this is a PGP generated " - "ElGamal key which is not secure for signatures!\n"), - locusr->d ); - free_secret_key( sk ); sk = NULL; - } - else { - r = xmalloc ( sizeof *r ); - r->sk = sk; sk = NULL; - r->next = sk_list; - r->mark = 0; - sk_list = r; - } - } - else { - free_secret_key( sk ); sk = NULL; - log_error("skipped `%s': %s\n", locusr->d, gpg_strerror (rc) ); - } - } - } - - - if( !rc && !sk_list ) { - log_error("no valid signators\n"); - rc = GPG_ERR_NO_USER_ID; - } - - if( rc ) - release_sk_list( sk_list ); - else - *ret_sk_list = sk_list; - return rc; -} - diff --git a/g10/status.c b/g10/status.c deleted file mode 100644 index aa55020be..000000000 --- a/g10/status.c +++ /dev/null @@ -1,472 +0,0 @@ -/* status.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> - -#include "gpg.h" -#include "util.h" -#include "status.h" -#include "ttyio.h" -#include "options.h" -#include "main.h" -#include "i18n.h" -#include "cipher.h" /* for progress functions */ - -#define CONTROL_D ('D' - 'A' + 1) - - - -static FILE *statusfp; - - -static void -progress_cb (void *ctx, const char *what, int printchar, int current, int total) -{ - char buf[150]; - - if (printchar == '\n') - printchar = 'X'; - - sprintf (buf, "%.20s %c %d %d", what, printchar, current, total); - write_status_text (STATUS_PROGRESS, buf); -} - -static const char * -get_status_string ( int no ) -{ - const char *s; - - switch( no ) { - case STATUS_ENTER : s = "ENTER"; break; - case STATUS_LEAVE : s = "LEAVE"; break; - case STATUS_ABORT : s = "ABORT"; break; - case STATUS_GOODSIG: s = "GOODSIG"; break; - case STATUS_KEYEXPIRED: s = "KEYEXPIRED"; break; - case STATUS_KEYREVOKED: s = "KEYREVOKED"; break; - case STATUS_BADSIG : s = "BADSIG"; break; - case STATUS_ERRSIG : s = "ERRSIG"; break; - case STATUS_BADARMOR : s = "BADARMOR"; break; - case STATUS_RSA_OR_IDEA : s= "RSA_OR_IDEA"; break; - case STATUS_TRUST_UNDEFINED: s = "TRUST_UNDEFINED"; break; - case STATUS_TRUST_NEVER : s = "TRUST_NEVER"; break; - case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL"; break; - case STATUS_TRUST_FULLY : s = "TRUST_FULLY"; break; - case STATUS_TRUST_ULTIMATE : s = "TRUST_ULTIMATE"; break; - case STATUS_GET_BOOL : s = "GET_BOOL"; break; - case STATUS_GET_LINE : s = "GET_LINE"; break; - case STATUS_GET_HIDDEN : s = "GET_HIDDEN"; break; - case STATUS_GOT_IT : s = "GOT_IT"; break; - case STATUS_SHM_INFO : s = "SHM_INFO"; break; - case STATUS_SHM_GET : s = "SHM_GET"; break; - case STATUS_SHM_GET_BOOL : s = "SHM_GET_BOOL"; break; - case STATUS_SHM_GET_HIDDEN : s = "SHM_GET_HIDDEN"; break; - case STATUS_NEED_PASSPHRASE: s = "NEED_PASSPHRASE"; break; - case STATUS_VALIDSIG : s = "VALIDSIG"; break; - case STATUS_SIG_ID : s = "SIG_ID"; break; - case STATUS_ENC_TO : s = "ENC_TO"; break; - case STATUS_NODATA : s = "NODATA"; break; - case STATUS_BAD_PASSPHRASE : s = "BAD_PASSPHRASE"; break; - case STATUS_NO_PUBKEY : s = "NO_PUBKEY"; break; - case STATUS_NO_SECKEY : s = "NO_SECKEY"; break; - case STATUS_NEED_PASSPHRASE_SYM: s = "NEED_PASSPHRASE_SYM"; break; - case STATUS_DECRYPTION_FAILED: s = "DECRYPTION_FAILED"; break; - case STATUS_DECRYPTION_OKAY: s = "DECRYPTION_OKAY"; break; - case STATUS_MISSING_PASSPHRASE: s = "MISSING_PASSPHRASE"; break; - case STATUS_GOOD_PASSPHRASE : s = "GOOD_PASSPHRASE"; break; - case STATUS_GOODMDC : s = "GOODMDC"; break; - case STATUS_BADMDC : s = "BADMDC"; break; - case STATUS_ERRMDC : s = "ERRMDC"; break; - case STATUS_IMPORTED : s = "IMPORTED"; break; - case STATUS_IMPORT_OK : s = "IMPORT_OK"; break; - case STATUS_IMPORT_CHECK : s = "IMPORT_CHECK"; break; - case STATUS_IMPORT_RES : s = "IMPORT_RES"; break; - case STATUS_FILE_START : s = "FILE_START"; break; - case STATUS_FILE_DONE : s = "FILE_DONE"; break; - case STATUS_FILE_ERROR : s = "FILE_ERROR"; break; - case STATUS_BEGIN_DECRYPTION:s = "BEGIN_DECRYPTION"; break; - case STATUS_END_DECRYPTION : s = "END_DECRYPTION"; break; - case STATUS_BEGIN_ENCRYPTION:s = "BEGIN_ENCRYPTION"; break; - case STATUS_END_ENCRYPTION : s = "END_ENCRYPTION"; break; - case STATUS_DELETE_PROBLEM : s = "DELETE_PROBLEM"; break; - case STATUS_PROGRESS : s = "PROGRESS"; break; - case STATUS_SIG_CREATED : s = "SIG_CREATED"; break; - case STATUS_SESSION_KEY : s = "SESSION_KEY"; break; - case STATUS_NOTATION_NAME : s = "NOTATION_NAME" ; break; - case STATUS_NOTATION_DATA : s = "NOTATION_DATA" ; break; - case STATUS_POLICY_URL : s = "POLICY_URL" ; break; - case STATUS_BEGIN_STREAM : s = "BEGIN_STREAM"; break; - case STATUS_END_STREAM : s = "END_STREAM"; break; - case STATUS_KEY_CREATED : s = "KEY_CREATED"; break; - case STATUS_USERID_HINT : s = "USERID_HINT"; break; - case STATUS_UNEXPECTED : s = "UNEXPECTED"; break; - case STATUS_INV_RECP : s = "INV_RECP"; break; - case STATUS_NO_RECP : s = "NO_RECP"; break; - case STATUS_ALREADY_SIGNED : s = "ALREADY_SIGNED"; break; - case STATUS_SIGEXPIRED : s = "SIGEXPIRED deprecated-use-keyexpired-instead"; break; - case STATUS_EXPSIG : s = "EXPSIG"; break; - case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break; - case STATUS_REVKEYSIG : s = "REVKEYSIG"; break; - case STATUS_ATTRIBUTE : s = "ATTRIBUTE"; break; - default: s = "?"; break; - } - return s; -} - -void -set_status_fd ( int fd ) -{ - static int last_fd = -1; - - if ( fd != -1 && last_fd == fd ) - return; - - if ( statusfp && statusfp != stdout && statusfp != stderr ) - fclose (statusfp); - statusfp = NULL; - if ( fd == -1 ) - return; - - if( fd == 1 ) - statusfp = stdout; - else if( fd == 2 ) - statusfp = stderr; - else - statusfp = fdopen( fd, "w" ); - if( !statusfp ) { - log_fatal("can't open fd %d for status output: %s\n", - fd, strerror(errno)); - } - last_fd = fd; - gcry_set_progress_handler (progress_cb, NULL); -} - -int -is_status_enabled() -{ - return !!statusfp; -} - -void -write_status ( int no ) -{ - write_status_text( no, NULL ); -} - -void -write_status_text ( int no, const char *text) -{ - if( !statusfp ) - return; /* not enabled */ - - fputs ( "[GNUPG:] ", statusfp ); - fputs ( get_status_string (no), statusfp ); - if( text ) { - putc ( ' ', statusfp ); - for (; *text; text++) { - if (*text == '\n') - fputs ( "\\n", statusfp ); - else if (*text == '\r') - fputs ( "\\r", statusfp ); - else - putc ( *(const byte *)text, statusfp ); - } - } - putc ('\n',statusfp); - fflush (statusfp); -} - - -/* - * Write a status line with a buffer using %XX escapes. If WRAP is > - * 0 wrap the line after this length. If STRING is not NULL it will - * be prepended to the buffer, no escaping is done for string. - * A wrap of -1 forces spaces not to be encoded as %20. - */ -void -write_status_text_and_buffer ( int no, const char *string, - const char *buffer, size_t len, int wrap ) -{ - const char *s, *text; - int esc, first; - int lower_limit = ' '; - size_t n, count, dowrap; - - if( !statusfp ) - return; /* not enabled */ - - if (wrap == -1) { - lower_limit--; - wrap = 0; - } - - text = get_status_string (no); - count = dowrap = first = 1; - do { - if (dowrap) { - fprintf (statusfp, "[GNUPG:] %s ", text ); - count = dowrap = 0; - if (first && string) { - fputs (string, statusfp); - count += strlen (string); - } - first = 0; - } - for (esc=0, s=buffer, n=len; n && !esc; s++, n-- ) { - if ( *s == '%' || *(const byte*)s <= lower_limit - || *(const byte*)s == 127 ) - esc = 1; - if ( wrap && ++count > wrap ) { - dowrap=1; - break; - } - } - if (esc) { - s--; n++; - } - if (s != buffer) - fwrite (buffer, s-buffer, 1, statusfp ); - if ( esc ) { - fprintf (statusfp, "%%%02X", *(const byte*)s ); - s++; n--; - } - buffer = s; - len = n; - if ( dowrap && len ) - putc ( '\n', statusfp ); - } while ( len ); - - putc ('\n',statusfp); - fflush (statusfp); -} - -void -write_status_buffer ( int no, const char *buffer, size_t len, int wrap ) -{ - write_status_text_and_buffer (no, NULL, buffer, len, wrap); -} - - - -static int -myread(int fd, void *buf, size_t count) -{ - int rc; - do { - rc = read( fd, buf, count ); - } while ( rc == -1 && errno == EINTR ); - if ( !rc && count ) { - static int eof_emmited=0; - if ( eof_emmited < 3 ) { - *(char*)buf = CONTROL_D; - rc = 1; - eof_emmited++; - } - else { /* Ctrl-D not caught - do something reasonable */ -#ifdef HAVE_DOSISH_SYSTEM - raise (SIGINT); /* nothing to hangup under DOS */ -#else - raise (SIGHUP); /* no more input data */ -#endif - } - } - return rc; -} - - - -/**************** - * Request a string from the client over the command-fd - * If bool, returns static string on true (do not free) or NULL for false - */ -static char * -do_get_from_fd( const char *keyword, int hidden, int bool ) -{ - int i, len; - char *string; - - write_status_text( bool? STATUS_GET_BOOL : - hidden? STATUS_GET_HIDDEN : STATUS_GET_LINE, keyword ); - - for( string = NULL, i = len = 200; ; i++ ) { - if( i >= len-1 ) { - char *save = string; - len += 100; - string = hidden? xmalloc_secure ( len ) : xmalloc ( len ); - if( save ) - memcpy(string, save, i ); - else - i=0; - } - /* Hmmm: why not use our read_line function here */ - if( myread( opt.command_fd, string+i, 1) != 1 || string[i] == '\n' ) - break; - else if ( string[i] == CONTROL_D ) { - /* found ETX - cancel the line and return a sole ETX */ - string[0] = CONTROL_D; - i=1; - break; - } - } - string[i] = 0; - - write_status( STATUS_GOT_IT ); - - if( bool ) /* Fixme: is this correct??? */ - return (string[0] == 'Y' || string[0] == 'y') ? "" : NULL; - - return string; -} - - - -int -cpr_enabled() -{ - if( opt.command_fd != -1 ) - return 1; - return 0; -} - -char * -cpr_get_no_help( const char *keyword, const char *prompt ) -{ - char *p; - - if( opt.command_fd != -1 ) - return do_get_from_fd ( keyword, 0, 0 ); - for(;;) { - p = tty_get( prompt ); - return p; - } -} - -char * -cpr_get( const char *keyword, const char *prompt ) -{ - char *p; - - if( opt.command_fd != -1 ) - return do_get_from_fd ( keyword, 0, 0 ); - for(;;) { - p = tty_get( prompt ); - if( *p=='?' && !p[1] && !(keyword && !*keyword)) { - xfree (p); - display_online_help( keyword ); - } - else - return p; - } -} - - -char * -cpr_get_utf8( const char *keyword, const char *prompt ) -{ - char *p; - p = cpr_get( keyword, prompt ); - if( p ) { - char *utf8 = native_to_utf8( p ); - xfree ( p ); - p = utf8; - } - return p; -} - -char * -cpr_get_hidden( const char *keyword, const char *prompt ) -{ - char *p; - - if( opt.command_fd != -1 ) - return do_get_from_fd ( keyword, 1, 0 ); - for(;;) { - p = tty_get_hidden( prompt ); - if( *p == '?' && !p[1] ) { - xfree (p); - display_online_help( keyword ); - } - else - return p; - } -} - -void -cpr_kill_prompt(void) -{ - if( opt.command_fd != -1 ) - return; - tty_kill_prompt(); - return; -} - -int -cpr_get_answer_is_yes( const char *keyword, const char *prompt ) -{ - int yes; - char *p; - - if( opt.command_fd != -1 ) - return !!do_get_from_fd ( keyword, 0, 1 ); - for(;;) { - p = tty_get( prompt ); - trim_spaces(p); /* it is okay to do this here */ - if( *p == '?' && !p[1] ) { - xfree (p); - display_online_help( keyword ); - } - else { - tty_kill_prompt(); - yes = answer_is_yes(p); - xfree (p); - return yes; - } - } -} - -int -cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt ) -{ - int yes; - char *p; - - if( opt.command_fd != -1 ) - return !!do_get_from_fd ( keyword, 0, 1 ); - for(;;) { - p = tty_get( prompt ); - trim_spaces(p); /* it is okay to do this here */ - if( *p == '?' && !p[1] ) { - xfree (p); - display_online_help( keyword ); - } - else { - tty_kill_prompt(); - yes = answer_is_yes_no_quit(p); - xfree (p); - return yes; - } - } -} diff --git a/g10/status.h b/g10/status.h deleted file mode 100644 index d8de81080..000000000 --- a/g10/status.h +++ /dev/null @@ -1,124 +0,0 @@ -/* status.h - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_STATUS_H -#define G10_STATUS_H - - -#define STATUS_ENTER 1 -#define STATUS_LEAVE 2 -#define STATUS_ABORT 3 - -#define STATUS_GOODSIG 4 -#define STATUS_BADSIG 5 -#define STATUS_ERRSIG 6 - - -#define STATUS_BADARMOR 7 - -#define STATUS_RSA_OR_IDEA 8 -#define STATUS_KEYEXPIRED 9 -#define STATUS_KEYREVOKED 10 - -#define STATUS_TRUST_UNDEFINED 11 -#define STATUS_TRUST_NEVER 12 -#define STATUS_TRUST_MARGINAL 13 -#define STATUS_TRUST_FULLY 14 -#define STATUS_TRUST_ULTIMATE 15 - -#define STATUS_SHM_INFO 16 -#define STATUS_SHM_GET 17 -#define STATUS_SHM_GET_BOOL 18 -#define STATUS_SHM_GET_HIDDEN 19 - -#define STATUS_NEED_PASSPHRASE 20 -#define STATUS_VALIDSIG 21 -#define STATUS_SIG_ID 22 -#define STATUS_ENC_TO 23 -#define STATUS_NODATA 24 -#define STATUS_BAD_PASSPHRASE 25 -#define STATUS_NO_PUBKEY 26 -#define STATUS_NO_SECKEY 27 -#define STATUS_NEED_PASSPHRASE_SYM 28 -#define STATUS_DECRYPTION_FAILED 29 -#define STATUS_DECRYPTION_OKAY 30 -#define STATUS_MISSING_PASSPHRASE 31 -#define STATUS_GOOD_PASSPHRASE 32 -#define STATUS_GOODMDC 33 -#define STATUS_BADMDC 34 -#define STATUS_ERRMDC 35 -#define STATUS_IMPORTED 36 -#define STATUS_IMPORT_RES 37 -#define STATUS_FILE_START 38 -#define STATUS_FILE_DONE 39 -#define STATUS_FILE_ERROR 40 - -#define STATUS_BEGIN_DECRYPTION 41 -#define STATUS_END_DECRYPTION 42 -#define STATUS_BEGIN_ENCRYPTION 43 -#define STATUS_END_ENCRYPTION 44 - -#define STATUS_DELETE_PROBLEM 45 -#define STATUS_GET_BOOL 46 -#define STATUS_GET_LINE 47 -#define STATUS_GET_HIDDEN 48 -#define STATUS_GOT_IT 49 -#define STATUS_PROGRESS 50 -#define STATUS_SIG_CREATED 51 -#define STATUS_SESSION_KEY 52 -#define STATUS_NOTATION_NAME 53 -#define STATUS_NOTATION_DATA 54 -#define STATUS_POLICY_URL 55 -#define STATUS_BEGIN_STREAM 56 -#define STATUS_END_STREAM 57 -#define STATUS_KEY_CREATED 58 -#define STATUS_USERID_HINT 59 -#define STATUS_UNEXPECTED 60 -#define STATUS_INV_RECP 61 -#define STATUS_NO_RECP 62 -#define STATUS_ALREADY_SIGNED 63 -#define STATUS_SIGEXPIRED 64 -#define STATUS_EXPSIG 65 -#define STATUS_EXPKEYSIG 66 -#define STATUS_ATTRIBUTE 67 -#define STATUS_IMPORT_OK 68 -#define STATUS_IMPORT_CHECK 69 -#define STATUS_REVKEYSIG 70 - -/*-- status.c --*/ -void set_status_fd ( int fd ); -int is_status_enabled ( void ); -void write_status ( int no ); -void write_status_text ( int no, const char *text ); -void write_status_buffer ( int no, - const char *buffer, size_t len, int wrap ); -void write_status_text_and_buffer ( int no, const char *text, - const char *buffer, size_t len, int wrap ); - -int cpr_enabled(void); -char *cpr_get( const char *keyword, const char *prompt ); -char *cpr_get_no_help( const char *keyword, const char *prompt ); -char *cpr_get_utf8( const char *keyword, const char *prompt ); -char *cpr_get_hidden( const char *keyword, const char *prompt ); -void cpr_kill_prompt(void); -int cpr_get_answer_is_yes( const char *keyword, const char *prompt ); -int cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt ); - - -#endif /*G10_STATUS_H*/ diff --git a/g10/tdbdump.c b/g10/tdbdump.c deleted file mode 100644 index 5eb482959..000000000 --- a/g10/tdbdump.c +++ /dev/null @@ -1,223 +0,0 @@ -/* tdbdump.c - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <ctype.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "trustdb.h" -#include "options.h" -#include "packet.h" -#include "main.h" -#include "i18n.h" -#include "tdbio.h" - - -#define HEXTOBIN(x) ( (x) >= '0' && (x) <= '9' ? ((x)-'0') : \ - (x) >= 'A' && (x) <= 'F' ? ((x)-'A'+10) : ((x)-'a'+10)) - - -/**************** - * Wirte a record but die on error - */ -static void -write_record( TRUSTREC *rec ) -{ - int rc = tdbio_write_record( rec ); - if( !rc ) - return; - log_error(_("trust record %lu, type %d: write failed: %s\n"), - rec->recnum, rec->rectype, gpg_strerror (rc) ); - tdbio_invalid(); -} - - -/**************** - * Dump the entire trustdb or only the entries of one key. - */ -void -list_trustdb( const char *username ) -{ - TRUSTREC rec; - - init_trustdb(); - /* for now we ignore the user ID */ - if (1) { - ulong recnum; - int i; - - printf("TrustDB: %s\n", tdbio_get_dbname() ); - for(i=9+strlen(tdbio_get_dbname()); i > 0; i-- ) - putchar('-'); - putchar('\n'); - for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) - tdbio_dump_record( &rec, stdout ); - } -} - - - - - -/**************** - * Print a list of all defined owner trust value. - */ -void -export_ownertrust() -{ - TRUSTREC rec; - ulong recnum; - int i; - byte *p; - - init_trustdb(); - printf(_("# List of assigned trustvalues, created %s\n" - "# (Use \"gpg --import-ownertrust\" to restore them)\n"), - asctimestamp( make_timestamp() ) ); - for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) { - if( rec.rectype == RECTYPE_TRUST ) { - if( !rec.r.trust.ownertrust ) - continue; - p = rec.r.trust.fingerprint; - for(i=0; i < 20; i++, p++ ) - printf("%02X", *p ); - printf(":%u:\n", (unsigned int)rec.r.trust.ownertrust ); - } - } -} - - -void -import_ownertrust( const char *fname ) -{ - FILE *fp; - int is_stdin=0; - char line[256]; - char *p; - size_t n, fprlen; - unsigned int otrust; - byte fpr[20]; - int any = 0; - int rc; - - init_trustdb(); - if( !fname || (*fname == '-' && !fname[1]) ) { - fp = stdin; - fname = "[stdin]"; - is_stdin = 1; - } - else if( !(fp = fopen( fname, "r" )) ) { - log_error ( _("can't open `%s': %s\n"), fname, strerror(errno) ); - return; - } - - while( fgets( line, DIM(line)-1, fp ) ) { - TRUSTREC rec; - - if( !*line || *line == '#' ) - continue; - n = strlen(line); - if( line[n-1] != '\n' ) { - log_error (_("\b%s: line too long\n"), fname ); - /* ... or last line does not have a LF */ - break; /* can't continue */ - } - for(p = line; *p && *p != ':' ; p++ ) - if( !hexdigitp (p) ) - break; - if( *p != ':' ) { - log_error (_("\b%s: error: missing colon\n"), fname ); - continue; - } - fprlen = p - line; - if( fprlen != 32 && fprlen != 40 ) { - log_error (_("\b%s: error: invalid fingerprint\n"), fname ); - continue; - } - if( sscanf(p, ":%u:", &otrust ) != 1 ) { - log_error (_("\b%s: error: no ownertrust value\n"), fname ); - continue; - } - if( !otrust ) - continue; /* no otrust defined - no need to update or insert */ - /* convert the ascii fingerprint to binary */ - for(p=line, fprlen=0; fprlen < 20 && *p != ':'; p += 2 ) - fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]); - while (fprlen < 20) - fpr[fprlen++] = 0; - - rc = tdbio_search_trust_byfpr (fpr, &rec); - if( !rc ) { /* found: update */ - if (rec.r.trust.ownertrust != otrust) - { - if( rec.r.trust.ownertrust ) - log_info("changing ownertrust from %u to %u\n", - rec.r.trust.ownertrust, otrust ); - else - log_info("setting ownertrust to %u\n", otrust ); - rec.r.trust.ownertrust = otrust; - write_record (&rec ); - any = 1; - } - } - else if( rc == -1 ) { /* not found: insert */ - log_info("inserting ownertrust of %u\n", otrust ); - memset (&rec, 0, sizeof rec); - rec.recnum = tdbio_new_recnum (); - rec.rectype = RECTYPE_TRUST; - memcpy (rec.r.trust.fingerprint, fpr, 20); - rec.r.trust.ownertrust = otrust; - write_record (&rec ); - any = 1; - } - else /* error */ - log_error (_("\b%s: error finding trust record: %s\n"), - fname, gpg_strerror (rc)); - } - if( ferror(fp) ) - log_error (_("\b%s: read error: %s\n"), fname, strerror(errno) ); - if( !is_stdin ) - fclose(fp); - - if (any) - { - revalidation_mark (); - rc = tdbio_sync (); - if (rc) - log_error (_("trustdb: sync failed: %s\n"), gpg_strerror (rc) ); - } - -} - - diff --git a/g10/tdbio.c b/g10/tdbio.c deleted file mode 100644 index 75687a3b0..000000000 --- a/g10/tdbio.c +++ /dev/null @@ -1,1636 +0,0 @@ -/* tdbio.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "options.h" -#include "main.h" -#include "i18n.h" -#include "trustdb.h" -#include "tdbio.h" - -#if defined(HAVE_DOSISH_SYSTEM) -#define ftruncate chsize -#endif - -#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__) -#define MY_O_BINARY O_BINARY -#else -#define MY_O_BINARY 0 -#endif - - -/**************** - * Yes, this is a very simple implementation. We should really - * use a page aligned buffer and read complete pages. - * To implement a simple trannsaction system, this is sufficient. - */ -typedef struct cache_ctrl_struct *CACHE_CTRL; -struct cache_ctrl_struct { - CACHE_CTRL next; - struct { - unsigned used:1; - unsigned dirty:1; - } flags; - ulong recno; - char data[TRUST_RECORD_LEN]; -}; - -#define MAX_CACHE_ENTRIES_SOFT 200 /* may be increased while in a */ -#define MAX_CACHE_ENTRIES_HARD 10000 /* transaction to this one */ -static CACHE_CTRL cache_list; -static int cache_entries; -static int cache_is_dirty; - -/* a type used to pass infomation to cmp_krec_fpr */ -struct cmp_krec_fpr_struct { - int pubkey_algo; - const char *fpr; - int fprlen; -}; - -/* a type used to pass infomation to cmp_[s]dir */ -struct cmp_xdir_struct { - int pubkey_algo; - u32 keyid[2]; -}; - - -static char *db_name; -static DOTLOCK lockhandle; -static int is_locked; -static int db_fd = -1; -static int in_transaction; - -static void open_db(void); -static void migrate_from_v2 (void); - - - -/************************************* - ************* record cache ********** - *************************************/ - -/**************** - * Get the data from therecord cache and return a - * pointer into that cache. Caller should copy - * the return data. NULL is returned on a cache miss. - */ -static const char * -get_record_from_cache( ulong recno ) -{ - CACHE_CTRL r; - - for( r = cache_list; r; r = r->next ) { - if( r->flags.used && r->recno == recno ) - return r->data; - } - return NULL; -} - - -static int -write_cache_item( CACHE_CTRL r ) -{ - int n; - gpg_error_t rc; - - if( lseek( db_fd, r->recno * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) { - rc = gpg_error_from_errno (errno); - log_error(_("trustdb rec %lu: lseek failed: %s\n"), - r->recno, strerror(errno) ); - return rc; - } - n = write( db_fd, r->data, TRUST_RECORD_LEN); - if( n != TRUST_RECORD_LEN ) { - rc = gpg_error_from_errno (errno); - log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"), - r->recno, n, strerror(errno) ); - return rc; - } - r->flags.dirty = 0; - return 0; -} - -/**************** - * Put data into the cache. This function may flush the - * some cache entries if there is not enough space available. - */ -int -put_record_into_cache( ulong recno, const char *data ) -{ - CACHE_CTRL r, unused; - int dirty_count = 0; - int clean_count = 0; - - /* see whether we already cached this one */ - for( unused = NULL, r = cache_list; r; r = r->next ) { - if( !r->flags.used ) { - if( !unused ) - unused = r; - } - else if( r->recno == recno ) { - if( !r->flags.dirty ) { - /* Hmmm: should we use a a copy and compare? */ - if( memcmp(r->data, data, TRUST_RECORD_LEN ) ) { - r->flags.dirty = 1; - cache_is_dirty = 1; - } - } - memcpy( r->data, data, TRUST_RECORD_LEN ); - return 0; - } - if( r->flags.used ) { - if( r->flags.dirty ) - dirty_count++; - else - clean_count++; - } - } - /* not in the cache: add a new entry */ - if( unused ) { /* reuse this entry */ - r = unused; - r->flags.used = 1; - r->recno = recno; - memcpy( r->data, data, TRUST_RECORD_LEN ); - r->flags.dirty = 1; - cache_is_dirty = 1; - cache_entries++; - return 0; - } - /* see whether we reached the limit */ - if( cache_entries < MAX_CACHE_ENTRIES_SOFT ) { /* no */ - r = xmalloc ( sizeof *r ); - r->flags.used = 1; - r->recno = recno; - memcpy( r->data, data, TRUST_RECORD_LEN ); - r->flags.dirty = 1; - r->next = cache_list; - cache_list = r; - cache_is_dirty = 1; - cache_entries++; - return 0; - } - /* cache is full: discard some clean entries */ - if( clean_count ) { - int n = clean_count / 3; /* discard a third of the clean entries */ - if( !n ) - n = 1; - for( unused = NULL, r = cache_list; r; r = r->next ) { - if( r->flags.used && !r->flags.dirty ) { - if( !unused ) - unused = r; - r->flags.used = 0; - cache_entries--; - if( !--n ) - break; - } - } - assert( unused ); - r = unused; - r->flags.used = 1; - r->recno = recno; - memcpy( r->data, data, TRUST_RECORD_LEN ); - r->flags.dirty = 1; - cache_is_dirty = 1; - cache_entries++; - return 0; - } - /* no clean entries: have to flush some dirty entries */ - if( in_transaction ) { - /* but we can't do this while in a transaction - * we increase the cache size instead */ - if( cache_entries < MAX_CACHE_ENTRIES_HARD ) { /* no */ - if( opt.debug && !(cache_entries % 100) ) - log_debug("increasing tdbio cache size\n"); - r = xmalloc ( sizeof *r ); - r->flags.used = 1; - r->recno = recno; - memcpy( r->data, data, TRUST_RECORD_LEN ); - r->flags.dirty = 1; - r->next = cache_list; - cache_list = r; - cache_is_dirty = 1; - cache_entries++; - return 0; - } - log_info(_("trustdb transaction too large\n")); - return GPG_ERR_RESOURCE_LIMIT; - } - if( dirty_count ) { - int n = dirty_count / 5; /* discard some dirty entries */ - if( !n ) - n = 1; - if( !is_locked ) { - if( make_dotlock( lockhandle, -1 ) ) - log_fatal("can't acquire lock - giving up\n"); - else - is_locked = 1; - } - for( unused = NULL, r = cache_list; r; r = r->next ) { - if( r->flags.used && r->flags.dirty ) { - int rc = write_cache_item( r ); - if( rc ) - return rc; - if( !unused ) - unused = r; - r->flags.used = 0; - cache_entries--; - if( !--n ) - break; - } - } - if( !opt.lock_once ) { - if( !release_dotlock( lockhandle ) ) - is_locked = 0; - } - assert( unused ); - r = unused; - r->flags.used = 1; - r->recno = recno; - memcpy( r->data, data, TRUST_RECORD_LEN ); - r->flags.dirty = 1; - cache_is_dirty = 1; - cache_entries++; - return 0; - } - BUG(); -} - - -int -tdbio_is_dirty() -{ - return cache_is_dirty; -} - - -/**************** - * Flush the cache. This cannot be used while in a transaction. - */ -int -tdbio_sync() -{ - CACHE_CTRL r; - int did_lock = 0; - - if( db_fd == -1 ) - open_db(); - if( in_transaction ) - log_bug("tdbio: syncing while in transaction\n"); - - if( !cache_is_dirty ) - return 0; - - if( !is_locked ) { - if( make_dotlock( lockhandle, -1 ) ) - log_fatal("can't acquire lock - giving up\n"); - else - is_locked = 1; - did_lock = 1; - } - for( r = cache_list; r; r = r->next ) { - if( r->flags.used && r->flags.dirty ) { - int rc = write_cache_item( r ); - if( rc ) - return rc; - } - } - cache_is_dirty = 0; - if( did_lock && !opt.lock_once ) { - if( !release_dotlock( lockhandle ) ) - is_locked = 0; - } - - return 0; -} - - -#if 0 -/* The transaction code is disabled in the 1.2.x branch, as it is not - yet used. It will be enabled in 1.3.x. */ - -/**************** - * Simple transactions system: - * Everything between begin_transaction and end/cancel_transaction - * is not immediatly written but at the time of end_transaction. - * - */ -int -tdbio_begin_transaction() -{ - int rc; - - if( in_transaction ) - log_bug("tdbio: nested transactions\n"); - /* flush everything out */ - rc = tdbio_sync(); - if( rc ) - return rc; - in_transaction = 1; - return 0; -} - -int -tdbio_end_transaction() -{ - int rc; - - if( !in_transaction ) - log_bug("tdbio: no active transaction\n"); - if( !is_locked ) { - if( make_dotlock( lockhandle, -1 ) ) - log_fatal("can't acquire lock - giving up\n"); - else - is_locked = 1; - } -#warning block_all_signals is not yet available in ../common/signals.c - /* block_all_signals(); */ - in_transaction = 0; - rc = tdbio_sync(); -/* unblock_all_signals(); */ - if( !opt.lock_once ) { - if( !release_dotlock( lockhandle ) ) - is_locked = 0; - } - return rc; -} - -int -tdbio_cancel_transaction() -{ - CACHE_CTRL r; - - if( !in_transaction ) - log_bug("tdbio: no active transaction\n"); - - /* remove all dirty marked entries, so that the original ones - * are read back the next time */ - if( cache_is_dirty ) { - for( r = cache_list; r; r = r->next ) { - if( r->flags.used && r->flags.dirty ) { - r->flags.used = 0; - cache_entries--; - } - } - cache_is_dirty = 0; - } - - in_transaction = 0; - return 0; -} - -#endif /* transaction code */ - - - -/******************************************************** - **************** cached I/O functions ****************** - ********************************************************/ - -static void -cleanup(void) -{ - if( is_locked ) { - if( !release_dotlock(lockhandle) ) - is_locked = 0; - } -} - -/* Caller must sync */ -int -tdbio_update_version_record (void) -{ - TRUSTREC rec; - int rc; - - memset( &rec, 0, sizeof rec ); - - rc=tdbio_read_record( 0, &rec, RECTYPE_VER); - if(rc==0) - { - rec.r.ver.created = make_timestamp(); - rec.r.ver.marginals = opt.marginals_needed; - rec.r.ver.completes = opt.completes_needed; - rec.r.ver.cert_depth = opt.max_cert_depth; - rec.r.ver.trust_model = opt.trust_model; - rc=tdbio_write_record(&rec); - } - - return rc; -} - -static int -create_version_record (void) -{ - TRUSTREC rec; - int rc; - - memset( &rec, 0, sizeof rec ); - rec.r.ver.version = 3; - rec.r.ver.created = make_timestamp(); - rec.r.ver.marginals = opt.marginals_needed; - rec.r.ver.completes = opt.completes_needed; - rec.r.ver.cert_depth = opt.max_cert_depth; - if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC) - rec.r.ver.trust_model = opt.trust_model; - else - rec.r.ver.trust_model = TM_PGP; - rec.rectype = RECTYPE_VER; - rec.recnum = 0; - rc = tdbio_write_record( &rec ); - if( !rc ) - tdbio_sync(); - return rc; -} - - - -int -tdbio_set_dbname( const char *new_dbname, int create ) -{ - char *fname; - static int initialized = 0; - - if( !initialized ) { - atexit( cleanup ); - initialized = 1; - } - - if(new_dbname==NULL) - fname=make_filename(opt.homedir,"trustdb" EXTSEP_S "gpg", NULL); - else if (*new_dbname != DIRSEP_C ) - { - if (strchr(new_dbname, DIRSEP_C) ) - fname = make_filename (new_dbname, NULL); - else - fname = make_filename (opt.homedir, new_dbname, NULL); - } - else - fname = xstrdup (new_dbname); - - if( access( fname, R_OK ) ) { - if( errno != ENOENT ) { - log_error( _("%s: can't access: %s\n"), fname, strerror(errno) ); - xfree (fname); - return GPG_ERR_TRUSTDB; - } - if( create ) { - FILE *fp; - TRUSTREC rec; - int rc; - char *p = strrchr( fname, DIRSEP_C ); - mode_t oldmask; - - assert(p); - *p = 0; - if( access( fname, F_OK ) ) { - try_make_homedir( fname ); - log_fatal( _("%s: directory does not exist!\n"), fname ); - } - *p = DIRSEP_C; - - xfree (db_name); - db_name = fname; -#ifdef __riscos__ - if( !lockhandle ) - lockhandle = create_dotlock( db_name ); - if( !lockhandle ) - log_fatal( _("%s: can't create lock\n"), db_name ); - if( make_dotlock( lockhandle, -1 ) ) - log_fatal( _("%s: can't make lock\n"), db_name ); -#endif /* __riscos__ */ - oldmask=umask(077); - fp =fopen( fname, "wb" ); - umask(oldmask); - if( !fp ) - log_fatal( _("%s: can't create: %s\n"), fname, strerror(errno) ); - fclose(fp); - db_fd = open( db_name, O_RDWR | MY_O_BINARY ); - if( db_fd == -1 ) - log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) ); - -#ifndef __riscos__ - if( !lockhandle ) - lockhandle = create_dotlock( db_name ); - if( !lockhandle ) - log_fatal( _("%s: can't create lock\n"), db_name ); -#endif /* !__riscos__ */ - - rc = create_version_record (); - if( rc ) - log_fatal( _("%s: failed to create version record: %s"), - fname, gpg_strerror (rc)); - /* and read again to check that we are okay */ - if( tdbio_read_record( 0, &rec, RECTYPE_VER ) ) - log_fatal( _("%s: invalid trustdb created\n"), db_name ); - - if( !opt.quiet ) - log_info(_("%s: trustdb created\n"), db_name); - - return 0; - } - } - xfree (db_name); - db_name = fname; - return 0; -} - - -const char * -tdbio_get_dbname() -{ - return db_name; -} - - - -static void -open_db() -{ - byte buf[10]; - int n; - TRUSTREC rec; - - assert( db_fd == -1 ); - - if (!lockhandle ) - lockhandle = create_dotlock( db_name ); - if (!lockhandle ) - log_fatal( _("%s: can't create lock\n"), db_name ); -#ifdef __riscos__ - if (make_dotlock( lockhandle, -1 ) ) - log_fatal( _("%s: can't make lock\n"), db_name ); -#endif /* __riscos__ */ - db_fd = open (db_name, O_RDWR | MY_O_BINARY ); - if (db_fd == -1 && errno == EACCES) { - db_fd = open (db_name, O_RDONLY | MY_O_BINARY ); - if (db_fd != -1) - log_info (_("NOTE: trustdb not writable\n")); - } - if ( db_fd == -1 ) - log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) ); - - /* check whether we need to do a version migration */ - do - n = read (db_fd, buf, 5); - while (n==-1 && errno == EINTR); - if (n == 5 && !memcmp (buf, "\x01gpg\x02", 5)) - { - migrate_from_v2 (); - } - - /* read the version record */ - if (tdbio_read_record (0, &rec, RECTYPE_VER ) ) - log_fatal( _("%s: invalid trustdb\n"), db_name ); -} - - -/**************** - * Make a hashtable: type 0 = trust hash - */ -static void -create_hashtable( TRUSTREC *vr, int type ) -{ - TRUSTREC rec; - off_t offset; - ulong recnum; - int i, n, rc; - - offset = lseek( db_fd, 0, SEEK_END ); - if( offset == -1 ) - log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) ); - recnum = offset / TRUST_RECORD_LEN; - assert(recnum); /* this is will never be the first record */ - - if( !type ) - vr->r.ver.trusthashtbl = recnum; - - /* Now write the records */ - n = (256+ITEMS_PER_HTBL_RECORD-1) / ITEMS_PER_HTBL_RECORD; - for(i=0; i < n; i++, recnum++ ) { - memset( &rec, 0, sizeof rec ); - rec.rectype = RECTYPE_HTBL; - rec.recnum = recnum; - rc = tdbio_write_record( &rec ); - if( rc ) - log_fatal( _("%s: failed to create hashtable: %s\n"), - db_name, gpg_strerror (rc)); - } - /* update the version record */ - rc = tdbio_write_record( vr ); - if( !rc ) - rc = tdbio_sync(); - if( rc ) - log_fatal( _("%s: error updating version record: %s\n"), - db_name, gpg_strerror (rc)); -} - - -int -tdbio_db_matches_options() -{ - static int yes_no = -1; - - if( yes_no == -1 ) - { - TRUSTREC vr; - int rc; - - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - - yes_no = vr.r.ver.marginals == opt.marginals_needed - && vr.r.ver.completes == opt.completes_needed - && vr.r.ver.cert_depth == opt.max_cert_depth - && vr.r.ver.trust_model == opt.trust_model; - } - - return yes_no; -} - -byte -tdbio_read_model(void) -{ - TRUSTREC vr; - int rc; - - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - return vr.r.ver.trust_model; -} - -/**************** - * Return the nextstamp value. - */ -ulong -tdbio_read_nextcheck () -{ - TRUSTREC vr; - int rc; - - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - return vr.r.ver.nextcheck; -} - -/* Return true when the stamp was actually changed. */ -int -tdbio_write_nextcheck (ulong stamp) -{ - TRUSTREC vr; - int rc; - - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - - if (vr.r.ver.nextcheck == stamp) - return 0; - - vr.r.ver.nextcheck = stamp; - rc = tdbio_write_record( &vr ); - if( rc ) - log_fatal( _("%s: error writing version record: %s\n"), - db_name, gpg_strerror (rc) ); - return 1; -} - - - -/**************** - * Return the record number of the trusthash tbl or create a new one. - */ -static ulong -get_trusthashrec(void) -{ - static ulong trusthashtbl; /* record number of the trust hashtable */ - - if( !trusthashtbl ) { - TRUSTREC vr; - int rc; - - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - if( !vr.r.ver.trusthashtbl ) - create_hashtable( &vr, 0 ); - - trusthashtbl = vr.r.ver.trusthashtbl; - } - return trusthashtbl; -} - - - -/**************** - * Update a hashtable. - * table gives the start of the table, key and keylen is the key, - * newrecnum is the record number to insert. - */ -static int -upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum ) -{ - TRUSTREC lastrec, rec; - ulong hashrec, item; - int msb; - int level=0; - int rc, i; - - hashrec = table; - next_level: - msb = key[level]; - hashrec += msb / ITEMS_PER_HTBL_RECORD; - rc = tdbio_read_record( hashrec, &rec, RECTYPE_HTBL ); - if( rc ) { - log_error ("upd_hashtable in `%s': read failed: %s\n", db_name, - gpg_strerror (rc) ); - return rc; - } - - item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD]; - if( !item ) { /* insert a new item into the hash table */ - rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = newrecnum; - rc = tdbio_write_record( &rec ); - if( rc ) { - log_error ("upd_hashtable in `%s': write htbl failed: %s\n", - db_name, gpg_strerror (rc) ); - return rc; - } - } - else if( item != newrecnum ) { /* must do an update */ - lastrec = rec; - rc = tdbio_read_record( item, &rec, 0 ); - if( rc ) { - log_error( "upd_hashtable: read item failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - - if( rec.rectype == RECTYPE_HTBL ) { - hashrec = item; - level++; - if( level >= keylen ) { - log_error( "hashtable has invalid indirections.\n"); - return GPG_ERR_TRUSTDB; - } - goto next_level; - } - else if( rec.rectype == RECTYPE_HLST ) { /* extend list */ - /* see whether the key is already in this list */ - for(;;) { - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { - if( rec.r.hlst.rnum[i] == newrecnum ) { - return 0; /* okay, already in the list */ - } - } - if( rec.r.hlst.next ) { - rc = tdbio_read_record( rec.r.hlst.next, - &rec, RECTYPE_HLST); - if( rc ) { - log_error( "upd_hashtable: read hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - } - else - break; /* not there */ - } - /* find the next free entry and put it in */ - for(;;) { - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { - if( !rec.r.hlst.rnum[i] ) { - rec.r.hlst.rnum[i] = newrecnum; - rc = tdbio_write_record( &rec ); - if( rc ) - log_error( "upd_hashtable: write hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; /* done */ - } - } - if( rec.r.hlst.next ) { - rc = tdbio_read_record( rec.r.hlst.next, - &rec, RECTYPE_HLST ); - if( rc ) { - log_error( "upd_hashtable: read hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - } - else { /* add a new list record */ - rec.r.hlst.next = item = tdbio_new_recnum(); - rc = tdbio_write_record( &rec ); - if( rc ) { - log_error( "upd_hashtable: write hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - memset( &rec, 0, sizeof rec ); - rec.rectype = RECTYPE_HLST; - rec.recnum = item; - rec.r.hlst.rnum[0] = newrecnum; - rc = tdbio_write_record( &rec ); - if( rc ) - log_error( "upd_hashtable: write ext hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; /* done */ - } - } /* end loop over hlst slots */ - } - else if( rec.rectype == RECTYPE_TRUST ) { /* insert a list record */ - if( rec.recnum == newrecnum ) { - return 0; - } - item = rec.recnum; /* save number of key record */ - memset( &rec, 0, sizeof rec ); - rec.rectype = RECTYPE_HLST; - rec.recnum = tdbio_new_recnum(); - rec.r.hlst.rnum[0] = item; /* old keyrecord */ - rec.r.hlst.rnum[1] = newrecnum; /* and new one */ - rc = tdbio_write_record( &rec ); - if( rc ) { - log_error( "upd_hashtable: write new hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - /* update the hashtable record */ - lastrec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = rec.recnum; - rc = tdbio_write_record( &lastrec ); - if( rc ) - log_error( "upd_hashtable: update htbl failed: %s\n", - gpg_strerror (rc) ); - return rc; /* ready */ - } - else { - log_error( "hashtbl %lu: %lu/%d points to an invalid record %lu\n", - table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item); - list_trustdb(NULL); - return GPG_ERR_TRUSTDB; - } - } - - return 0; -} - - -/**************** - * Drop an entry from a hashtable - * table gives the start of the table, key and keylen is the key, - */ -static int -drop_from_hashtable( ulong table, byte *key, int keylen, ulong recnum ) -{ - TRUSTREC rec; - ulong hashrec, item; - int msb; - int level=0; - int rc, i; - - hashrec = table; - next_level: - msb = key[level]; - hashrec += msb / ITEMS_PER_HTBL_RECORD; - rc = tdbio_read_record( hashrec, &rec, RECTYPE_HTBL ); - if( rc ) { - log_error ("drop_from_hashtable `%s': read failed: %s\n", - db_name, gpg_strerror (rc) ); - return rc; - } - - item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD]; - if( !item ) /* not found - forget about it */ - return 0; - - if( item == recnum ) { /* tables points direct to the record */ - rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = 0; - rc = tdbio_write_record( &rec ); - if( rc ) - log_error ("drop_from_hashtable `%s': write htbl failed: %s\n", - db_name, gpg_strerror (rc) ); - return rc; - } - - rc = tdbio_read_record( item, &rec, 0 ); - if( rc ) { - log_error( "drop_from_hashtable: read item failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - - if( rec.rectype == RECTYPE_HTBL ) { - hashrec = item; - level++; - if( level >= keylen ) { - log_error( "hashtable has invalid indirections.\n"); - return GPG_ERR_TRUSTDB; - } - goto next_level; - } - - if( rec.rectype == RECTYPE_HLST ) { - for(;;) { - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { - if( rec.r.hlst.rnum[i] == recnum ) { - rec.r.hlst.rnum[i] = 0; /* drop */ - rc = tdbio_write_record( &rec ); - if( rc ) - log_error ("drop_from_hashtable `%s': " - "write htbl failed: %s\n", - db_name, gpg_strerror (rc) ); - return rc; - } - } - if( rec.r.hlst.next ) { - rc = tdbio_read_record( rec.r.hlst.next, - &rec, RECTYPE_HLST); - if( rc ) { - log_error( "drop_from_hashtable: read hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - } - else - return 0; /* key not in table */ - } - } - - log_error( "hashtbl %lu: %lu/%d points to wrong record %lu\n", - table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item); - return GPG_ERR_TRUSTDB; -} - - - -/**************** - * Lookup a record via the hashtable tablewith key/keylen and return the - * result in rec. cmp() should return if the record is the desired one. - * Returns -1 if not found, 0 if found or another errocode - */ -static int -lookup_hashtable( ulong table, const byte *key, size_t keylen, - int (*cmpfnc)(void*, const TRUSTREC *), void *cmpdata, - TRUSTREC *rec ) -{ - int rc; - ulong hashrec, item; - int msb; - int level=0; - - hashrec = table; - next_level: - msb = key[level]; - hashrec += msb / ITEMS_PER_HTBL_RECORD; - rc = tdbio_read_record( hashrec, rec, RECTYPE_HTBL ); - if( rc ) { - log_error ("lookup_hashtable in `%s' failed: %s\n", - db_name, gpg_strerror (rc) ); - return rc; - } - - item = rec->r.htbl.item[msb % ITEMS_PER_HTBL_RECORD]; - if( !item ) - return -1; /* not found */ - - rc = tdbio_read_record( item, rec, 0 ); - if( rc ) { - log_error ("hashtable `%s' read failed: %s\n", - db_name, gpg_strerror (rc) ); - return rc; - } - if( rec->rectype == RECTYPE_HTBL ) { - hashrec = item; - level++; - if( level >= keylen ) { - log_error ("hashtable `%s' has invalid indirections\n", db_name); - return GPG_ERR_TRUSTDB; - } - goto next_level; - } - else if( rec->rectype == RECTYPE_HLST ) { - for(;;) { - int i; - - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { - if( rec->r.hlst.rnum[i] ) { - TRUSTREC tmp; - - rc = tdbio_read_record( rec->r.hlst.rnum[i], &tmp, 0 ); - if( rc ) { - log_error( "lookup_hashtable: read item failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - if( (*cmpfnc)( cmpdata, &tmp ) ) { - *rec = tmp; - return 0; - } - } - } - if( rec->r.hlst.next ) { - rc = tdbio_read_record( rec->r.hlst.next, rec, RECTYPE_HLST ); - if( rc ) { - log_error( "lookup_hashtable: read hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - } - else - return -1; /* not found */ - } - } - - - if( (*cmpfnc)( cmpdata, rec ) ) - return 0; /* really found */ - - return -1; /* no: not found */ -} - - -/**************** - * Update the trust hashtbl or create the table if it does not exist - */ -static int -update_trusthashtbl( TRUSTREC *tr ) -{ - return upd_hashtable( get_trusthashrec(), - tr->r.trust.fingerprint, 20, tr->recnum ); -} - - - -void -tdbio_dump_record( TRUSTREC *rec, FILE *fp ) -{ - int i; - ulong rnum = rec->recnum; - - fprintf(fp, "rec %5lu, ", rnum ); - - switch( rec->rectype ) { - case 0: fprintf(fp, "blank\n"); - break; - case RECTYPE_VER: fprintf(fp, - "version, td=%lu, f=%lu, m/c/d=%d/%d/%d tm=%d nc=%lu (%s)\n", - rec->r.ver.trusthashtbl, - rec->r.ver.firstfree, - rec->r.ver.marginals, - rec->r.ver.completes, - rec->r.ver.cert_depth, - rec->r.ver.trust_model, - rec->r.ver.nextcheck, - strtimestamp(rec->r.ver.nextcheck) - ); - break; - case RECTYPE_FREE: fprintf(fp, "free, next=%lu\n", rec->r.free.next ); - break; - case RECTYPE_HTBL: - fprintf(fp, "htbl,"); - for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) - fprintf(fp, " %lu", rec->r.htbl.item[i] ); - putc('\n', fp); - break; - case RECTYPE_HLST: - fprintf(fp, "hlst, next=%lu,", rec->r.hlst.next ); - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) - fprintf(fp, " %lu", rec->r.hlst.rnum[i] ); - putc('\n', fp); - break; - case RECTYPE_TRUST: - fprintf(fp, "trust "); - for(i=0; i < 20; i++ ) - fprintf(fp, "%02X", rec->r.trust.fingerprint[i] ); - fprintf (fp, ", ot=%d, d=%d, vl=%lu\n", rec->r.trust.ownertrust, - rec->r.trust.depth, rec->r.trust.validlist); - break; - case RECTYPE_VALID: - fprintf(fp, "valid "); - for(i=0; i < 20; i++ ) - fprintf(fp, "%02X", rec->r.valid.namehash[i] ); - fprintf (fp, ", v=%d, next=%lu\n", rec->r.valid.validity, - rec->r.valid.next); - break; - default: - fprintf(fp, "unknown type %d\n", rec->rectype ); - break; - } -} - -/**************** - * read the record with number recnum - * returns: -1 on error, 0 on success - */ -int -tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected ) -{ - byte readbuf[TRUST_RECORD_LEN]; - const byte *buf, *p; - int rc = 0; - int n, i; - - if( db_fd == -1 ) - open_db(); - buf = get_record_from_cache( recnum ); - if( !buf ) { - if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) { - rc = gpg_error_from_errno (errno); - log_error(_("trustdb: lseek failed: %s\n"), strerror(errno) ); - return rc; - } - n = read( db_fd, readbuf, TRUST_RECORD_LEN); - if( !n ) { - return -1; /* eof */ - } - else if( n != TRUST_RECORD_LEN ) { - rc = gpg_error_from_errno (errno); - log_error(_("trustdb: read failed (n=%d): %s\n"), n, - strerror(errno) ); - return rc; - } - buf = readbuf; - } - rec->recnum = recnum; - rec->dirty = 0; - p = buf; - rec->rectype = *p++; - if( expected && rec->rectype != expected ) { - log_error("%lu: read expected rec type %d, got %d\n", - recnum, expected, rec->rectype ); - return GPG_ERR_TRUSTDB; - } - p++; /* skip reserved byte */ - switch( rec->rectype ) { - case 0: /* unused (free) record */ - break; - case RECTYPE_VER: /* version record */ - if( memcmp(buf+1, "gpg", 3 ) ) { - log_error( _("%s: not a trustdb file\n"), db_name ); - rc = GPG_ERR_TRUSTDB; - } - p += 2; /* skip "gpg" */ - rec->r.ver.version = *p++; - rec->r.ver.marginals = *p++; - rec->r.ver.completes = *p++; - rec->r.ver.cert_depth = *p++; - rec->r.ver.trust_model = *p++; - p += 3; - rec->r.ver.created = buftoulong(p); p += 4; - rec->r.ver.nextcheck = buftoulong(p); p += 4; - p += 4; - p += 4; - rec->r.ver.firstfree =buftoulong(p); p += 4; - p += 4; - rec->r.ver.trusthashtbl =buftoulong(p); p += 4; - if( recnum ) { - log_error( _("%s: version record with recnum %lu\n"), db_name, - (ulong)recnum ); - rc = GPG_ERR_TRUSTDB; - } - else if( rec->r.ver.version != 3 ) { - log_error( _("%s: invalid file version %d\n"), db_name, - rec->r.ver.version ); - rc = GPG_ERR_TRUSTDB; - } - break; - case RECTYPE_FREE: - rec->r.free.next = buftoulong(p); p += 4; - break; - case RECTYPE_HTBL: - for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) { - rec->r.htbl.item[i] = buftoulong(p); p += 4; - } - break; - case RECTYPE_HLST: - rec->r.hlst.next = buftoulong(p); p += 4; - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { - rec->r.hlst.rnum[i] = buftoulong(p); p += 4; - } - break; - case RECTYPE_TRUST: - memcpy( rec->r.trust.fingerprint, p, 20); p+=20; - rec->r.trust.ownertrust = *p++; - rec->r.trust.depth = *p++; - rec->r.trust.min_ownertrust = *p++; - p++; - rec->r.trust.validlist = buftoulong(p); p += 4; - break; - case RECTYPE_VALID: - memcpy( rec->r.valid.namehash, p, 20); p+=20; - rec->r.valid.validity = *p++; - rec->r.valid.next = buftoulong(p); p += 4; - rec->r.valid.full_count = *p++; - rec->r.valid.marginal_count = *p++; - break; - default: - log_error( "%s: invalid record type %d at recnum %lu\n", - db_name, rec->rectype, (ulong)recnum ); - rc = GPG_ERR_TRUSTDB; - break; - } - - return rc; -} - -/**************** - * Write the record at RECNUM - */ -int -tdbio_write_record( TRUSTREC *rec ) -{ - byte buf[TRUST_RECORD_LEN], *p; - int rc = 0; - int i; - ulong recnum = rec->recnum; - - if( db_fd == -1 ) - open_db(); - - memset(buf, 0, TRUST_RECORD_LEN); - p = buf; - *p++ = rec->rectype; p++; - switch( rec->rectype ) { - case 0: /* unused record */ - break; - case RECTYPE_VER: /* version record */ - if( recnum ) - BUG(); - memcpy(p-1, "gpg", 3 ); p += 2; - *p++ = rec->r.ver.version; - *p++ = rec->r.ver.marginals; - *p++ = rec->r.ver.completes; - *p++ = rec->r.ver.cert_depth; - *p++ = rec->r.ver.trust_model; - p += 3; - ulongtobuf(p, rec->r.ver.created); p += 4; - ulongtobuf(p, rec->r.ver.nextcheck); p += 4; - p += 4; - p += 4; - ulongtobuf(p, rec->r.ver.firstfree ); p += 4; - p += 4; - ulongtobuf(p, rec->r.ver.trusthashtbl ); p += 4; - break; - - case RECTYPE_FREE: - ulongtobuf(p, rec->r.free.next); p += 4; - break; - - - case RECTYPE_HTBL: - for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) { - ulongtobuf( p, rec->r.htbl.item[i]); p += 4; - } - break; - - case RECTYPE_HLST: - ulongtobuf( p, rec->r.hlst.next); p += 4; - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { - ulongtobuf( p, rec->r.hlst.rnum[i]); p += 4; - } - break; - - case RECTYPE_TRUST: - memcpy( p, rec->r.trust.fingerprint, 20); p += 20; - *p++ = rec->r.trust.ownertrust; - *p++ = rec->r.trust.depth; - *p++ = rec->r.trust.min_ownertrust; - p++; - ulongtobuf( p, rec->r.trust.validlist); p += 4; - break; - - case RECTYPE_VALID: - memcpy( p, rec->r.valid.namehash, 20); p += 20; - *p++ = rec->r.valid.validity; - ulongtobuf( p, rec->r.valid.next); p += 4; - *p++ = rec->r.valid.full_count; - *p++ = rec->r.valid.marginal_count; - break; - - default: - BUG(); - } - - rc = put_record_into_cache( recnum, buf ); - if( rc ) - ; - else if( rec->rectype == RECTYPE_TRUST ) - rc = update_trusthashtbl( rec ); - - return rc; -} - -int -tdbio_delete_record( ulong recnum ) -{ - TRUSTREC vr, rec; - int rc; - - /* Must read the record fist, so we can drop it from the hash tables */ - rc = tdbio_read_record( recnum, &rec, 0 ); - if( rc ) - ; - else if( rec.rectype == RECTYPE_TRUST ) { - rc = drop_from_hashtable( get_trusthashrec(), - rec.r.trust.fingerprint, 20, rec.recnum ); - } - - if( rc ) - return rc; - - /* now we can chnage it to a free record */ - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - - rec.recnum = recnum; - rec.rectype = RECTYPE_FREE; - rec.r.free.next = vr.r.ver.firstfree; - vr.r.ver.firstfree = recnum; - rc = tdbio_write_record( &rec ); - if( !rc ) - rc = tdbio_write_record( &vr ); - return rc; -} - -/**************** - * create a new record and return its record number - */ -ulong -tdbio_new_recnum() -{ - off_t offset; - ulong recnum; - TRUSTREC vr, rec; - int rc; - - /* look for unused records */ - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - if( vr.r.ver.firstfree ) { - recnum = vr.r.ver.firstfree; - rc = tdbio_read_record( recnum, &rec, RECTYPE_FREE ); - if( rc ) { - log_error( _("%s: error reading free record: %s\n"), - db_name, gpg_strerror (rc) ); - return rc; - } - /* update dir record */ - vr.r.ver.firstfree = rec.r.free.next; - rc = tdbio_write_record( &vr ); - if( rc ) { - log_error( _("%s: error writing dir record: %s\n"), - db_name, gpg_strerror (rc) ); - return rc; - } - /*zero out the new record */ - memset( &rec, 0, sizeof rec ); - rec.rectype = 0; /* unused record */ - rec.recnum = recnum; - rc = tdbio_write_record( &rec ); - if( rc ) - log_fatal(_("%s: failed to zero a record: %s\n"), - db_name, gpg_strerror (rc)); - } - else { /* not found, append a new record */ - offset = lseek( db_fd, 0, SEEK_END ); - if( offset == -1 ) - log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) ); - recnum = offset / TRUST_RECORD_LEN; - assert(recnum); /* this is will never be the first record */ - /* we must write a record, so that the next call to this function - * returns another recnum */ - memset( &rec, 0, sizeof rec ); - rec.rectype = 0; /* unused record */ - rec.recnum = recnum; - rc = 0; - if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) { - rc = gpg_error_from_errno (errno); - log_error(_("trustdb rec %lu: lseek failed: %s\n"), - recnum, strerror(errno) ); - } - else { - int n = write( db_fd, &rec, TRUST_RECORD_LEN); - if( n != TRUST_RECORD_LEN ) { - rc = gpg_error_from_errno (errno); - log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"), - recnum, n, strerror(errno) ); - } - } - - if( rc ) - log_fatal(_("%s: failed to append a record: %s\n"), - db_name, gpg_strerror (rc)); - } - return recnum ; -} - - - -static int -cmp_trec_fpr ( void *fpr, const TRUSTREC *rec ) -{ - return rec->rectype == RECTYPE_TRUST - && !memcmp( rec->r.trust.fingerprint, fpr, 20); -} - - -int -tdbio_search_trust_byfpr( const byte *fingerprint, TRUSTREC *rec ) -{ - int rc; - - /* locate the trust record using the hash table */ - rc = lookup_hashtable( get_trusthashrec(), fingerprint, 20, - cmp_trec_fpr, (void*)fingerprint, rec ); - return rc; -} - -int -tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec) -{ - byte fingerprint[MAX_FINGERPRINT_LEN]; - size_t fingerlen; - - fingerprint_from_pk( pk, fingerprint, &fingerlen ); - for (; fingerlen < 20; fingerlen++ ) - fingerprint[fingerlen] = 0; - return tdbio_search_trust_byfpr (fingerprint, rec); -} - - - -void -tdbio_invalid(void) -{ - log_error(_( - "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n") ); - g10_exit(2); -} - -/* - * Migrate the trustdb as just up to gpg 1.0.6 (trustdb version 2) - * to the 2.1 version as used with 1.0.6b - This is pretty trivial as needs - * only to scan the tdb and insert new the new trust records. The old ones are - * obsolte from now on - */ -static void -migrate_from_v2 () -{ - TRUSTREC rec; - int i, n; - struct { - ulong keyrecno; - byte ot; - byte okay; - byte fpr[20]; - } *ottable; - int ottable_size, ottable_used; - byte oldbuf[40]; - ulong recno; - int rc, count; - - ottable_size = 5; - ottable = xmalloc (ottable_size * sizeof *ottable); - ottable_used = 0; - - /* We have some restrictions here. We can't use the version record - * and we can't use any of the old hashtables because we dropped the - * code. So we first collect all ownertrusts and then use a second - * pass fo find the associated keys. We have to do this all without using - * the regular record read functions. - */ - - /* get all the ownertrusts */ - if (lseek (db_fd, 0, SEEK_SET ) == -1 ) - log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno)); - for (recno=0;;recno++) - { - do - n = read (db_fd, oldbuf, 40); - while (n==-1 && errno == EINTR); - if (!n) - break; /* eof */ - if (n != 40) - log_fatal ("migrate_vfrom_v2: read error or short read\n"); - - if (*oldbuf != 2) - continue; - - /* v2 dir record */ - if (ottable_used == ottable_size) - { - ottable_size += 1000; - ottable = xrealloc (ottable, ottable_size * sizeof *ottable); - } - ottable[ottable_used].keyrecno = buftoulong (oldbuf+6); - ottable[ottable_used].ot = oldbuf[18]; - ottable[ottable_used].okay = 0; - memset (ottable[ottable_used].fpr,0, 20); - if (ottable[ottable_used].keyrecno && ottable[ottable_used].ot) - ottable_used++; - } - log_info ("found %d ownertrust records\n", ottable_used); - - /* Read again and find the fingerprints */ - if (lseek (db_fd, 0, SEEK_SET ) == -1 ) - log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno)); - for (recno=0;;recno++) - { - do - n = read (db_fd, oldbuf, 40); - while (n==-1 && errno == EINTR); - if (!n) - break; /* eof */ - if (n != 40) - log_fatal ("migrate_from_v2: read error or short read\n"); - - if (*oldbuf != 3) - continue; - - /* v2 key record */ - for (i=0; i < ottable_used; i++) - { - if (ottable[i].keyrecno == recno) - { - memcpy (ottable[i].fpr, oldbuf+20, 20); - ottable[i].okay = 1; - break; - } - } - } - - /* got everything - create the v3 trustdb */ - if (ftruncate (db_fd, 0)) - log_fatal ("can't truncate `%s': %s\n", db_name, strerror (errno) ); - if (create_version_record ()) - log_fatal ("failed to recreate version record of `%s'\n", db_name); - - /* access the hash table, so it is store just after the version record, - * this is not needed put a dump is more pretty */ - get_trusthashrec (); - - /* And insert the old ownertrust values */ - count = 0; - for (i=0; i < ottable_used; i++) - { - if (!ottable[i].okay) - continue; - - memset (&rec, 0, sizeof rec); - rec.recnum = tdbio_new_recnum (); - rec.rectype = RECTYPE_TRUST; - memcpy(rec.r.trust.fingerprint, ottable[i].fpr, 20); - rec.r.trust.ownertrust = ottable[i].ot; - if (tdbio_write_record (&rec)) - log_fatal ("failed to write trust record of `%s'\n", db_name); - count++; - } - - revalidation_mark (); - rc = tdbio_sync (); - if (rc) - log_fatal ("failed to sync `%s'\n", db_name); - log_info ("migrated %d version 2 ownertrusts\n", count); - xfree (ottable); -} diff --git a/g10/tdbio.h b/g10/tdbio.h deleted file mode 100644 index 708e06d2b..000000000 --- a/g10/tdbio.h +++ /dev/null @@ -1,117 +0,0 @@ -/* tdbio.h - Trust database I/O functions - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_TDBIO_H -#define G10_TDBIO_H - -#include "host2net.h" - -#define TRUST_RECORD_LEN 40 -#define SIGS_PER_RECORD ((TRUST_RECORD_LEN-10)/5) -#define ITEMS_PER_HTBL_RECORD ((TRUST_RECORD_LEN-2)/4) -#define ITEMS_PER_HLST_RECORD ((TRUST_RECORD_LEN-6)/5) -#define ITEMS_PER_PREF_RECORD (TRUST_RECORD_LEN-10) -#if ITEMS_PER_PREF_RECORD % 2 -#error ITEMS_PER_PREF_RECORD must be even -#endif -#define MAX_LIST_SIGS_DEPTH 20 - - -#define RECTYPE_VER 1 -#define RECTYPE_HTBL 10 -#define RECTYPE_HLST 11 -#define RECTYPE_TRUST 12 -#define RECTYPE_VALID 13 -#define RECTYPE_FREE 254 - - -struct trust_record { - int rectype; - int mark; - int dirty; /* for now only used internal by functions */ - struct trust_record *next; /* help pointer to build lists in memory */ - ulong recnum; - union { - struct { /* version record: */ - byte version; /* should be 3 */ - byte marginals; - byte completes; - byte cert_depth; - byte trust_model; - ulong created; /* timestamp of trustdb creation */ - ulong nextcheck; /* timestamp of next scheduled check */ - ulong reserved; - ulong reserved2; - ulong firstfree; - ulong reserved3; - ulong trusthashtbl; - } ver; - struct { /* free record */ - ulong next; - } free; - struct { - ulong item[ITEMS_PER_HTBL_RECORD]; - } htbl; - struct { - ulong next; - ulong rnum[ITEMS_PER_HLST_RECORD]; /* of another record */ - } hlst; - struct { - byte fingerprint[20]; - byte ownertrust; - byte depth; - ulong validlist; - byte min_ownertrust; - } trust; - struct { - byte namehash[20]; - ulong next; - byte validity; - byte full_count; - byte marginal_count; - } valid; - } r; -}; -typedef struct trust_record TRUSTREC; - -/*-- tdbio.c --*/ -int tdbio_update_version_record(void); -int tdbio_set_dbname( const char *new_dbname, int create ); -const char *tdbio_get_dbname(void); -void tdbio_dump_record( TRUSTREC *rec, FILE *fp ); -int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected ); -int tdbio_write_record( TRUSTREC *rec ); -int tdbio_db_matches_options(void); -byte tdbio_read_model(void); -ulong tdbio_read_nextcheck (void); -int tdbio_write_nextcheck (ulong stamp); -int tdbio_is_dirty(void); -int tdbio_sync(void); -int tdbio_begin_transaction(void); -int tdbio_end_transaction(void); -int tdbio_cancel_transaction(void); -int tdbio_delete_record( ulong recnum ); -ulong tdbio_new_recnum(void); -int tdbio_search_trust_byfpr(const byte *fingerprint, TRUSTREC *rec ); -int tdbio_search_trust_bypk(PKT_public_key *pk, TRUSTREC *rec ); - -void tdbio_invalid(void); - -#endif /*G10_TDBIO_H*/ diff --git a/g10/textfilter.c b/g10/textfilter.c deleted file mode 100644 index a3ea4b138..000000000 --- a/g10/textfilter.c +++ /dev/null @@ -1,235 +0,0 @@ -/* textfilter.c - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "filter.h" -#include "i18n.h" -#include "options.h" - -#ifdef HAVE_DOSISH_SYSTEM -#define LF "\r\n" -#else -#define LF "\n" -#endif - -#define MAX_LINELEN 19995 /* a little bit smaller than in armor.c */ - /* to make sure that a warning is displayed while */ - /* creating a message */ - -static unsigned -len_without_trailing_chars( byte *line, unsigned len, const char *trimchars ) -{ - byte *p, *mark; - unsigned n; - - for(mark=NULL, p=line, n=0; n < len; n++, p++ ) { - if( strchr( trimchars, *p ) ) { - if( !mark ) - mark = p; - } - else - mark = NULL; - } - - return mark? (mark - line) : len; -} - -unsigned -len_without_trailing_ws( byte *line, unsigned len ) -{ - return len_without_trailing_chars( line, len, " \t\r\n" ); -} - - - - -static int -standard( text_filter_context_t *tfx, iobuf_t a, - byte *buf, size_t size, size_t *ret_len) -{ - int rc=0; - size_t len = 0; - unsigned maxlen; - - assert( size > 10 ); - size -= 2; /* reserve 2 bytes to append CR,LF */ - while( !rc && len < size ) { - int lf_seen; - - while( len < size && tfx->buffer_pos < tfx->buffer_len ) - buf[len++] = tfx->buffer[tfx->buffer_pos++]; - if( len >= size ) - continue; - - /* read the next line */ - maxlen = MAX_LINELEN; - tfx->buffer_pos = 0; - tfx->buffer_len = iobuf_read_line( a, &tfx->buffer, - &tfx->buffer_size, &maxlen ); - if( !maxlen ) - tfx->truncated++; - if( !tfx->buffer_len ) { - if( !len ) - rc = -1; /* eof */ - break; - } - lf_seen = tfx->buffer[tfx->buffer_len-1] == '\n'; - tfx->buffer_len = trim_trailing_ws( tfx->buffer, tfx->buffer_len ); - if( lf_seen ) { - tfx->buffer[tfx->buffer_len++] = '\r'; - tfx->buffer[tfx->buffer_len++] = '\n'; - } - } - *ret_len = len; - return rc; -} - - - - -/**************** - * The filter is used to make canonical text: Lines are terminated by - * CR, LF, trailing white spaces are removed. - */ -int -text_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - text_filter_context_t *tfx = opaque; - int rc=0; - - if( control == IOBUFCTRL_UNDERFLOW ) { - rc = standard( tfx, a, buf, size, ret_len ); - } - else if( control == IOBUFCTRL_FREE ) { - if( tfx->truncated ) - log_error(_("can't handle text lines longer than %d characters\n"), - MAX_LINELEN ); - xfree ( tfx->buffer ); - tfx->buffer = NULL; - } - else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "text_filter"; - return rc; -} - - -/**************** - * Copy data from INP to OUT and do some escaping if requested. - * md is updated as required by rfc2440 - */ -int -copy_clearsig_text( iobuf_t out, iobuf_t inp, MD_HANDLE md, - int escape_dash, int escape_from, int pgp2mode ) -{ - unsigned maxlen; - byte *buffer = NULL; /* malloced buffer */ - unsigned bufsize; /* and size of this buffer */ - unsigned n; - int truncated = 0; - int pending_lf = 0; - - if( !opt.pgp2_workarounds ) - pgp2mode = 0; - - if( !escape_dash ) - escape_from = 0; - - for(;;) { - maxlen = MAX_LINELEN; - n = iobuf_read_line( inp, &buffer, &bufsize, &maxlen ); - if( !maxlen ) - truncated++; - - if( !n ) - break; /* read_line has returned eof */ - - /* update the message digest */ - if( escape_dash ) { - if( pending_lf ) { - gcry_md_putc( md, '\r' ); - gcry_md_putc( md, '\n' ); - } - gcry_md_write( md, buffer, - len_without_trailing_chars( buffer, n, - pgp2mode? " \r\n":" \t\r\n")); - } - else - gcry_md_write( md, buffer, n ); - pending_lf = buffer[n-1] == '\n'; - - /* write the output */ - if( ( escape_dash && *buffer == '-') - || ( escape_from && n > 4 && !memcmp(buffer, "From ", 5 ) ) ) { - iobuf_put( out, '-' ); - iobuf_put( out, ' ' ); - } - -#if 0 /*defined(HAVE_DOSISH_SYSTEM)*/ - /* We don't use this anymore because my interpretation of rfc2440 7.1 - * is that there is no conversion needed. If one decides to - * clearsign a unix file on a DOS box he will get a mixed line endings. - * If at some point it turns out, that a conversion is a nice feature - * we can make an option out of it. - */ - /* make sure the lines do end in CR,LF */ - if( n > 1 && ( (buffer[n-2] == '\r' && buffer[n-1] == '\n' ) - || (buffer[n-2] == '\n' && buffer[n-1] == '\r'))) { - iobuf_write( out, buffer, n-2 ); - iobuf_put( out, '\r'); - iobuf_put( out, '\n'); - } - else if( n && buffer[n-1] == '\n' ) { - iobuf_write( out, buffer, n-1 ); - iobuf_put( out, '\r'); - iobuf_put( out, '\n'); - } - else - iobuf_write( out, buffer, n ); - -#else - iobuf_write( out, buffer, n ); -#endif - } - - /* at eof */ - if( !pending_lf ) { /* make sure that the file ends with a LF */ - iobuf_writestr( out, LF ); - if( !escape_dash ) - gcry_md_putc( md, '\n' ); - } - - if( truncated ) - log_info(_("input line longer than %d characters\n"), MAX_LINELEN ); - - return 0; /* okay */ -} diff --git a/g10/trustdb.c b/g10/trustdb.c deleted file mode 100644 index b3a2b369e..000000000 --- a/g10/trustdb.c +++ /dev/null @@ -1,2158 +0,0 @@ -/* trustdb.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 - * Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#ifndef DISABLE_REGEX -#include <sys/types.h> -#ifdef USE_GNU_REGEX -#include "_regex.h" -#else -#include <regex.h> -#endif -#endif /* !DISABLE_REGEX */ - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "options.h" -#include "packet.h" -#include "main.h" -#include "i18n.h" -#include "tdbio.h" -#include "trustdb.h" - - -/* - * A structure to store key identification as well as some stuff needed - * for validation - */ -struct key_item { - struct key_item *next; - unsigned int ownertrust,min_ownertrust; - byte trust_depth; - byte trust_value; - char *trust_regexp; - u32 kid[2]; -}; - - -typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */ - -/* - * Structure to keep track of keys, this is used as an array wherre - * the item right after the last one has a keyblock set to NULL. - * Maybe we can drop this thing and replace it by key_item - */ -struct key_array { - KBNODE keyblock; -}; - - -/* control information for the trust DB */ -static struct { - int init; - int level; - char *dbname; -} trustdb_args; - -/* some globals */ -static struct key_item *user_utk_list; /* temp. used to store --trusted-keys */ -static struct key_item *utk_list; /* all ultimately trusted keys */ - -static int pending_check_trustdb; - -static int validate_keys (int interactive); - - -/********************************************** - ************* some helpers ******************* - **********************************************/ - -static struct key_item * -new_key_item (void) -{ - struct key_item *k; - - k = xcalloc (1,sizeof *k); - return k; -} - -static void -release_key_items (struct key_item *k) -{ - struct key_item *k2; - - for (; k; k = k2) - { - k2 = k->next; - xfree (k->trust_regexp); - xfree (k); - } -} - -/* - * For fast keylook up we need a hash table. Each byte of a KeyIDs - * should be distributed equally over the 256 possible values (except - * for v3 keyIDs but we consider them as not important here). So we - * can just use 10 bits to index a table of 1024 key items. - * Possible optimization: Don not use key_items but other hash_table when the - * duplicates lists gets too large. - */ -static KeyHashTable -new_key_hash_table (void) -{ - struct key_item **tbl; - - tbl = xcalloc (1,1024 * sizeof *tbl); - return tbl; -} - -static void -release_key_hash_table (KeyHashTable tbl) -{ - int i; - - if (!tbl) - return; - for (i=0; i < 1024; i++) - release_key_items (tbl[i]); - xfree (tbl); -} - -/* - * Returns: True if the keyID is in the given hash table - */ -static int -test_key_hash_table (KeyHashTable tbl, u32 *kid) -{ - struct key_item *k; - - for (k = tbl[(kid[1] & 0x03ff)]; k; k = k->next) - if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) - return 1; - return 0; -} - -/* - * Add a new key to the hash table. The key is identified by its key ID. - */ -static void -add_key_hash_table (KeyHashTable tbl, u32 *kid) -{ - struct key_item *k, *kk; - - for (k = tbl[(kid[1] & 0x03ff)]; k; k = k->next) - if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) - return; /* already in table */ - - kk = new_key_item (); - kk->kid[0] = kid[0]; - kk->kid[1] = kid[1]; - kk->next = tbl[(kid[1] & 0x03ff)]; - tbl[(kid[1] & 0x03ff)] = kk; -} - -/* - * Release a key_array - */ -static void -release_key_array ( struct key_array *keys ) -{ - struct key_array *k; - - if (keys) { - for (k=keys; k->keyblock; k++) - release_kbnode (k->keyblock); - xfree (keys); - } -} - - -/********************************************* - ********** Initialization ***************** - *********************************************/ - - - -/* - * Used to register extra ultimately trusted keys - this has to be done - * before initializing the validation module. - * FIXME: Should be replaced by a function to add those keys to the trustdb. - */ -void -register_trusted_key( const char *string ) -{ - KEYDB_SEARCH_DESC desc; - struct key_item *k; - - if (classify_user_id (string, &desc) != KEYDB_SEARCH_MODE_LONG_KID ) { - log_error(_("`%s' is not a valid long keyID\n"), string ); - return; - } - - k = new_key_item (); - k->kid[0] = desc.u.kid[0]; - k->kid[1] = desc.u.kid[1]; - k->next = user_utk_list; - user_utk_list = k; -} - -/* - * Helper to add a key to the global list of ultimately trusted keys. - * Retruns: true = inserted, false = already in in list. - */ -static int -add_utk (u32 *kid) -{ - struct key_item *k; - - for (k = utk_list; k; k = k->next) - { - if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) - { - return 0; - } - } - - k = new_key_item (); - k->kid[0] = kid[0]; - k->kid[1] = kid[1]; - k->ownertrust = TRUST_ULTIMATE; - k->next = utk_list; - utk_list = k; - if( opt.verbose > 1 ) - log_info(_("key %08lX: accepted as trusted key\n"), (ulong)kid[1]); - return 1; -} - - -/**************** - * Verify that all our secret keys are usable and put them into the utk_list. - */ -static void -verify_own_keys(void) -{ - TRUSTREC rec; - ulong recnum; - int rc; - struct key_item *k; - - if (utk_list) - return; - - /* scan the trustdb to find all ultimately trusted keys */ - for (recnum=1; !tdbio_read_record (recnum, &rec, 0); recnum++ ) - { - if ( rec.rectype == RECTYPE_TRUST - && (rec.r.trust.ownertrust & TRUST_MASK) == TRUST_ULTIMATE) - { - byte *fpr = rec.r.trust.fingerprint; - int fprlen; - u32 kid[2]; - - /* Problem: We do only use fingerprints in the trustdb but - * we need the keyID here to indetify the key; we can only - * use that ugly hack to distinguish between 16 and 20 - * butes fpr - it does not work always so we better change - * the whole validation code to only work with - * fingerprints */ - fprlen = (!fpr[16] && !fpr[17] && !fpr[18] && !fpr[19])? 16:20; - keyid_from_fingerprint (fpr, fprlen, kid); - if (!add_utk (kid)) - log_info(_("key %08lX occurs more than once in the trustdb\n"), - (ulong)kid[1]); - } - } - - /* Put any --trusted-key keys into the trustdb */ - for (k = user_utk_list; k; k = k->next) - { - if ( add_utk (k->kid) ) - { /* not yet in trustDB as ultimately trusted */ - PKT_public_key pk; - - memset (&pk, 0, sizeof pk); - rc = get_pubkey (&pk, k->kid); - if (rc) { - log_info(_("key %08lX: no public key for trusted key - skipped\n"), - (ulong)k->kid[1] ); - } - else { - update_ownertrust (&pk, - ((get_ownertrust (&pk) & ~TRUST_MASK) - | TRUST_ULTIMATE )); - release_public_key_parts (&pk); - } - log_info (_("key %08lX marked as ultimately trusted\n"), - (ulong)k->kid[1]); - } - } - - - /* release the helper table table */ - release_key_items (user_utk_list); - user_utk_list = NULL; - return; -} - - -/********************************************* - *********** TrustDB stuff ******************* - *********************************************/ - -/* - * Read a record but die if it does not exist - */ -static void -read_record (ulong recno, TRUSTREC *rec, int rectype ) -{ - int rc = tdbio_read_record (recno, rec, rectype); - if (rc) - { - log_error(_("trust record %lu, req type %d: read failed: %s\n"), - recno, rec->rectype, gpg_strerror (rc) ); - tdbio_invalid(); - } - if (rectype != rec->rectype) - { - log_error(_("trust record %lu is not of requested type %d\n"), - rec->recnum, rectype); - tdbio_invalid(); - } -} - -/* - * Write a record and die on error - */ -static void -write_record (TRUSTREC *rec) -{ - int rc = tdbio_write_record (rec); - if (rc) - { - log_error(_("trust record %lu, type %d: write failed: %s\n"), - rec->recnum, rec->rectype, gpg_strerror (rc) ); - tdbio_invalid(); - } -} - -/* - * sync the TrustDb and die on error - */ -static void -do_sync(void) -{ - int rc = tdbio_sync (); - if(rc) - { - log_error (_("trustdb: sync failed: %s\n"), gpg_strerror (rc) ); - g10_exit(2); - } -} - -static const char * -trust_model_string(void) -{ - switch(opt.trust_model) - { - case TM_PGP: return "PGP"; - case TM_CLASSIC: return "classic"; - case TM_ALWAYS: return "always"; - default: return "unknown"; - } -} - -/**************** - * Perform some checks over the trustdb - * level 0: only open the db - * 1: used for initial program startup - */ -int -setup_trustdb( int level, const char *dbname ) -{ - /* just store the args */ - if( trustdb_args.init ) - return 0; - trustdb_args.level = level; - trustdb_args.dbname = dbname? xstrdup (dbname): NULL; - return 0; -} - -void -init_trustdb() -{ - int rc=0; - int level = trustdb_args.level; - const char* dbname = trustdb_args.dbname; - - if( trustdb_args.init ) - return; - - trustdb_args.init = 1; - - if ( !level || level==1) - { - rc = tdbio_set_dbname( dbname, !!level ); - if( !rc ) - { - if( !level ) - return; - - /* verify that our own keys are in the trustDB - * or move them to the trustdb. */ - verify_own_keys(); - - /* should we check whether there is no other ultimately trusted - * key in the database? */ - } - } - else - BUG(); - if( rc ) - log_fatal("can't init trustdb: %s\n", gpg_strerror (rc) ); - - if(opt.trust_model==TM_AUTO) - { - /* Try and set the trust model off of whatever the trustdb says - it is. */ - opt.trust_model=tdbio_read_model(); - - /* Sanity check this ;) */ - if(opt.trust_model!=TM_PGP && opt.trust_model!=TM_CLASSIC) - { - log_info(_("unable to use unknown trust model (%d) - " - "assuming %s trust model\n"),opt.trust_model,"PGP"); - opt.trust_model=TM_PGP; - } - - if(opt.verbose) - log_info(_("using %s trust model\n"),trust_model_string()); - } - - if((opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC) - && !tdbio_db_matches_options()) - pending_check_trustdb=1; -} - - - - -/*********************************************** - ************* Print helpers **************** - ***********************************************/ - -/**************** - * This function returns a letter for a trustvalue Trust flags - * are ignore. - */ -static int -trust_letter (unsigned int value) -{ - switch( (value & TRUST_MASK) ) - { - case TRUST_UNKNOWN: return '-'; - case TRUST_EXPIRED: return 'e'; - case TRUST_UNDEFINED: return 'q'; - case TRUST_NEVER: return 'n'; - case TRUST_MARGINAL: return 'm'; - case TRUST_FULLY: return 'f'; - case TRUST_ULTIMATE: return 'u'; - default: return '?'; - } -} - -/* The strings here are similar to those in - pkclist.c:do_edit_ownertrust() */ -const char * -trust_value_to_string (unsigned int value) -{ - switch( (value & TRUST_MASK) ) - { - case TRUST_UNKNOWN: return _("unknown"); - case TRUST_EXPIRED: return _("expired"); - case TRUST_UNDEFINED: return _("undefined"); - case TRUST_NEVER: return _("never"); - case TRUST_MARGINAL: return _("marginal"); - case TRUST_FULLY: return _("full"); - case TRUST_ULTIMATE: return _("ultimate"); - default: return "err"; - } -} - -int -string_to_trust_value (const char *str) -{ - if(ascii_strcasecmp(str,"undefined")==0) - return TRUST_UNDEFINED; - else if(ascii_strcasecmp(str,"never")==0) - return TRUST_NEVER; - else if(ascii_strcasecmp(str,"marginal")==0) - return TRUST_MARGINAL; - else if(ascii_strcasecmp(str,"full")==0) - return TRUST_FULLY; - else if(ascii_strcasecmp(str,"ultimate")==0) - return TRUST_ULTIMATE; - else - return -1; -} - -/**************** - * Recreate the WoT but do not ask for new ownertrusts. Special - * feature: In batch mode and without a forced yes, this is only done - * when a check is due. This can be used to run the check from a crontab - */ -void -check_trustdb () -{ - init_trustdb(); - if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC) - { - if (opt.batch && !opt.answer_yes) - { - ulong scheduled; - - scheduled = tdbio_read_nextcheck (); - if (!scheduled) - { - log_info (_("no need for a trustdb check\n")); - return; - } - - if (scheduled > make_timestamp ()) - { - log_info (_("next trustdb check due at %s\n"), - strtimestamp (scheduled)); - return; - } - } - - validate_keys (0); - } - else - log_info (_("no need for a trustdb check with \"%s\" trust model\n"), - trust_model_string()); -} - - -/* - * Recreate the WoT. - */ -void -update_trustdb() -{ - init_trustdb(); - if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC) - validate_keys (1); - else - log_info (_("no need for a trustdb update with \"%s\" trust model\n"), - trust_model_string()); -} - -void -revalidation_mark (void) -{ - init_trustdb(); - /* we simply set the time for the next check to 1 (far back in 1970) - * so that a --update-trustdb will be scheduled */ - if (tdbio_write_nextcheck (1)) - do_sync (); - pending_check_trustdb = 1; -} - -int -trustdb_pending_check(void) -{ - return pending_check_trustdb; -} - -void -read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck, - byte *marginals,byte *completes,byte *cert_depth) -{ - TRUSTREC opts; - - init_trustdb(); - - read_record(0,&opts,RECTYPE_VER); - - if(trust_model) - *trust_model=opts.r.ver.trust_model; - if(created) - *created=opts.r.ver.created; - if(nextcheck) - *nextcheck=opts.r.ver.nextcheck; - if(marginals) - *marginals=opts.r.ver.marginals; - if(completes) - *completes=opts.r.ver.completes; - if(cert_depth) - *cert_depth=opts.r.ver.cert_depth; -} - - - -/*********************************************** - *********** Ownertrust et al. **************** - ***********************************************/ - -static int -read_trust_record (PKT_public_key *pk, TRUSTREC *rec) -{ - int rc; - - init_trustdb(); - rc = tdbio_search_trust_bypk (pk, rec); - if (rc == -1) - return -1; /* no record yet */ - if (rc) - { - log_error ("trustdb: searching trust record failed: %s\n", - gpg_strerror (rc)); - return rc; - } - - if (rec->rectype != RECTYPE_TRUST) - { - log_error ("trustdb: record %lu is not a trust record\n", - rec->recnum); - return GPG_ERR_TRUSTDB; - } - - return 0; -} - -/**************** - * Return the assigned ownertrust value for the given public key. - * The key should be the primary key. - */ -unsigned int -get_ownertrust ( PKT_public_key *pk) -{ - TRUSTREC rec; - int rc; - - rc = read_trust_record (pk, &rec); - if (rc == -1) - return TRUST_UNKNOWN; /* no record yet */ - if (rc) - { - tdbio_invalid (); - return rc; /* actually never reached */ - } - - return rec.r.trust.ownertrust; -} - -unsigned int -get_min_ownertrust (PKT_public_key *pk) -{ - TRUSTREC rec; - int rc; - - rc = read_trust_record (pk, &rec); - if (rc == -1) - return TRUST_UNKNOWN; /* no record yet */ - if (rc) - { - tdbio_invalid (); - return rc; /* actually never reached */ - } - - return rec.r.trust.min_ownertrust; -} - -/* - * Same as get_ownertrust but this takes the minimum ownertrust value - * into into account, and will bump up the value as needed. - */ -static int -get_ownertrust_with_min (PKT_public_key *pk) -{ - unsigned int otrust,otrust_min; - - otrust = (get_ownertrust (pk) & TRUST_MASK); - otrust_min = get_min_ownertrust (pk); - if(otrust<otrust_min) - { - /* If the trust that the user has set is less than the trust - that was calculated from a trust signature chain, use the - higher of the two. We do this here and not in - get_ownertrust since the underlying ownertrust should not - really be set - just the appearance of the ownertrust. */ - - otrust=otrust_min; - } - - return otrust; -} - -/* - * Same as get_ownertrust but return a trust letter instead of an - * value. This takes the minimum ownertrust value into account. - */ -int -get_ownertrust_info (PKT_public_key *pk) -{ - return trust_letter(get_ownertrust_with_min(pk)); -} - -/* - * Same as get_ownertrust but return a trust string instead of an - * value. This takes the minimum ownertrust value into account. - */ -const char * -get_ownertrust_string (PKT_public_key *pk) -{ - return trust_value_to_string(get_ownertrust_with_min(pk)); -} - -/* - * Set the trust value of the given public key to the new value. - * The key should be a primary one. - */ -void -update_ownertrust (PKT_public_key *pk, unsigned int new_trust ) -{ - TRUSTREC rec; - int rc; - - rc = read_trust_record (pk, &rec); - if (!rc) - { - if (DBG_TRUST) - log_debug ("update ownertrust from %u to %u\n", - (unsigned int)rec.r.trust.ownertrust, new_trust ); - if (rec.r.trust.ownertrust != new_trust) - { - rec.r.trust.ownertrust = new_trust; - write_record( &rec ); - revalidation_mark (); - do_sync (); - } - } - else if (rc == -1) - { /* no record yet - create a new one */ - size_t dummy; - - if (DBG_TRUST) - log_debug ("insert ownertrust %u\n", new_trust ); - - memset (&rec, 0, sizeof rec); - rec.recnum = tdbio_new_recnum (); - rec.rectype = RECTYPE_TRUST; - fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy); - rec.r.trust.ownertrust = new_trust; - write_record (&rec); - revalidation_mark (); - do_sync (); - rc = 0; - } - else - { - tdbio_invalid (); - } -} - -static void -update_min_ownertrust (u32 *kid, unsigned int new_trust ) -{ - PKT_public_key *pk; - TRUSTREC rec; - int rc; - - pk = xcalloc (1,sizeof *pk); - rc = get_pubkey (pk, kid); - if (rc) - { - log_error (_("public key %08lX not found: %s\n"), - (ulong)kid[1], gpg_strerror (rc) ); - return; - } - - rc = read_trust_record (pk, &rec); - if (!rc) - { - if (DBG_TRUST) - log_debug ("key %08lX: update min_ownertrust from %u to %u\n", - (ulong)kid[1],(unsigned int)rec.r.trust.min_ownertrust, - new_trust ); - if (rec.r.trust.min_ownertrust != new_trust) - { - rec.r.trust.min_ownertrust = new_trust; - write_record( &rec ); - revalidation_mark (); - do_sync (); - } - } - else if (rc == -1) - { /* no record yet - create a new one */ - size_t dummy; - - if (DBG_TRUST) - log_debug ("insert min_ownertrust %u\n", new_trust ); - - memset (&rec, 0, sizeof rec); - rec.recnum = tdbio_new_recnum (); - rec.rectype = RECTYPE_TRUST; - fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy); - rec.r.trust.min_ownertrust = new_trust; - write_record (&rec); - revalidation_mark (); - do_sync (); - rc = 0; - } - else - { - tdbio_invalid (); - } -} - -/* Clear the ownertrust and min_ownertrust values. Return true if a - change actually happened. */ -int -clear_ownertrusts (PKT_public_key *pk) -{ - TRUSTREC rec; - int rc; - - rc = read_trust_record (pk, &rec); - if (!rc) - { - if (DBG_TRUST) - { - log_debug ("clearing ownertrust (old value %u)\n", - (unsigned int)rec.r.trust.ownertrust); - log_debug ("clearing min_ownertrust (old value %u)\n", - (unsigned int)rec.r.trust.min_ownertrust); - } - if (rec.r.trust.ownertrust || rec.r.trust.min_ownertrust) - { - rec.r.trust.ownertrust = 0; - rec.r.trust.min_ownertrust = 0; - write_record( &rec ); - revalidation_mark (); - do_sync (); - return 1; - } - } - else if (rc != -1) - { - tdbio_invalid (); - } - return 0; -} - -/* - * Note: Caller has to do a sync - */ -static void -update_validity (PKT_public_key *pk, PKT_user_id *uid, - int depth, int validity) -{ - TRUSTREC trec, vrec; - int rc; - ulong recno; - - namehash_from_uid(uid); - - rc = read_trust_record (pk, &trec); - if (rc && rc != -1) - { - tdbio_invalid (); - return; - } - if (rc == -1) /* no record yet - create a new one */ - { - size_t dummy; - - rc = 0; - memset (&trec, 0, sizeof trec); - trec.recnum = tdbio_new_recnum (); - trec.rectype = RECTYPE_TRUST; - fingerprint_from_pk (pk, trec.r.trust.fingerprint, &dummy); - trec.r.trust.ownertrust = 0; - } - - /* locate an existing one */ - recno = trec.r.trust.validlist; - while (recno) - { - read_record (recno, &vrec, RECTYPE_VALID); - if ( !memcmp (vrec.r.valid.namehash, uid->namehash, 20) ) - break; - recno = vrec.r.valid.next; - } - - if (!recno) /* insert a new validity record */ - { - memset (&vrec, 0, sizeof vrec); - vrec.recnum = tdbio_new_recnum (); - vrec.rectype = RECTYPE_VALID; - memcpy (vrec.r.valid.namehash, uid->namehash, 20); - vrec.r.valid.next = trec.r.trust.validlist; - trec.r.trust.validlist = vrec.recnum; - } - vrec.r.valid.validity = validity; - vrec.r.valid.full_count = uid->help_full_count; - vrec.r.valid.marginal_count = uid->help_marginal_count; - write_record (&vrec); - trec.r.trust.depth = depth; - write_record (&trec); -} - - -/* reset validity for all user IDs. Caller must sync. */ -static int -clear_validity (PKT_public_key *pk) -{ - TRUSTREC trec, vrec; - int rc; - ulong recno; - int any = 0; - - rc = read_trust_record (pk, &trec); - if (rc && rc != -1) - { - tdbio_invalid (); - return 0; - } - if (rc == -1) /* no record yet - no need to clear it then ;-) */ - return 0; - - /* Clear minimum ownertrust, if any */ - if(trec.r.trust.min_ownertrust) - { - trec.r.trust.min_ownertrust=0; - write_record(&trec); - } - - recno = trec.r.trust.validlist; - while (recno) - { - read_record (recno, &vrec, RECTYPE_VALID); - if ((vrec.r.valid.validity & TRUST_MASK) - || vrec.r.valid.marginal_count || vrec.r.valid.full_count) - { - vrec.r.valid.validity &= ~TRUST_MASK; - vrec.r.valid.marginal_count = vrec.r.valid.full_count = 0; - write_record (&vrec); - any = 1; - } - recno = vrec.r.valid.next; - } - - return any; -} - -/*********************************************** - ********* Query trustdb values ************** - ***********************************************/ - -/* Return true if key is disabled */ -int -cache_disabled_value(PKT_public_key *pk) -{ - int rc; - TRUSTREC trec; - int disabled=0; - - if(pk->is_disabled) - return (pk->is_disabled==2); - - init_trustdb(); - - rc = read_trust_record (pk, &trec); - if (rc && rc != -1) - { - tdbio_invalid (); - goto leave; - } - if (rc == -1) /* no record found, so assume not disabled */ - goto leave; - - if(trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) - disabled=1; - - /* Cache it for later so we don't need to look at the trustdb every - time */ - if(disabled) - pk->is_disabled=2; - else - pk->is_disabled=1; - - leave: - return disabled; -} - -/* - * Return the validity information for PK. If the namehash is not - * NULL, the validity of the corresponsing user ID is returned, - * otherwise, a reasonable value for the entire key is returned. - */ -unsigned int -get_validity (PKT_public_key *pk, PKT_user_id *uid) -{ - static int did_nextcheck; - TRUSTREC trec, vrec; - int rc; - ulong recno; - unsigned int validity; - u32 kid[2]; - PKT_public_key *main_pk; - - if(uid) - namehash_from_uid(uid); - - init_trustdb (); - if (!did_nextcheck - && (opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)) - { - ulong scheduled; - - did_nextcheck = 1; - scheduled = tdbio_read_nextcheck (); - if (scheduled && scheduled <= make_timestamp ()) - { - if (opt.no_auto_check_trustdb) - { - pending_check_trustdb = 1; - log_info (_("please do a --check-trustdb\n")); - } - else - { - log_info (_("checking the trustdb\n")); - validate_keys (0); - } - } - } - - keyid_from_pk (pk, kid); - if (pk->main_keyid[0] != kid[0] || pk->main_keyid[1] != kid[1]) - { /* this is a subkey - get the mainkey */ - main_pk = xcalloc (1,sizeof *main_pk); - rc = get_pubkey (main_pk, pk->main_keyid); - if (rc) - { - log_error ("error getting main key %08lX of subkey %08lX: %s\n", - (ulong)pk->main_keyid[1], (ulong)kid[1], gpg_strerror (rc)); - validity = TRUST_UNKNOWN; - goto leave; - } - } - else - main_pk = pk; - - rc = read_trust_record (main_pk, &trec); - if (rc && rc != -1) - { - tdbio_invalid (); - return 0; - } - if (rc == -1) /* no record found */ - { - validity = TRUST_UNKNOWN; - goto leave; - } - - /* loop over all user IDs */ - recno = trec.r.trust.validlist; - validity = 0; - while (recno) - { - read_record (recno, &vrec, RECTYPE_VALID); - - if(uid) - { - /* If a user ID is given we return the validity for that - user ID ONLY. If the namehash is not found, then there - is no validity at all (i.e. the user ID wasn't - signed). */ - if(memcmp(vrec.r.valid.namehash,uid->namehash,20)==0) - { - validity=(vrec.r.valid.validity & TRUST_MASK); - break; - } - } - else - { - /* If no namehash is given, we take the maximum validity - over all user IDs */ - if ( validity < (vrec.r.valid.validity & TRUST_MASK) ) - validity = (vrec.r.valid.validity & TRUST_MASK); - } - - recno = vrec.r.valid.next; - } - - if ( (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) ) - { - validity |= TRUST_FLAG_DISABLED; - pk->is_disabled=2; - } - else - pk->is_disabled=1; - - leave: - /* set some flags direct from the key */ - if (main_pk->is_revoked) - validity |= TRUST_FLAG_REVOKED; - if (main_pk != pk && pk->is_revoked) - validity |= TRUST_FLAG_SUB_REVOKED; - /* Note: expiration is a trust value and not a flag - don't know why - * I initially designed it that way */ - if (main_pk->has_expired || pk->has_expired) - validity = (validity & ~TRUST_MASK) | TRUST_EXPIRED; - - if (pending_check_trustdb) - validity |= TRUST_FLAG_PENDING_CHECK; - - if (main_pk != pk) - free_public_key (main_pk); - return validity; -} - -int -get_validity_info (PKT_public_key *pk, PKT_user_id *uid) -{ - int trustlevel; - - trustlevel = get_validity (pk, uid); - if( trustlevel & TRUST_FLAG_REVOKED ) - return 'r'; - return trust_letter ( trustlevel ); -} - -const char * -get_validity_string (PKT_public_key *pk, PKT_user_id *uid) -{ - int trustlevel; - - trustlevel = get_validity (pk, uid); - if( trustlevel & TRUST_FLAG_REVOKED ) - return _("revoked"); - return trust_value_to_string(trustlevel); -} - -static void -get_validity_counts (PKT_public_key *pk, PKT_user_id *uid) -{ - TRUSTREC trec, vrec; - ulong recno; - - if(pk==NULL || uid==NULL) - BUG(); - - namehash_from_uid(uid); - - uid->help_marginal_count=uid->help_full_count=0; - - init_trustdb (); - - if(read_trust_record (pk, &trec)!=0) - return; - - /* loop over all user IDs */ - recno = trec.r.trust.validlist; - while (recno) - { - read_record (recno, &vrec, RECTYPE_VALID); - - if(memcmp(vrec.r.valid.namehash,uid->namehash,20)==0) - { - uid->help_marginal_count=vrec.r.valid.marginal_count; - uid->help_full_count=vrec.r.valid.full_count; - /* printf("Fetched marginal %d, full %d\n",uid->help_marginal_count,uid->help_full_count); */ - break; - } - - recno = vrec.r.valid.next; - } -} - -void -list_trust_path( const char *username ) -{ -} - -/**************** - * Enumerate all keys, which are needed to build all trust paths for - * the given key. This function does not return the key itself or - * the ultimate key (the last point in cerificate chain). Only - * certificate chains which ends up at an ultimately trusted key - * are listed. If ownertrust or validity is not NULL, the corresponding - * value for the returned LID is also returned in these variable(s). - * - * 1) create a void pointer and initialize it to NULL - * 2) pass this void pointer by reference to this function. - * Set lid to the key you want to enumerate and pass it by reference. - * 3) call this function as long as it does not return -1 - * to indicate EOF. LID does contain the next key used to build the web - * 4) Always call this function a last time with LID set to NULL, - * so that it can free its context. - * - * Returns: -1 on EOF or the level of the returned LID - */ -int -enum_cert_paths( void **context, ulong *lid, - unsigned *ownertrust, unsigned *validity ) -{ - return -1; -} - - -/**************** - * Print the current path - */ -void -enum_cert_paths_print( void **context, FILE *fp, - int refresh, ulong selected_lid ) -{ - return; -} - - - -/**************************************** - *********** NEW NEW NEW **************** - ****************************************/ - -static int -ask_ownertrust (u32 *kid,int minimum) -{ - PKT_public_key *pk; - int rc; - int ot; - - pk = xcalloc (1,sizeof *pk); - rc = get_pubkey (pk, kid); - if (rc) - { - log_error (_("public key %08lX not found: %s\n"), - (ulong)kid[1], gpg_strerror (rc) ); - return TRUST_UNKNOWN; - } - - if(opt.force_ownertrust) - { - log_info("force trust for key %08lX%08lX to %s\n", - (ulong)kid[0],(ulong)kid[1], - trust_value_to_string(opt.force_ownertrust)); - update_ownertrust(pk,opt.force_ownertrust); - ot=opt.force_ownertrust; - } - else - { - ot=edit_ownertrust(pk,0); - if(ot>0) - ot = get_ownertrust (pk); - else if(ot==0) - ot = minimum?minimum:TRUST_UNDEFINED; - else - ot = -1; /* quit */ - } - - free_public_key( pk ); - - return ot; -} - - -static void -mark_keyblock_seen (KeyHashTable tbl, KBNODE node) -{ - for ( ;node; node = node->next ) - if (node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - { - u32 aki[2]; - - keyid_from_pk (node->pkt->pkt.public_key, aki); - add_key_hash_table (tbl, aki); - } -} - - -static void -dump_key_array (int depth, struct key_array *keys) -{ - struct key_array *kar; - - for (kar=keys; kar->keyblock; kar++) - { - KBNODE node = kar->keyblock; - u32 kid[2]; - - keyid_from_pk(node->pkt->pkt.public_key, kid); - printf ("%d:%08lX%08lX:K::%c::::\n", - depth, (ulong)kid[0], (ulong)kid[1], '?'); - - for (; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID) - { - int len = node->pkt->pkt.user_id->len; - - if (len > 30) - len = 30; - printf ("%d:%08lX%08lX:U:::%c:::", - depth, (ulong)kid[0], (ulong)kid[1], - (node->flag & 4)? 'f': - (node->flag & 2)? 'm': - (node->flag & 1)? 'q':'-'); - print_string (stdout, node->pkt->pkt.user_id->name, len, ':'); - putchar (':'); - putchar ('\n'); - } - } - } -} - - -static void -store_validation_status (int depth, KBNODE keyblock, KeyHashTable stored) -{ - KBNODE node; - int status; - int any = 0; - - for (node=keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID) - { - PKT_user_id *uid = node->pkt->pkt.user_id; - if (node->flag & 4) - status = TRUST_FULLY; - else if (node->flag & 2) - status = TRUST_MARGINAL; - else if (node->flag & 1) - status = TRUST_UNDEFINED; - else - status = 0; - - if (status) - { - update_validity (keyblock->pkt->pkt.public_key, - uid, depth, status); - - mark_keyblock_seen(stored,keyblock); - - any = 1; - } - } - } - - if (any) - do_sync (); -} - -/* - * check whether the signature sig is in the klist k - */ -static struct key_item * -is_in_klist (struct key_item *k, PKT_signature *sig) -{ - for (; k; k = k->next) - { - if (k->kid[0] == sig->keyid[0] && k->kid[1] == sig->keyid[1]) - return k; - } - return NULL; -} - -/* - * Mark the signature of the given UID which are used to certify it. - * To do this, we first revmove all signatures which are not valid and - * from the remain ones we look for the latest one. If this is not a - * certification revocation signature we mark the signature by setting - * node flag bit 8. Note that flag bits 9 and 10 are used for internal - * purposes. - */ -static void -mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode, - u32 *main_kid, struct key_item *klist, - u32 curtime, u32 *next_expire) -{ - KBNODE node; - PKT_signature *sig; - - /* first check all signatures */ - for (node=uidnode->next; node; node = node->next) - { - node->flag &= ~(1<<8 | 1<<9 | 1<<10); - if (node->pkt->pkttype == PKT_USER_ID - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - break; /* ready */ - if (node->pkt->pkttype != PKT_SIGNATURE) - continue; - - sig = node->pkt->pkt.signature; - if (sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1]) - continue; /* ignore self-signatures */ - if (!IS_UID_SIG(sig) && !IS_UID_REV(sig)) - continue; /* we only look at these signature classes */ - if (!is_in_klist (klist, sig)) - continue; /* no need to check it then */ - if (check_key_signature (keyblock, node, NULL)) - continue; /* ignore invalid signatures */ - node->flag |= 1<<9; - } - /* reset the remaining flags */ - for (; node; node = node->next) - node->flag &= ~(1<<8 | 1<<9 | 1 << 10); - - /* kbnode flag usage: bit 9 is here set for signatures to consider, - * bit 10 will be set by the loop to keep track of keyIDs already - * processed, bit 8 will be set for the usable signatures */ - - /* for each cert figure out the latest valid one */ - for (node=uidnode->next; node; node = node->next) - { - KBNODE n, signode; - u32 kid[2]; - u32 sigdate; - - if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - break; - if ( !(node->flag & (1<<9)) ) - continue; /* not a node to look at */ - if ( (node->flag & (1<<10)) ) - continue; /* signature with a keyID already processed */ - node->flag |= (1<<10); /* mark this node as processed */ - sig = node->pkt->pkt.signature; - signode = node; - sigdate = sig->timestamp; - kid[0] = sig->keyid[0]; kid[1] = sig->keyid[1]; - for (n=uidnode->next; n; n = n->next) - { - if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY) - break; - if ( !(n->flag & (1<<9)) ) - continue; - if ( (n->flag & (1<<10)) ) - continue; /* shortcut already processed signatures */ - sig = n->pkt->pkt.signature; - if (kid[0] != sig->keyid[0] || kid[1] != sig->keyid[1]) - continue; - n->flag |= (1<<10); /* mark this node as processed */ - - /* If signode is nonrevocable and unexpired and n isn't, - then take signode (skip). It doesn't matter which is - older: if signode was older then we don't want to take n - as signode is nonrevocable. If n was older then we're - automatically fine. */ - - if(((IS_UID_SIG(signode->pkt->pkt.signature) && - !signode->pkt->pkt.signature->flags.revocable && - (signode->pkt->pkt.signature->expiredate==0 || - signode->pkt->pkt.signature->expiredate>curtime))) && - (!(IS_UID_SIG(n->pkt->pkt.signature) && - !n->pkt->pkt.signature->flags.revocable && - (n->pkt->pkt.signature->expiredate==0 || - n->pkt->pkt.signature->expiredate>curtime)))) - continue; - - /* If n is nonrevocable and unexpired and signode isn't, - then take n. Again, it doesn't matter which is older: if - n was older then we don't want to take signode as n is - nonrevocable. If signode was older then we're - automatically fine. */ - - if((!(IS_UID_SIG(signode->pkt->pkt.signature) && - !signode->pkt->pkt.signature->flags.revocable && - (signode->pkt->pkt.signature->expiredate==0 || - signode->pkt->pkt.signature->expiredate>curtime))) && - ((IS_UID_SIG(n->pkt->pkt.signature) && - !n->pkt->pkt.signature->flags.revocable && - (n->pkt->pkt.signature->expiredate==0 || - n->pkt->pkt.signature->expiredate>curtime)))) - { - signode = n; - sigdate = sig->timestamp; - continue; - } - - /* At this point, if it's newer, it goes in as the only - remaining possibilities are signode and n are both either - revocable or expired or both nonrevocable and unexpired. - If the timestamps are equal take the later ordered - packet, presuming that the key packets are hopefully in - their original order. */ - - if (sig->timestamp >= sigdate) - { - signode = n; - sigdate = sig->timestamp; - } - } - sig = signode->pkt->pkt.signature; - if (IS_UID_SIG (sig)) - { /* this seems to be a usable one which is not revoked. - * Just need to check whether there is an expiration time, - * We do the expired certification after finding a suitable - * certification, the assumption is that a signator does not - * want that after the expiration of his certificate the - * system falls back to an older certification which has a - * different expiration time */ - const byte *p; - u32 expire; - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL ); - expire = p? sig->timestamp + buffer_to_u32(p) : 0; - - if (expire==0 || expire > curtime ) - { - signode->flag |= (1<<8); /* yeah, found a good cert */ - if (expire && expire < *next_expire) - *next_expire = expire; - } - } - } -} - -/* Used by validate_one_keyblock to confirm a regexp within a trust - signature. Returns 1 for match, and 0 for no match or regex - error. */ -static int -check_regexp(const char *expr,const char *string) -{ -#ifdef DISABLE_REGEX - /* When DISABLE_REGEX is defined, assume all regexps do not - match. */ - return 0; -#elif defined(__riscos__) - return riscos_check_regexp(expr, string, DBG_TRUST); -#else - int ret; - regex_t pat; - - if(regcomp(&pat,expr,REG_ICASE|REG_NOSUB|REG_EXTENDED)!=0) - return 0; - - ret=regexec(&pat,string,0,NULL,0); - - regfree(&pat); - - if(DBG_TRUST) - log_debug("regexp \"%s\" on \"%s\": %s\n",expr,string,ret==0?"YES":"NO"); - - return (ret==0); -#endif -} - -/* - * Return true if the key is signed by one of the keys in the given - * key ID list. User IDs with a valid signature are marked by node - * flags as follows: - * flag bit 0: There is at least one signature - * 1: There is marginal confidence that this is a legitimate uid - * 2: There is full confidence that this is a legitimate uid. - * 8: Used for internal purposes. - * 9: Ditto (in mark_usable_uid_certs()) - * 10: Ditto (ditto) - * This function assumes that all kbnode flags are cleared on entry. - */ -static int -validate_one_keyblock (KBNODE kb, struct key_item *klist, - u32 curtime, u32 *next_expire) -{ - struct key_item *kr; - KBNODE node, uidnode=NULL; - PKT_user_id *uid=NULL; - PKT_public_key *pk = kb->pkt->pkt.public_key; - u32 main_kid[2]; - int issigned=0, any_signed = 0; - - keyid_from_pk(pk, main_kid); - for (node=kb; node; node = node->next) - { - /* A bit of discussion here: is it better for the web of trust - to be built among only self-signed uids? On the one hand, a - self-signed uid is a statement that the key owner definitely - intended that uid to be there, but on the other hand, a - signed (but not self-signed) uid does carry trust, of a sort, - even if it is a statement being made by people other than the - key owner "through" the uids on the key owner's key. I'm - going with the latter. However, if the user ID was - explicitly revoked, or passively allowed to expire, that - should stop validity through the user ID until it is - resigned. -dshaw */ - - if (node->pkt->pkttype == PKT_USER_ID - && !node->pkt->pkt.user_id->is_revoked - && !node->pkt->pkt.user_id->is_expired) - { - if (uidnode && issigned) - { - if (uid->help_full_count >= opt.completes_needed - || uid->help_marginal_count >= opt.marginals_needed ) - uidnode->flag |= 4; - else if (uid->help_full_count || uid->help_marginal_count) - uidnode->flag |= 2; - uidnode->flag |= 1; - any_signed = 1; - } - uidnode = node; - uid=uidnode->pkt->pkt.user_id; - - /* If the selfsig is going to expire... */ - if(uid->expiredate && uid->expiredate<*next_expire) - *next_expire = uid->expiredate; - - issigned = 0; - get_validity_counts(pk,uid); - mark_usable_uid_certs (kb, uidnode, main_kid, klist, - curtime, next_expire); - } - else if (node->pkt->pkttype == PKT_SIGNATURE - && (node->flag & (1<<8)) && uid) - { - /* Note that we are only seeing unrevoked sigs here */ - PKT_signature *sig = node->pkt->pkt.signature; - - kr = is_in_klist (klist, sig); - /* If the trust_regexp does not match, it's as if the sig - did not exist. This is safe for non-trust sigs as well - since we don't accept a regexp on the sig unless it's a - trust sig. */ - if (kr && (kr->trust_regexp==NULL || opt.trust_model!=TM_PGP || - (uidnode && check_regexp(kr->trust_regexp, - uidnode->pkt->pkt.user_id->name)))) - { - if(DBG_TRUST && opt.trust_model==TM_PGP && sig->trust_depth) - log_debug("trust sig on %s, sig depth is %d, kr depth is %d\n", - uidnode->pkt->pkt.user_id->name,sig->trust_depth, - kr->trust_depth); - - /* Are we part of a trust sig chain? We always favor - the latest trust sig, rather than the greater or - lesser trust sig or value. I could make a decent - argument for any of these cases, but this seems to be - what PGP does, and I'd like to be compatible. -dms */ - if(opt.trust_model==TM_PGP && sig->trust_depth - && pk->trust_timestamp<=sig->timestamp - && (sig->trust_depth<=kr->trust_depth - || kr->ownertrust==TRUST_ULTIMATE)) - { - /* If we got here, we know that: - - this is a trust sig. - - it's a newer trust sig than any previous trust - sig on this key (not uid). - - it is legal in that it was either generated by an - ultimate key, or a key that was part of a trust - chain, and the depth does not violate the - original trust sig. - - if there is a regexp attached, it matched - successfully. - */ - - if(DBG_TRUST) - log_debug("replacing trust value %d with %d and " - "depth %d with %d\n", - pk->trust_value,sig->trust_value, - pk->trust_depth,sig->trust_depth); - - pk->trust_value=sig->trust_value; - pk->trust_depth=sig->trust_depth-1; - - /* If the trust sig contains a regexp, record it - on the pk for the next round. */ - if(sig->trust_regexp) - pk->trust_regexp=sig->trust_regexp; - } - - if (kr->ownertrust == TRUST_ULTIMATE) - uid->help_full_count = opt.completes_needed; - else if (kr->ownertrust == TRUST_FULLY) - uid->help_full_count++; - else if (kr->ownertrust == TRUST_MARGINAL) - uid->help_marginal_count++; - issigned = 1; - } - } - } - - if (uidnode && issigned) - { - if (uid->help_full_count >= opt.completes_needed - || uid->help_marginal_count >= opt.marginals_needed ) - uidnode->flag |= 4; - else if (uid->help_full_count || uid->help_marginal_count) - uidnode->flag |= 2; - uidnode->flag |= 1; - any_signed = 1; - } - - return any_signed; -} - - -static int -search_skipfnc (void *opaque, u32 *kid) -{ - return test_key_hash_table ((KeyHashTable)opaque, kid); -} - - -/* - * Scan all keys and return a key_array of all suitable keys from - * kllist. The caller has to pass keydb handle so that we don't use - * to create our own. Returns either a key_array or NULL in case of - * an error. No results found are indicated by an empty array. - * Caller hast to release the returned array. - */ -static struct key_array * -validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust, - struct key_item *klist, u32 curtime, u32 *next_expire) -{ - KBNODE keyblock = NULL; - struct key_array *keys = NULL; - size_t nkeys, maxkeys; - int rc; - KEYDB_SEARCH_DESC desc; - - maxkeys = 1000; - keys = xmalloc ((maxkeys+1) * sizeof *keys); - nkeys = 0; - - rc = keydb_search_reset (hd); - if (rc) - { - log_error ("keydb_search_reset failed: %s\n", gpg_strerror (rc)); - xfree (keys); - return NULL; - } - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FIRST; - desc.skipfnc = search_skipfnc; - desc.skipfncvalue = full_trust; - rc = keydb_search (hd, &desc, 1); - if (rc == -1) - { - keys[nkeys].keyblock = NULL; - return keys; - } - if (rc) - { - log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc)); - xfree (keys); - return NULL; - } - - desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */ - do - { - PKT_public_key *pk; - - rc = keydb_get_keyblock (hd, &keyblock); - if (rc) - { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - xfree (keys); - return NULL; - } - - if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY) - { - log_debug ("ooops: invalid pkttype %d encountered\n", - keyblock->pkt->pkttype); - dump_kbnode (keyblock); - release_kbnode(keyblock); - continue; - } - - /* prepare the keyblock for further processing */ - merge_keys_and_selfsig (keyblock); - clear_kbnode_flags (keyblock); - pk = keyblock->pkt->pkt.public_key; - if (pk->has_expired || pk->is_revoked) - { - /* it does not make sense to look further at those keys */ - mark_keyblock_seen (full_trust, keyblock); - } - else if (validate_one_keyblock (keyblock, klist, curtime, next_expire)) - { - KBNODE node; - - if (pk->expiredate && pk->expiredate >= curtime - && pk->expiredate < *next_expire) - *next_expire = pk->expiredate; - - if (nkeys == maxkeys) { - maxkeys += 1000; - keys = xrealloc (keys, (maxkeys+1) * sizeof *keys); - } - keys[nkeys++].keyblock = keyblock; - - /* Optimization - if all uids are fully trusted, then we - never need to consider this key as a candidate again. */ - - for (node=keyblock; node; node = node->next) - if (node->pkt->pkttype == PKT_USER_ID && !(node->flag & 4)) - break; - - if(node==NULL) - mark_keyblock_seen (full_trust, keyblock); - - keyblock = NULL; - } - - release_kbnode (keyblock); - keyblock = NULL; - } - while ( !(rc = keydb_search (hd, &desc, 1)) ); - if (rc && rc != -1) - { - log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc)); - xfree (keys); - return NULL; - } - - keys[nkeys].keyblock = NULL; - return keys; -} - -/* Caller must sync */ -static void -reset_trust_records (KEYDB_HANDLE hd, KeyHashTable exclude) -{ - int rc; - KBNODE keyblock = NULL; - KEYDB_SEARCH_DESC desc; - int count = 0, nreset = 0; - - rc = keydb_search_reset (hd); - if (rc) - { - log_error ("keydb_search_reset failed: %s\n", gpg_strerror (rc)); - return; - } - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FIRST; - if(exclude) - { - desc.skipfnc = search_skipfnc; - desc.skipfncvalue = exclude; - } - rc = keydb_search (hd, &desc, 1); - if (rc && rc != -1 ) - log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc)); - else if (!rc) - { - desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */ - do - { - rc = keydb_get_keyblock (hd, &keyblock); - if (rc) - { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - break; - } - count++; - - if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY) /* paranoid assertion*/ - { - nreset += clear_validity (keyblock->pkt->pkt.public_key); - release_kbnode (keyblock); - } - } - while ( !(rc = keydb_search (hd, &desc, 1)) ); - if (rc && rc != -1) - log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc)); - } - if (opt.verbose) - log_info (_("%d keys processed (%d validity counts cleared)\n"), - count, nreset); -} - -/* - * Run the key validation procedure. - * - * This works this way: - * Step 1: Find all ultimately trusted keys (UTK). - * mark them all as seen and put them into klist. - * Step 2: loop max_cert_times - * Step 3: if OWNERTRUST of any key in klist is undefined - * ask user to assign ownertrust - * Step 4: Loop over all keys in the keyDB which are not marked seen - * Step 5: if key is revoked or expired - * mark key as seen - * continue loop at Step 4 - * Step 6: For each user ID of that key signed by a key in klist - * Calculate validity by counting trusted signatures. - * Set validity of user ID - * Step 7: If any signed user ID was found - * mark key as seen - * End Loop - * Step 8: Build a new klist from all fully trusted keys from step 6 - * End Loop - * Ready - * - */ -static int -validate_keys (int interactive) -{ - int rc = 0; - int quit=0; - struct key_item *klist = NULL; - struct key_item *k; - struct key_array *keys = NULL; - struct key_array *kar; - KEYDB_HANDLE kdb = NULL; - KBNODE node; - int depth; - int key_count; - int ot_unknown, ot_undefined, ot_never, ot_marginal, ot_full, ot_ultimate; - KeyHashTable stored,used,full_trust; - u32 start_time, next_expire; - - start_time = make_timestamp (); - next_expire = 0xffffffff; /* set next expire to the year 2106 */ - stored = new_key_hash_table (); - used = new_key_hash_table (); - full_trust = new_key_hash_table (); - /* Fixme: Instead of always building a UTK list, we could just build it - * here when needed */ - if (!utk_list) - { - log_info (_("no ultimately trusted keys found\n")); - goto leave; - } - - kdb = keydb_new (0); - - reset_trust_records (kdb,NULL); - - /* mark all UTKs as used and fully_trusted and set validity to - ultimate */ - for (k=utk_list; k; k = k->next) - { - KBNODE keyblock; - PKT_public_key *pk; - - keyblock = get_pubkeyblock (k->kid); - if (!keyblock) - { - log_error (_("public key of ultimately" - " trusted key %08lX not found\n"), (ulong)k->kid[1]); - continue; - } - mark_keyblock_seen (used, keyblock); - mark_keyblock_seen (stored, keyblock); - mark_keyblock_seen (full_trust, keyblock); - pk = keyblock->pkt->pkt.public_key; - for (node=keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID) - update_validity (pk, node->pkt->pkt.user_id, 0, TRUST_ULTIMATE); - } - if ( pk->expiredate && pk->expiredate >= start_time - && pk->expiredate < next_expire) - next_expire = pk->expiredate; - - release_kbnode (keyblock); - do_sync (); - } - - klist = utk_list; - - log_info(_("%d marginal(s) needed, %d complete(s) needed, %s trust model\n"), - opt.marginals_needed,opt.completes_needed,trust_model_string()); - - for (depth=0; depth < opt.max_cert_depth; depth++) - { - /* See whether we should assign ownertrust values to the keys in - utk_list. */ - ot_unknown = ot_undefined = ot_never = 0; - ot_marginal = ot_full = ot_ultimate = 0; - for (k=klist; k; k = k->next) - { - int min=0; - - /* 120 and 60 are as per RFC2440 */ - if(k->trust_value>=120) - min=TRUST_FULLY; - else if(k->trust_value>=60) - min=TRUST_MARGINAL; - - if(min!=k->min_ownertrust) - update_min_ownertrust(k->kid,min); - - if (interactive && k->ownertrust == TRUST_UNKNOWN) - { - k->ownertrust = ask_ownertrust (k->kid,min); - - if (k->ownertrust == -1) - { - quit=1; - goto leave; - } - } - - /* This can happen during transition from an old trustdb - before trust sigs. It can also happen if a user uses two - different versions of GnuPG or changes the --trust-model - setting. */ - if(k->ownertrust<min) - { - if(DBG_TRUST) - log_debug("key %08lX: " - "overriding ownertrust \"%s\" with \"%s\"\n", - (ulong)k->kid[1], - trust_value_to_string(k->ownertrust), - trust_value_to_string(min)); - - k->ownertrust=min; - } - - if (k->ownertrust == TRUST_UNKNOWN) - ot_unknown++; - else if (k->ownertrust == TRUST_UNDEFINED) - ot_undefined++; - else if (k->ownertrust == TRUST_NEVER) - ot_never++; - else if (k->ownertrust == TRUST_MARGINAL) - ot_marginal++; - else if (k->ownertrust == TRUST_FULLY) - ot_full++; - else if (k->ownertrust == TRUST_ULTIMATE) - ot_ultimate++; - } - - /* Find all keys which are signed by a key in kdlist */ - keys = validate_key_list (kdb, full_trust, klist, - start_time, &next_expire); - if (!keys) - { - log_error ("validate_key_list failed\n"); - rc = GPG_ERR_GENERAL; - goto leave; - } - - for (key_count=0, kar=keys; kar->keyblock; kar++, key_count++) - ; - - /* Store the calculated valididation status somewhere */ - if (opt.verbose > 1) - dump_key_array (depth, keys); - - for (kar=keys; kar->keyblock; kar++) - store_validation_status (depth, kar->keyblock, stored); - - log_info (_("checking at depth %d valid=%d" - " ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n"), - depth, key_count, ot_unknown, ot_undefined, - ot_never, ot_marginal, ot_full, ot_ultimate ); - - /* Build a new kdlist from all fully valid keys in KEYS */ - if (klist != utk_list) - release_key_items (klist); - klist = NULL; - for (kar=keys; kar->keyblock; kar++) - { - for (node=kar->keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID && (node->flag & 4)) - { - u32 kid[2]; - - /* have we used this key already? */ - keyid_from_pk (kar->keyblock->pkt->pkt.public_key, kid); - if(test_key_hash_table(used,kid)==0) - { - /* Normally we add both the primary and subkey - ids to the hash via mark_keyblock_seen, but - since we aren't using this hash as a skipfnc, - that doesn't matter here. */ - add_key_hash_table (used,kid); - k = new_key_item (); - k->kid[0]=kid[0]; - k->kid[1]=kid[1]; - k->ownertrust = - (get_ownertrust (kar->keyblock->pkt->pkt.public_key) - & TRUST_MASK); - k->min_ownertrust = - get_min_ownertrust(kar->keyblock->pkt->pkt.public_key); - k->trust_depth= - kar->keyblock->pkt->pkt.public_key->trust_depth; - k->trust_value= - kar->keyblock->pkt->pkt.public_key->trust_value; - if(kar->keyblock->pkt->pkt.public_key->trust_regexp) - k->trust_regexp= - xstrdup (kar->keyblock->pkt-> - pkt.public_key->trust_regexp); - k->next = klist; - klist = k; - break; - } - } - } - } - release_key_array (keys); - keys = NULL; - if (!klist) - break; /* no need to dive in deeper */ - } - - leave: - keydb_release (kdb); - release_key_array (keys); - release_key_items (klist); - release_key_hash_table (full_trust); - release_key_hash_table (used); - release_key_hash_table (stored); - if (!rc && !quit) /* mark trustDB as checked */ - { - if (next_expire == 0xffffffff || next_expire < start_time ) - tdbio_write_nextcheck (0); - else - { - tdbio_write_nextcheck (next_expire); - log_info (_("next trustdb check due at %s\n"), - strtimestamp (next_expire)); - } - - if(tdbio_update_version_record()!=0) - { - log_error(_("unable to update trustdb version record: " - "write failed: %s\n"), gpg_strerror (rc)); - tdbio_invalid(); - } - - do_sync (); - pending_check_trustdb = 0; - } - - return rc; -} diff --git a/g10/trustdb.h b/g10/trustdb.h deleted file mode 100644 index 414c37702..000000000 --- a/g10/trustdb.h +++ /dev/null @@ -1,86 +0,0 @@ -/* trustdb.h - Trust database - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 - * Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_TRUSTDB_H -#define G10_TRUSTDB_H - - -/* Trust values must be sorted in ascending order */ -#define TRUST_MASK 15 -#define TRUST_UNKNOWN 0 /* o: not yet calculated/assigned */ -#define TRUST_EXPIRED 1 /* e: calculation may be invalid */ -#define TRUST_UNDEFINED 2 /* q: not enough information for calculation */ -#define TRUST_NEVER 3 /* n: never trust this pubkey */ -#define TRUST_MARGINAL 4 /* m: marginally trusted */ -#define TRUST_FULLY 5 /* f: fully trusted */ -#define TRUST_ULTIMATE 6 /* u: ultimately trusted */ -/* trust values not covered by the mask */ -#define TRUST_FLAG_REVOKED 32 /* r: revoked */ -#define TRUST_FLAG_SUB_REVOKED 64 /* r: revoked but for subkeys */ -#define TRUST_FLAG_DISABLED 128 /* d: key/uid disabled */ -#define TRUST_FLAG_PENDING_CHECK 256 /* a check-trustdb is pending */ - -/*-- trustdb.c --*/ -void register_trusted_key( const char *string ); -void check_trustdb (void); -void update_trustdb (void); -int setup_trustdb( int level, const char *dbname ); -void init_trustdb( void ); -void sync_trustdb( void ); - -const char *trust_value_to_string (unsigned int value); -int string_to_trust_value (const char *str); - -void revalidation_mark (void); -int trustdb_pending_check(void); - -int cache_disabled_value(PKT_public_key *pk); - -unsigned int get_validity (PKT_public_key *pk, PKT_user_id *uid); -int get_validity_info (PKT_public_key *pk, PKT_user_id *uid); -const char *get_validity_string (PKT_public_key *pk, PKT_user_id *uid); - -void list_trust_path( const char *username ); -int enum_cert_paths( void **context, ulong *lid, - unsigned *ownertrust, unsigned *validity ); -void enum_cert_paths_print( void **context, FILE *fp, - int refresh, ulong selected_lid ); - -void read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck, - byte *marginals,byte *completes,byte *cert_depth); - -unsigned int get_ownertrust (PKT_public_key *pk); -unsigned int get_min_ownertrust (PKT_public_key *pk); -int get_ownertrust_info (PKT_public_key *pk); -const char *get_ownertrust_string (PKT_public_key *pk); - -void update_ownertrust (PKT_public_key *pk, unsigned int new_trust ); -int clear_ownertrusts (PKT_public_key *pk); - -/*-- tdbdump.c --*/ -void list_trustdb(const char *username); -void export_ownertrust(void); -void import_ownertrust(const char *fname); - -/*-- pkclist.c --*/ -int edit_ownertrust (PKT_public_key *pk, int mode ); - -#endif /*G10_TRUSTDB_H*/ diff --git a/g10/verify.c b/g10/verify.c deleted file mode 100644 index cfa373637..000000000 --- a/g10/verify.c +++ /dev/null @@ -1,197 +0,0 @@ -/* verify.c - verify signed data - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <unistd.h> /* for isatty() */ - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "status.h" -#include "filter.h" -#include "ttyio.h" -#include "i18n.h" - - - -/**************** - * Assume that the input is a signature and verify it 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 from stdin. With more than 1 argument, the first should - * be a detached signature and the remaining files are the signed stuff. - */ - -int -verify_signatures( int nfiles, char **files ) -{ - iobuf_t fp; - armor_filter_context_t afx; - progress_filter_context_t pfx; - const char *sigfile; - int i, rc; - STRLIST sl; - - memset( &afx, 0, sizeof afx); - /* decide whether we should handle a detached or a normal signature, - * which is needed so that the code later can hash the correct data and - * not have a normal signature act as detached signature and ignoring the - * indended signed material from the 2nd file or stdin. - * 1. gpg <file - normal - * 2. gpg file - normal (or detached) - * 3. gpg file <file2 - detached - * 4. gpg file file2 - detached - * The question is how decide between case 2 and 3? The only way - * we can do it is by reading one byte from stdin and the unget - * it; the problem here is that we may be reading from the - * terminal (which could be detected using isatty() but won't work - * when under contol of a pty using program (e.g. expect)) and - * might get us in trouble when stdin is used for another purpose - * (--passphrase-fd 0). So we have to break with the behaviour - * prior to gpg 1.0.4 by assuming that case 3 is a normal - * signature (where file2 is ignored and require for a detached - * signature to indicate signed material comes from stdin by using - * case 4 with a file2 of "-". - * - * Actually we don't have to change anything here but can handle - * that all quite easily in mainproc.c - */ - - - sigfile = nfiles? *files : NULL; - - /* open the signature file */ - fp = iobuf_open(sigfile); - if( !fp ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't open `%s': %s\n"), - print_fname_stdin(sigfile), strerror (errno)); - return rc; - } - handle_progress (&pfx, fp, sigfile); - - if( !opt.no_armor && use_armor_filter( fp ) ) - iobuf_push_filter( fp, armor_filter, &afx ); - - sl = NULL; - for(i=1 ; i < nfiles; i++ ) - add_to_strlist( &sl, files[i] ); - rc = proc_signature_packets( NULL, fp, sl, sigfile ); - free_strlist(sl); - iobuf_close(fp); - if( afx.no_openpgp_data && rc == -1 ) { - log_error(_("the signature could not be verified.\n" - "Please remember that the signature file (.sig or .asc)\n" - "should be the first file given on the command line.\n") ); - rc = 0; - } - - return rc; -} - - -void -print_file_status( int status, const char *name, int what ) -{ - char *p = xmalloc (strlen(name)+10); - sprintf(p, "%d %s", what, name ); - write_status_text( status, p ); - xfree (p); -} - - -static int -verify_one_file( const char *name ) -{ - iobuf_t fp; - armor_filter_context_t afx; - progress_filter_context_t pfx; - int rc; - - print_file_status( STATUS_FILE_START, name, 1 ); - fp = iobuf_open(name); - if( !fp ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't open `%s': %s\n"), - print_fname_stdin(name), strerror (errno)); - print_file_status( STATUS_FILE_ERROR, name, 1 ); - return rc; - } - handle_progress (&pfx, fp, name); - - if( !opt.no_armor ) { - if( use_armor_filter( fp ) ) { - memset( &afx, 0, sizeof afx); - iobuf_push_filter( fp, armor_filter, &afx ); - } - } - - rc = proc_signature_packets( NULL, fp, NULL, name ); - iobuf_close(fp); - write_status( STATUS_FILE_DONE ); - return rc; -} - -/**************** - * Verify each file given in the files array or read the names of the - * files from stdin. - * Note: This function can not handle detached signatures. - */ -int -verify_files( int nfiles, char **files ) -{ - int i; - - if( !nfiles ) { /* read the filenames from stdin */ - char line[2048]; - unsigned int lno = 0; - - while( fgets(line, DIM(line), stdin) ) { - lno++; - if( !*line || line[strlen(line)-1] != '\n' ) { - log_error(_("input line %u too long or missing LF\n"), lno ); - return GPG_ERR_GENERAL; - } - /* This code does not work on MSDOS but how cares there are - * also no script languages available. We don't strip any - * spaces, so that we can process nearly all filenames */ - line[strlen(line)-1] = 0; - verify_one_file( line ); - } - - } - else { /* take filenames from the array */ - for(i=0; i < nfiles; i++ ) - verify_one_file( files[i] ); - } - return 0; -} diff --git a/include/ChangeLog b/include/ChangeLog deleted file mode 100644 index 5b343f5a0..000000000 --- a/include/ChangeLog +++ /dev/null @@ -1,403 +0,0 @@ -2003-09-04 David Shaw <dshaw@jabberwocky.com> - - * cipher.h: Drop TIGER/192 support. - - * types.h: Prefer using uint64_t when creating a 64-bit unsigned - type. This avoids a warning on compilers that support but complain - about unsigned long long. - - * util.h: Make sure that only ascii is passed to isfoo - functions. (From Werner on stable branch). - -2003-09-04 Werner Koch <wk@gnupg.org> - - * cipher.h (PUBKEY_USAGE_AUTH): Added. - -2003-07-03 Werner Koch <wk@gnupg.org> - - * cipher.h (DBG_CIPHER,g10c_debug_mode): Removed. - -2003-06-11 Werner Koch <wk@gnupg.org> - - * cipher.h: Include gcrypt.h and mapped cipher algo names to - gcrypt ones. Removed twofish_old and skipjack. Removed all - handle definitions and other raerely used stuff. This file will - eventually be entirely removed. - -2003-06-10 Werner Koch <wk@gnupg.org> - - * types.h (struct strlist): Removed. - -2003-05-24 David Shaw <dshaw@jabberwocky.com> - - * cipher.h, i18n.h, iobuf.h, memory.h, mpi.h, types.h, util.h: - Edit all preprocessor instructions to remove whitespace before the - '#'. This is not required by C89, but there are some compilers - out there that don't like it. - -2003-05-14 David Shaw <dshaw@jabberwocky.com> - - * types.h: Add initializer macros for 64-bit unsigned type. - -2003-05-02 David Shaw <dshaw@jabberwocky.com> - - * cipher.h: Add constants for compression algorithms. - -2003-03-11 David Shaw <dshaw@jabberwocky.com> - - * http.h: Add HTTP_FLAG_TRY_SRV. - -2003-02-11 David Shaw <dshaw@jabberwocky.com> - - * types.h: Try and use uint64_t for a 64-bit type. - -2003-02-04 David Shaw <dshaw@jabberwocky.com> - - * cipher.h: Add constants for new SHAs. - -2002-11-13 David Shaw <dshaw@jabberwocky.com> - - * util.h [__CYGWIN32__]: Don't need the registry prototypes. From - Werner on stable branch. - -2002-11-06 David Shaw <dshaw@jabberwocky.com> - - * util.h: Add wipememory2() macro (same as wipememory, but can - specify the byte to wipe with). - -2002-10-31 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Prefixed all RISC OS prototypes with - riscos_* - - * zlib-riscos.h: New. This is macro magic in order to make the - zlib library calls indeed call the RISC OS ZLib module. - -2002-10-31 David Shaw <dshaw@jabberwocky.com> - - * util.h: Add wipememory() macro. - -2002-10-29 Stefan Bellon <sbellon@sbellon.de> - - * util.h: Added parameter argument to make_basename() needed for - filetype support. - [__riscos__]: Added prototype. - -2002-10-28 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Added prototypes for new filetype support. - -2002-10-19 David Shaw <dshaw@jabberwocky.com> - - * distfiles, _regex.h: Add _regex.h from glibc 2.3.1. - -2002-10-14 David Shaw <dshaw@jabberwocky.com> - - * keyserver.h: Go to KEYSERVER_PROTO_VERSION 1. - -2002-10-08 David Shaw <dshaw@jabberwocky.com> - - * keyserver.h: Add new error code KEYSERVER_UNREACHABLE. - -2002-10-03 David Shaw <dshaw@jabberwocky.com> - - * util.h: Add new log_warning logger command which can be switched - between log_info and log_error via log_set_strict. - -2002-09-24 David Shaw <dshaw@jabberwocky.com> - - * keyserver.h: Add some new error codes for better GPA support. - -2002-09-10 Werner Koch <wk@gnupg.org> - - * mpi.h (mpi_is_protected, mpi_set_protect_flag) - (mpi_clear_protect_flag): Removed. - (mpi_get_nbit_info, mpi_set_nbit_info): Removed. - -2002-08-13 David Shaw <dshaw@jabberwocky.com> - - * cipher.h: Add AES aliases for RIJNDAEL algo numbers. - -2002-08-07 David Shaw <dshaw@jabberwocky.com> - - * cipher.h: Add md_algo_present(). - -2002-08-06 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Added riscos_getchar(). - -2002-06-21 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Further moving away of RISC OS specific - stuff from general code. - -2002-06-20 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Added riscos_set_filetype(). - -2002-06-14 David Shaw <dshaw@jabberwocky.com> - - * util.h: Add pop_strlist() from strgutil.c. - -2002-06-07 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: RISC OS needs strings.h for strcasecmp() - and strncasecmp(). - -2002-05-22 Werner Koch <wk@gnupg.org> - - * util.h: Add strncasecmp. Removed stricmp and memicmp. - -2002-05-10 Stefan Bellon <sbellon@sbellon.de> - - * mpi.h: New function mpi_debug_alloc_like for M_DEBUG. - - * util.h [__riscos__]: Make use of __func__ that later - Norcroft compiler provides. - - * memory.h: Fixed wrong definition of m_alloc_secure_clear. - -2002-04-23 David Shaw <dshaw@jabberwocky.com> - - * util.h: New function answer_is_yes_no_default() to give a - default answer. - -2002-04-22 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Removed riscos_open, riscos_fopen and - riscos_fstat as those special versions aren't needed anymore. - -2002-02-19 David Shaw <dshaw@jabberwocky.com> - - * keyserver.h: Add KEYSERVER_NOT_SUPPORTED for unsupported actions - (say, a keyserver that has no way to search, or a readonly - keyserver that has no way to add). - -2002-01-02 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Updated prototype list. - - * types.h [__riscos__]: Changed comment wording. - -2001-12-27 David Shaw <dshaw@jabberwocky.com> - - * KEYSERVER_SCHEME_NOT_FOUND should be 127 to match the POSIX - system() (via /bin/sh) way of signaling this. - - * Added G10ERR_KEYSERVER - -2001-12-27 Werner Koch <wk@gnupg.org> - - * util.h [MINGW32]: Fixed name of include file. - -2001-12-22 Timo Schulz <ts@winpt.org> - - * util.h (is_file_compressed): New. - -2001-12-19 Werner Koch <wk@gnupg.org> - - * util.h [CYGWIN32]: Allow this as an alias for MINGW32. Include - stdarg.h becuase we use the va_list type. By Disastry. - -2001-09-28 Werner Koch <wk@gnupg.org> - - * cipher.h (PUBKEY_USAGE_CERT): New. - -2001-09-07 Werner Koch <wk@gnupg.org> - - * util.h: Add strsep(). - -2001-08-30 Werner Koch <wk@gnupg.org> - - * cipher.h (DEK): Added use_mdc. - -2001-08-24 Werner Koch <wk@gnupg.org> - - * cipher.h (md_write): Made buf arg const. - -2001-08-20 Werner Koch <wk@gnupg.org> - - * cipher.h (DEK): Added algo_info_printed; - - * util.h [__riscos__]: Added prototypes and made sure that we - never use __attribute__. - * cipher.h, iobuf.h, memory.h, mpi.h [__riscos__]: extern hack. - * i18n.h [__riscos__]: Use another include file - -2001-05-30 Werner Koch <wk@gnupg.org> - - * ttyio.h (tty_printf): Add missing parenthesis for non gcc. - * http.h: Removed trailing comma to make old ccs happy. Both are - by Albert Chin. - -2001-05-25 Werner Koch <wk@gnupg.org> - - * ttyio.h (tty_printf): Add printf attribute. - -2001-04-23 Werner Koch <wk@gnupg.org> - - * http.h: New flag HTTP_FLAG_NO_SHUTDOWN. - -2001-04-13 Werner Koch <wk@gnupg.org> - - * iobuf.h: Removed iobuf_fopen. - -2001-03-01 Werner Koch <wk@gnupg.org> - - * errors.h (G10ERR_UNU_SECKEY,G10ERR_UNU_PUBKEY): New - -2000-11-30 Werner Koch <wk@gnupg.org> - - * iobuf.h (iobuf_translate_file_handle): Add prototype. - -2000-11-11 Paul Eggert <eggert@twinsun.com> - - * iobuf.h (iobuf_get_filelength): Now returns off_t, not u32. - (struct iobuf_struct, iobuf_set_limit, - iobuf_tell, iobuf_seek): Use off_t, not ulong, for file offsets. - -2000-10-12 Werner Koch <wk@gnupg.org> - - * mpi.h: Changed the way mpi_limb_t is defined. - -Wed Sep 6 17:55:47 CEST 2000 Werner Koch <wk@openit.de> - - * iobuf.c (IOBUF_FILELENGTH_LIMIT): New. - -2000-03-14 14:03:43 Werner Koch (wk@habibti.openit.de) - - * types.h (HAVE_U64_TYPEDEF): Defined depending on configure test. - -Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de> - - * types.h (HAVE_U64_TYPEDEF): Add a test for _LONGLONG which fixes - this long living SGI bug. Reported by Alec Habig. - -Sat Dec 4 12:30:28 CET 1999 Werner Koch <wk@gnupg.de> - - * iobuf.h (IOBUFCTRL_CANCEL): Nww. - -Mon Oct 4 21:23:04 CEST 1999 Werner Koch <wk@gnupg.de> - - * errors.h (G10ERR_NOT_PROCESSED): New. - -Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * i18n.h: Add support for simple-gettext. - -Tue Jun 29 21:44:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * util.h (stricmp): Use strcasecmp as replacement. - -Sat Jun 26 12:15:59 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * cipher.h (MD_HANDLE): Assigned a structure name. - -Fri Apr 9 12:26:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * cipher.h (BLOWFISH160): Removed. - -Tue Apr 6 19:58:12 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * cipher.h (DEK): increased max. key length to 32 bytes - - -Sat Feb 20 21:40:49 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10lib.h: Removed file and changed all files that includes this. - -Tue Feb 16 14:10:02 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * types.h (STRLIST): Add field flags. - -Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * cipher.h (CIPHER_ALGO_TWOFISH): Chnaged ID to 10 and renamed - the old experimenatl algorithm to xx_OLD. - -Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * cipher.h (MD_BUFFER_SIZE): Removed. - -Mon Dec 14 21:18:49 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * types.h: fix for SUNPRO_C - -Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * mpi.h (MPI): Changed the structure name to gcry_mpi and - changed all users. - -Tue Oct 20 11:40:00 1998 Werner Koch (wk@isil.d.shuttle.de) - - * iobuf.h (iobuf_get_temp_buffer): New. - -Tue Oct 13 12:40:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * iobuf.h (iobuf_get): Now uses .nofast - (iobuf_get2): Removed. - -Mon Sep 14 09:17:22 1998 Werner Koch (wk@(none)) - - * util.h (HAVE_ATEXIT): New. - (HAVE_RAISE): New. - -Mon Jul 6 10:41:55 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h (PUBKEY_USAGE_): New. - -Mon Jul 6 09:49:51 1998 Werner Koch (wk@isil.d.shuttle.de) - - * iobuf.h (iobuf_set_error): New. - (iobuf_error): New. - -Sat Jun 13 17:31:32 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10lib.h: New as interface for the g10lib. - -Mon Jun 8 22:14:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h (CIPHER_ALGO_CAST5): Changed name from .. CAST - -Thu May 21 13:25:51 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h: removed ROT 5 and changed one id and add dummy - -Tue May 19 18:09:05 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h (DIGEST_ALGO_TIGER): Chnaged id from 101 to 6. - -Mon May 4 16:37:17 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h (PUBKEY_ALGO_ELGAMAL_E): New, with value of the - old one. - * (is_ELGAMAL, is_RSA): New macros - -Sun Apr 26 14:35:24 1998 Werner Koch (wk@isil.d.shuttle.de) - - * types.h: New type u64 - -Mon Mar 9 12:59:55 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h: Included dsa.h. - -Tue Mar 3 15:11:21 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h (random.h): Add new header and move all relevalt - functions to this header. - - - Copyright 1998, 1999, 2000, 2001 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. - - diff --git a/include/_regex.h b/include/_regex.h deleted file mode 100644 index fac441dc6..000000000 --- a/include/_regex.h +++ /dev/null @@ -1,574 +0,0 @@ -/* Definitions for data structures and routines for the regular - expression library. - Copyright (C) 1985,1989-93,1995-98,2000,2001,2002 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _REGEX_H -#define _REGEX_H 1 - -/* Allow the use in C++ code. */ -#ifdef __cplusplus -extern "C" { -#endif - -/* POSIX says that <sys/types.h> must be included (by the caller) before - <regex.h>. */ - -#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS -/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it - should be there. */ -# include <stddef.h> -#endif - -/* The following two types have to be signed and unsigned integer type - wide enough to hold a value of a pointer. For most ANSI compilers - ptrdiff_t and size_t should be likely OK. Still size of these two - types is 2 for Microsoft C. Ugh... */ -typedef long int s_reg_t; -typedef unsigned long int active_reg_t; - -/* The following bits are used to determine the regexp syntax we - recognize. The set/not-set meanings are chosen so that Emacs syntax - remains the value 0. The bits are given in alphabetical order, and - the definitions shifted by one from the previous bit; thus, when we - add or remove a bit, only one other definition need change. */ -typedef unsigned long int reg_syntax_t; - -/* If this bit is not set, then \ inside a bracket expression is literal. - If set, then such a \ quotes the following character. */ -#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) - -/* If this bit is not set, then + and ? are operators, and \+ and \? are - literals. - If set, then \+ and \? are operators and + and ? are literals. */ -#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) - -/* If this bit is set, then character classes are supported. They are: - [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], - [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. - If not set, then character classes are not supported. */ -#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) - -/* If this bit is set, then ^ and $ are always anchors (outside bracket - expressions, of course). - If this bit is not set, then it depends: - ^ is an anchor if it is at the beginning of a regular - expression or after an open-group or an alternation operator; - $ is an anchor if it is at the end of a regular expression, or - before a close-group or an alternation operator. - - This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because - POSIX draft 11.2 says that * etc. in leading positions is undefined. - We already implemented a previous draft which made those constructs - invalid, though, so we haven't changed the code back. */ -#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) - -/* If this bit is set, then special characters are always special - regardless of where they are in the pattern. - If this bit is not set, then special characters are special only in - some contexts; otherwise they are ordinary. Specifically, - * + ? and intervals are only special when not after the beginning, - open-group, or alternation operator. */ -#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) - -/* If this bit is set, then *, +, ?, and { cannot be first in an re or - immediately after an alternation or begin-group operator. */ -#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) - -/* If this bit is set, then . matches newline. - If not set, then it doesn't. */ -#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) - -/* If this bit is set, then . doesn't match NUL. - If not set, then it does. */ -#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) - -/* If this bit is set, nonmatching lists [^...] do not match newline. - If not set, they do. */ -#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) - -/* If this bit is set, either \{...\} or {...} defines an - interval, depending on RE_NO_BK_BRACES. - If not set, \{, \}, {, and } are literals. */ -#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) - -/* If this bit is set, +, ? and | aren't recognized as operators. - If not set, they are. */ -#define RE_LIMITED_OPS (RE_INTERVALS << 1) - -/* If this bit is set, newline is an alternation operator. - If not set, newline is literal. */ -#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) - -/* If this bit is set, then `{...}' defines an interval, and \{ and \} - are literals. - If not set, then `\{...\}' defines an interval. */ -#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) - -/* If this bit is set, (...) defines a group, and \( and \) are literals. - If not set, \(...\) defines a group, and ( and ) are literals. */ -#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) - -/* If this bit is set, then \<digit> matches <digit>. - If not set, then \<digit> is a back-reference. */ -#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) - -/* If this bit is set, then | is an alternation operator, and \| is literal. - If not set, then \| is an alternation operator, and | is literal. */ -#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) - -/* If this bit is set, then an ending range point collating higher - than the starting range point, as in [z-a], is invalid. - If not set, then when ending range point collates higher than the - starting range point, the range is ignored. */ -#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) - -/* If this bit is set, then an unmatched ) is ordinary. - If not set, then an unmatched ) is invalid. */ -#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) - -/* If this bit is set, succeed as soon as we match the whole pattern, - without further backtracking. */ -#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1) - -/* If this bit is set, do not process the GNU regex operators. - If not set, then the GNU regex operators are recognized. */ -#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1) - -/* If this bit is set, turn on internal regex debugging. - If not set, and debugging was on, turn it off. - This only works if regex.c is compiled -DDEBUG. - We define this bit always, so that all that's needed to turn on - debugging is to recompile regex.c; the calling code can always have - this bit set, and it won't affect anything in the normal case. */ -#define RE_DEBUG (RE_NO_GNU_OPS << 1) - -/* If this bit is set, a syntactically invalid interval is treated as - a string of ordinary characters. For example, the ERE 'a{1' is - treated as 'a\{1'. */ -#define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1) - -/* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -#define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1) - -/* This global variable defines the particular regexp syntax to use (for - some interfaces). When a regexp is compiled, the syntax used is - stored in the pattern buffer, so changing this does not affect - already-compiled regexps. */ -extern reg_syntax_t re_syntax_options; - -/* Define combinations of the above bits for the standard possibilities. - (The [[[ comments delimit what gets put into the Texinfo file, so - don't delete them!) */ -/* [[[begin syntaxes]]] */ -#define RE_SYNTAX_EMACS 0 - -#define RE_SYNTAX_AWK \ - (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ - | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ - | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) - -#define RE_SYNTAX_GNU_AWK \ - ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \ - & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS \ - | RE_CONTEXT_INVALID_OPS )) - -#define RE_SYNTAX_POSIX_AWK \ - (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ - | RE_INTERVALS | RE_NO_GNU_OPS) - -#define RE_SYNTAX_GREP \ - (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ - | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ - | RE_NEWLINE_ALT) - -#define RE_SYNTAX_EGREP \ - (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ - | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ - | RE_NO_BK_VBAR) - -#define RE_SYNTAX_POSIX_EGREP \ - (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES \ - | RE_INVALID_INTERVAL_ORD) - -/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ -#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC - -#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC - -/* Syntax bits common to both basic and extended POSIX regex syntax. */ -#define _RE_SYNTAX_POSIX_COMMON \ - (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ - | RE_INTERVALS | RE_NO_EMPTY_RANGES) - -#define RE_SYNTAX_POSIX_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) - -/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes - RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this - isn't minimal, since other operators, such as \`, aren't disabled. */ -#define RE_SYNTAX_POSIX_MINIMAL_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) - -#define RE_SYNTAX_POSIX_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ - | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD) - -/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is - removed and RE_NO_BK_REFS is added. */ -#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) -/* [[[end syntaxes]]] */ - -/* Maximum number of duplicates an interval can allow. Some systems - (erroneously) define this in other header files, but we want our - value, so remove any previous define. */ -#ifdef RE_DUP_MAX -# undef RE_DUP_MAX -#endif -/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */ -#define RE_DUP_MAX (0x7fff) - - -/* POSIX `cflags' bits (i.e., information for `regcomp'). */ - -/* If this bit is set, then use extended regular expression syntax. - If not set, then use basic regular expression syntax. */ -#define REG_EXTENDED 1 - -/* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -#define REG_ICASE (REG_EXTENDED << 1) - -/* If this bit is set, then anchors do not match at newline - characters in the string. - If not set, then anchors do match at newlines. */ -#define REG_NEWLINE (REG_ICASE << 1) - -/* If this bit is set, then report only success or fail in regexec. - If not set, then returns differ between not matching and errors. */ -#define REG_NOSUB (REG_NEWLINE << 1) - - -/* POSIX `eflags' bits (i.e., information for regexec). */ - -/* If this bit is set, then the beginning-of-line operator doesn't match - the beginning of the string (presumably because it's not the - beginning of a line). - If not set, then the beginning-of-line operator does match the - beginning of the string. */ -#define REG_NOTBOL 1 - -/* Like REG_NOTBOL, except for the end-of-line. */ -#define REG_NOTEOL (1 << 1) - - -/* If any error codes are removed, changed, or added, update the - `re_error_msg' table in regex.c. */ -typedef enum -{ -#ifdef _XOPEN_SOURCE - REG_ENOSYS = -1, /* This will never happen for this implementation. */ -#endif - - REG_NOERROR = 0, /* Success. */ - REG_NOMATCH, /* Didn't find a match (for regexec). */ - - /* POSIX regcomp return error codes. (In the order listed in the - standard.) */ - REG_BADPAT, /* Invalid pattern. */ - REG_ECOLLATE, /* Not implemented. */ - REG_ECTYPE, /* Invalid character class name. */ - REG_EESCAPE, /* Trailing backslash. */ - REG_ESUBREG, /* Invalid back reference. */ - REG_EBRACK, /* Unmatched left bracket. */ - REG_EPAREN, /* Parenthesis imbalance. */ - REG_EBRACE, /* Unmatched \{. */ - REG_BADBR, /* Invalid contents of \{\}. */ - REG_ERANGE, /* Invalid range end. */ - REG_ESPACE, /* Ran out of memory. */ - REG_BADRPT, /* No preceding re for repetition op. */ - - /* Error codes we've added. */ - REG_EEND, /* Premature end. */ - REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ - REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ -} reg_errcode_t; - -/* This data structure represents a compiled pattern. Before calling - the pattern compiler, the fields `buffer', `allocated', `fastmap', - `translate', and `no_sub' can be set. After the pattern has been - compiled, the `re_nsub' field is available. All other fields are - private to the regex routines. */ - -#ifndef RE_TRANSLATE_TYPE -# define RE_TRANSLATE_TYPE char * -#endif - -struct re_pattern_buffer -{ -/* [[[begin pattern_buffer]]] */ - /* Space that holds the compiled pattern. It is declared as - `unsigned char *' because its elements are - sometimes used as array indexes. */ - unsigned char *buffer; - - /* Number of bytes to which `buffer' points. */ - unsigned long int allocated; - - /* Number of bytes actually used in `buffer'. */ - unsigned long int used; - - /* Syntax setting with which the pattern was compiled. */ - reg_syntax_t syntax; - - /* Pointer to a fastmap, if any, otherwise zero. re_search uses - the fastmap, if there is one, to skip over impossible - starting points for matches. */ - char *fastmap; - - /* Either a translate table to apply to all characters before - comparing them, or zero for no translation. The translation - is applied to a pattern when it is compiled and to a string - when it is matched. */ - RE_TRANSLATE_TYPE translate; - - /* Number of subexpressions found by the compiler. */ - size_t re_nsub; - - /* Zero if this pattern cannot match the empty string, one else. - Well, in truth it's used only in `re_search_2', to see - whether or not we should use the fastmap, so we don't set - this absolutely perfectly; see `re_compile_fastmap' (the - `duplicate' case). */ - unsigned can_be_null : 1; - - /* If REGS_UNALLOCATED, allocate space in the `regs' structure - for `max (RE_NREGS, re_nsub + 1)' groups. - If REGS_REALLOCATE, reallocate space if necessary. - If REGS_FIXED, use what's there. */ -#define REGS_UNALLOCATED 0 -#define REGS_REALLOCATE 1 -#define REGS_FIXED 2 - unsigned regs_allocated : 2; - - /* Set to zero when `regex_compile' compiles a pattern; set to one - by `re_compile_fastmap' if it updates the fastmap. */ - unsigned fastmap_accurate : 1; - - /* If set, `re_match_2' does not return information about - subexpressions. */ - unsigned no_sub : 1; - - /* If set, a beginning-of-line anchor doesn't match at the - beginning of the string. */ - unsigned not_bol : 1; - - /* Similarly for an end-of-line anchor. */ - unsigned not_eol : 1; - - /* If true, an anchor at a newline matches. */ - unsigned newline_anchor : 1; - -/* [[[end pattern_buffer]]] */ -}; - -typedef struct re_pattern_buffer regex_t; - -/* Type for byte offsets within the string. POSIX mandates this. */ -typedef int regoff_t; - - -/* This is the structure we store register match data in. See - regex.texinfo for a full description of what registers match. */ -struct re_registers -{ - unsigned num_regs; - regoff_t *start; - regoff_t *end; -}; - - -/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, - `re_match_2' returns information about at least this many registers - the first time a `regs' structure is passed. */ -#ifndef RE_NREGS -# define RE_NREGS 30 -#endif - - -/* POSIX specification for registers. Aside from the different names than - `re_registers', POSIX uses an array of structures, instead of a - structure of arrays. */ -typedef struct -{ - regoff_t rm_so; /* Byte offset from string's start to substring's start. */ - regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ -} regmatch_t; - -/* Declarations for routines. */ - -/* To avoid duplicating every routine declaration -- once with a - prototype (if we are ANSI), and once without (if we aren't) -- we - use the following macro to declare argument types. This - unfortunately clutters up the declarations a bit, but I think it's - worth it. */ - -#if __STDC__ - -# define _RE_ARGS(args) args - -#else /* not __STDC__ */ - -# define _RE_ARGS(args) () - -#endif /* not __STDC__ */ - -/* Sets the current default syntax to SYNTAX, and return the old syntax. - You can also simply assign to the `re_syntax_options' variable. */ -extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); - -/* Compile the regular expression PATTERN, with length LENGTH - and syntax given by the global `re_syntax_options', into the buffer - BUFFER. Return NULL if successful, and an error string if not. */ -extern const char *re_compile_pattern - _RE_ARGS ((const char *pattern, size_t length, - struct re_pattern_buffer *buffer)); - - -/* Compile a fastmap for the compiled pattern in BUFFER; used to - accelerate searches. Return 0 if successful and -2 if was an - internal error. */ -extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); - - -/* Search in the string STRING (with length LENGTH) for the pattern - compiled into BUFFER. Start searching at position START, for RANGE - characters. Return the starting position of the match, -1 for no - match, or -2 for an internal error. Also return register - information in REGS (if REGS and BUFFER->no_sub are nonzero). */ -extern int re_search - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, int range, struct re_registers *regs)); - - -/* Like `re_search', but search in the concatenation of STRING1 and - STRING2. Also, stop searching at index START + STOP. */ -extern int re_search_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, int range, struct re_registers *regs, int stop)); - - -/* Like `re_search', but return how many characters in STRING the regexp - in BUFFER matched, starting at position START. */ -extern int re_match - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, struct re_registers *regs)); - - -/* Relates to `re_match' as `re_search_2' relates to `re_search'. */ -extern int re_match_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, struct re_registers *regs, int stop)); - - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using BUFFER and REGS will use this memory - for recording register information. STARTS and ENDS must be - allocated with malloc, and must each be at least `NUM_REGS * sizeof - (regoff_t)' bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ -extern void re_set_registers - _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, - unsigned num_regs, regoff_t *starts, regoff_t *ends)); - -#if defined _REGEX_RE_COMP || defined _LIBC -# ifndef _CRAY -/* 4.2 bsd compatibility. */ -extern char *re_comp _RE_ARGS ((const char *)); -extern int re_exec _RE_ARGS ((const char *)); -# endif -#endif - -/* GCC 2.95 and later have "__restrict"; C99 compilers have - "restrict", and "configure" may have defined "restrict". */ -#ifndef __restrict -# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)) -# if defined restrict || 199901L <= __STDC_VERSION__ -# define __restrict restrict -# else -# define __restrict -# endif -# endif -#endif -/* gcc 3.1 and up support the [restrict] syntax. */ -#ifndef __restrict_arr -# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -# define __restrict_arr __restrict -# else -# define __restrict_arr -# endif -#endif - -/* POSIX compatibility. */ -extern int regcomp _RE_ARGS ((regex_t *__restrict __preg, - const char *__restrict __pattern, - int __cflags)); - -extern int regexec _RE_ARGS ((const regex_t *__restrict __preg, - const char *__restrict __string, size_t __nmatch, - regmatch_t __pmatch[__restrict_arr], - int __eflags)); - -extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg, - char *__errbuf, size_t __errbuf_size)); - -extern void regfree _RE_ARGS ((regex_t *__preg)); - - -#ifdef __cplusplus -} -#endif /* C++ */ - -#endif /* regex.h */ - -/* -Local variables: -make-backup-files: t -version-control: t -trim-versions-without-asking: nil -End: -*/ diff --git a/include/cipher.h b/include/cipher.h deleted file mode 100644 index e7e36c6d5..000000000 --- a/include/cipher.h +++ /dev/null @@ -1,97 +0,0 @@ -/* cipher.h - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_CIPHER_H -#define G10_CIPHER_H - -#include <gcrypt.h> - -#define CIPHER_ALGO_NONE GCRY_CIPHER_NONE -#define CIPHER_ALGO_IDEA GCRY_CIPHER_IDEA -#define CIPHER_ALGO_3DES GCRY_CIPHER_3DES -#define CIPHER_ALGO_CAST5 GCRY_CIPHER_CAST5 -#define CIPHER_ALGO_BLOWFISH GCRY_CIPHER_BLOWFISH /* 128 bit */ -#define CIPHER_ALGO_SAFER_SK128 GCRY_CIPHER_SK128 -#define CIPHER_ALGO_DES_SK GCRY_CIPHER_DES_SK -#define CIPHER_ALGO_AES GCRY_CIPHER_AES -#define CIPHER_ALGO_AES192 GCRY_CIPHER_AES192 -#define CIPHER_ALGO_AES256 GCRY_CIPHER_AES256 -#define CIPHER_ALGO_RIJNDAEL CIPHER_ALGO_AES -#define CIPHER_ALGO_RIJNDAEL192 CIPHER_ALGO_AES192 -#define CIPHER_ALGO_RIJNDAEL256 CIPHER_ALGO_AES256 -#define CIPHER_ALGO_TWOFISH GCRY_CIPHER_TWOFISH /* 256 bit */ -#define CIPHER_ALGO_DUMMY 110 /* no encryption at all */ - -#define PUBKEY_ALGO_RSA GCRY_PK_RSA -#define PUBKEY_ALGO_RSA_E GCRY_PK_RSA_E -#define PUBKEY_ALGO_RSA_S GCRY_PK_RSA_S -#define PUBKEY_ALGO_ELGAMAL_E GCRY_PK_ELG_E -#define PUBKEY_ALGO_DSA GCRY_PK_DSA -#define PUBKEY_ALGO_ELGAMAL GCRY_PK_ELG - -#define PUBKEY_USAGE_SIG GCRY_PK_USAGE_SIGN -#define PUBKEY_USAGE_ENC GCRY_PK_USAGE_ENCR -#define PUBKEY_USAGE_CERT 4 /* key is also good to certify other keys*/ -#define PUBKEY_USAGE_AUTH 8 - -#define DIGEST_ALGO_MD5 GCRY_MD_MD5 -#define DIGEST_ALGO_SHA1 GCRY_MD_SHA1 -#define DIGEST_ALGO_RMD160 GCRY_MD_RMD160 -#define DIGEST_ALGO_SHA256 GCRY_MD_SHA256 -#define DIGEST_ALGO_SHA384 GCRY_MD_SHA384 -#define DIGEST_ALGO_SHA512 GCRY_MD_SHA512 - -#define COMPRESS_ALGO_NONE 0 -#define COMPRESS_ALGO_ZIP 1 -#define COMPRESS_ALGO_ZLIB 2 - -#define is_RSA(a) ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \ - || (a)==PUBKEY_ALGO_RSA_S ) -#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL || (a)==PUBKEY_ALGO_ELGAMAL_E) - -typedef struct { - int algo; - int keylen; - int algo_info_printed; - int use_mdc; - byte key[32]; /* this is the largest used keylen (256 bit) */ -} DEK; - - -#ifndef EXTERN_UNLESS_MAIN_MODULE -#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE) -#define EXTERN_UNLESS_MAIN_MODULE extern -#else -#define EXTERN_UNLESS_MAIN_MODULE -#endif -#endif -EXTERN_UNLESS_MAIN_MODULE int g10_opt_verbose; -EXTERN_UNLESS_MAIN_MODULE const char *g10_opt_homedir; - - - -#define PUBKEY_MAX_NPKEY 4 -#define PUBKEY_MAX_NSKEY 6 -#define PUBKEY_MAX_NSIG 2 -#define PUBKEY_MAX_NENC 2 - -#define MD_HANDLE gcry_md_hd_t -#define CIPHER_HANDLE gcry_cipher_hd_t - -#endif /*G10_CIPHER_H*/ diff --git a/include/distfiles b/include/distfiles deleted file mode 100644 index b11749d78..000000000 --- a/include/distfiles +++ /dev/null @@ -1,13 +0,0 @@ -cipher.h -errors.h -memory.h -mpi.h -types.h -util.h -i18n.h -host2net.h -http.h -keyserver.h -_regex.h - -ChangeLog diff --git a/include/errors.h b/include/errors.h deleted file mode 100644 index ed437fa99..000000000 --- a/include/errors.h +++ /dev/null @@ -1,101 +0,0 @@ -/* errors.h - error code - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef GNUPG_INCLUDE_ERRORS_H -#define GNUPG_INCLUDE_ERRORS_H - -#if 0 -#error Remove this file after replacing all error codes with those -#error from libgpg-error. The numerical values are identical, though. -#endif - - -#if 0 /* Not used anymore. */ -#define G10ERR_GENERAL 1 -#define G10ERR_UNKNOWN_PACKET 2 -#define G10ERR_UNKNOWN_VERSION 3 /* Unknown version (in packet) */ -#define G10ERR_PUBKEY_ALGO 4 /* Unknown pubkey algorithm */ -#define G10ERR_DIGEST_ALGO 5 /* Unknown digest algorithm */ -#define G10ERR_BAD_PUBKEY 6 /* Bad public key */ -#define G10ERR_BAD_SECKEY 7 /* Bad secret key */ -#define G10ERR_BAD_SIGN 8 /* Bad signature */ -#define G10ERR_NO_PUBKEY 9 /* public key not found */ -#define G10ERR_CHECKSUM 10 /* checksum error */ -#define G10ERR_BAD_PASS 11 /* Bad passphrase */ -#define G10ERR_CIPHER_ALGO 12 /* Unknown cipher algorithm */ -#define G10ERR_KEYRING_OPEN 13 -#define G10ERR_INVALID_PACKET 14 -#define G10ERR_INVALID_ARMOR 15 -#define G10ERR_NO_USER_ID 16 -#define G10ERR_NO_SECKEY 17 /* secret key not available */ -#define G10ERR_WRONG_SECKEY 18 /* wrong seckey used */ -#define G10ERR_UNSUPPORTED 19 -#define G10ERR_BAD_KEY 20 /* bad (session) key */ -#define G10ERR_READ_FILE 21 -#define G10ERR_WRITE_FILE 22 -#define G10ERR_COMPR_ALGO 23 /* Unknown compress algorithm */ -#define G10ERR_OPEN_FILE 24 -#define G10ERR_CREATE_FILE 25 -#define G10ERR_PASSPHRASE 26 /* invalid passphrase */ -#define G10ERR_NI_PUBKEY 27 -#define G10ERR_NI_CIPHER 28 -#define G10ERR_SIG_CLASS 29 -#define G10ERR_BAD_MPI 30 -#define G10ERR_RESOURCE_LIMIT 31 -#define G10ERR_INV_KEYRING 32 -#define G10ERR_TRUSTDB 33 /* a problem with the trustdb */ -#define G10ERR_BAD_CERT 34 /* bad certicate */ -#define G10ERR_INV_USER_ID 35 -#define G10ERR_CLOSE_FILE 36 -#define G10ERR_RENAME_FILE 37 -#define G10ERR_DELETE_FILE 38 -#define G10ERR_UNEXPECTED 39 -#define G10ERR_TIME_CONFLICT 40 -#define G10ERR_WR_PUBKEY_ALGO 41 /* unusabe pubkey algo */ -#define G10ERR_FILE_EXISTS 42 -#define G10ERR_WEAK_KEY 43 /* NOTE: hardcoded into the cipher modules */ -#define G10ERR_WRONG_KEYLEN 44 /* NOTE: hardcoded into the cipher modules */ -#define G10ERR_INV_ARG 45 -#define G10ERR_BAD_URI 46 /* syntax error in URI */ -#define G10ERR_INVALID_URI 47 /* e.g. unsupported scheme */ -#define G10ERR_NETWORK 48 /* general network error */ -#define G10ERR_UNKNOWN_HOST 49 -#define G10ERR_SELFTEST_FAILED 50 -#define G10ERR_NOT_ENCRYPTED 51 -#define G10ERR_NOT_PROCESSED 52 -#define G10ERR_UNU_PUBKEY 53 -#define G10ERR_UNU_SECKEY 54 -#define G10ERR_KEYSERVER 55 -#endif - -#ifndef HAVE_STRERROR -char *strerror( int n ); -#endif - -#endif /*GNUPG_INCLUDE_ERRORS_H*/ - - - - - - - - - - diff --git a/include/host2net.h b/include/host2net.h deleted file mode 100644 index 0f12a8e1d..000000000 --- a/include/host2net.h +++ /dev/null @@ -1,43 +0,0 @@ -/* host2net.h - Some macros - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_HOST2NET_H -#define G10_HOST2NET_H - -#include "types.h" - -#define buftoulong( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \ - (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3))) -#define buftoushort( p ) ((*((byte*)(p)) << 8) | (*((byte*)(p)+1))) -#define ulongtobuf( p, a ) do { \ - ((byte*)p)[0] = a >> 24; \ - ((byte*)p)[1] = a >> 16; \ - ((byte*)p)[2] = a >> 8; \ - ((byte*)p)[3] = a ; \ - } while(0) -#define ushorttobuf( p, a ) do { \ - ((byte*)p)[0] = a >> 8; \ - ((byte*)p)[1] = a ; \ - } while(0) -#define buftou32( p) buftoulong( (p) ) -#define u32tobuf( p, a) ulongtobuf( (p), (a) ) - - -#endif /*G10_HOST2NET_H*/ diff --git a/include/http.h b/include/http.h deleted file mode 100644 index b53ac9f9f..000000000 --- a/include/http.h +++ /dev/null @@ -1,82 +0,0 @@ -/* http.h - HTTP protocol handler - * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_HTTP_H -#define G10_HTTP_H 1 - -#include "iobuf.h" - -struct uri_tuple { - struct uri_tuple *next; - const char *name; /* a pointer into name */ - char *value; /* a pointer to value (a Nul is always appended) */ - size_t valuelen; /* and the real length of the value */ - /* because the value may contain embedded Nuls */ -}; -typedef struct uri_tuple *URI_TUPLE; - -struct parsed_uri { - /* all these pointers point into buffer; most stuff is not escaped */ - char *scheme; /* pointer to the scheme string (lowercase) */ - char *host; /* host (converted to lowercase) */ - ushort port; /* port (always set if the host is set) */ - char *path; /* the path */ - URI_TUPLE params; /* ";xxxxx" */ - URI_TUPLE query; /* "?xxx=yyy" */ - char buffer[1]; /* buffer which holds a (modified) copy of the URI */ -}; -typedef struct parsed_uri *PARSED_URI; - -typedef enum { - HTTP_REQ_GET = 1, - HTTP_REQ_HEAD = 2, - HTTP_REQ_POST = 3 -} HTTP_REQ_TYPE; - -enum { /* put flag values into an enum, so that gdb can display them */ - HTTP_FLAG_TRY_PROXY = 1, - HTTP_FLAG_NO_SHUTDOWN = 2, - HTTP_FLAG_TRY_SRV = 3 -}; - -struct http_context { - int initialized; - unsigned int status_code; - int sock; - int in_data; - IOBUF fp_read; - IOBUF fp_write; - int is_http_0_9; - PARSED_URI uri; - HTTP_REQ_TYPE req_type; - byte *buffer; /* line buffer */ - unsigned buffer_size; - unsigned int flags; -}; -typedef struct http_context *HTTP_HD; - -int http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url, - unsigned int flags ); -void http_start_data( HTTP_HD hd ); -int http_wait_response( HTTP_HD hd, unsigned int *ret_status ); -void http_close( HTTP_HD hd ); - -int http_open_document( HTTP_HD hd, const char *document, unsigned int flags ); - -#endif /*G10_HTTP_H*/ diff --git a/include/i18n.h b/include/i18n.h deleted file mode 100644 index 20c2570ab..000000000 --- a/include/i18n.h +++ /dev/null @@ -1,54 +0,0 @@ -/* i18n.h - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_I18N_H -#define G10_I18N_H - -#ifdef USE_SIMPLE_GETTEXT -int set_gettext_file( const char *filename ); -const char *gettext( const char *msgid ); - -#define _(a) gettext (a) -#define N_(a) (a) - -#else -#ifdef HAVE_LOCALE_H -#include <locale.h> /* suggested by Ernst Molitor */ -#endif - -#ifdef ENABLE_NLS -#ifndef __riscos__ -#include <libintl.h> -#else -#include "libgettext.h" -#endif /* __riscos__ */ -#define _(a) gettext (a) -#ifdef gettext_noop -#define N_(a) gettext_noop (a) -#else -#define N_(a) (a) -#endif -#else -#define _(a) (a) -#define N_(a) (a) -#endif -#endif /* !USE_SIMPLE_GETTEXT */ - -#endif /*G10_I18N_H*/ diff --git a/include/keyserver.h b/include/keyserver.h deleted file mode 100644 index 33c1b318b..000000000 --- a/include/keyserver.h +++ /dev/null @@ -1,42 +0,0 @@ -/* keyserver.h - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef _KEYSERVER_H_ -#define _KEYSERVER_H_ - -#define KEYSERVER_PROTO_VERSION 1 - -/* These are usable for return codes for the gpgkeys_ process, and - also KEY FAILED codes. */ -#define KEYSERVER_OK 0 /* not an error */ -#define KEYSERVER_INTERNAL_ERROR 1 /* gpgkeys_ internal error */ -#define KEYSERVER_NOT_SUPPORTED 2 /* operation not supported */ -#define KEYSERVER_VERSION_ERROR 3 /* VERSION mismatch */ -#define KEYSERVER_GENERAL_ERROR 4 /* keyserver internal error */ -#define KEYSERVER_NO_MEMORY 5 /* out of memory */ -#define KEYSERVER_KEY_NOT_FOUND 6 /* key not found */ -#define KEYSERVER_KEY_EXISTS 7 /* key already exists */ -#define KEYSERVER_KEY_INCOMPLETE 8 /* key incomplete (EOF) */ -#define KEYSERVER_UNREACHABLE 9 /* unable to contact keyserver */ - -/* Must be 127 due to shell internal magic. */ -#define KEYSERVER_SCHEME_NOT_FOUND 127 - -#endif /* !_KEYSERVER_H_ */ diff --git a/include/memory.h b/include/memory.h deleted file mode 100644 index 959f2999e..000000000 --- a/include/memory.h +++ /dev/null @@ -1,93 +0,0 @@ -/* memory.h - memory allocation - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_MEMORY_H -#define G10_MEMORY_H - -#ifdef M_DEBUG -#ifndef STR -#define STR(v) #v -#endif -#ifndef __riscos__ -#define M_DBGINFO(a) __FUNCTION__ "["__FILE__ ":" STR(a) "]" -#else /* __riscos__ */ -#define M_DBGINFO(a) "["__FILE__ ":" STR(a) "]" -#endif /* __riscos__ */ -#define m_alloc(n) m_debug_alloc((n), M_DBGINFO( __LINE__ ) ) -#define m_alloc_clear(n) m_debug_alloc_clear((n), M_DBGINFO(__LINE__) ) -#define m_alloc_secure(n) m_debug_alloc((n), M_DBGINFO(__LINE__) ) -#define m_alloc_secure_clear(n) m_debug_alloc_secure_clear((n), M_DBGINFO(__LINE__) ) -#define m_realloc(n,m) m_debug_realloc((n),(m), M_DBGINFO(__LINE__) ) -#define m_free(n) m_debug_free((n), M_DBGINFO(__LINE__) ) -#define m_check(n) m_debug_check((n), M_DBGINFO(__LINE__) ) -/*#define m_copy(a) m_debug_copy((a), M_DBGINFO(__LINE__) )*/ -#define m_strdup(a) m_debug_strdup((a), M_DBGINFO(__LINE__) ) - -void *m_debug_alloc( size_t n, const char *info ); -void *m_debug_alloc_clear( size_t n, const char *info ); -void *m_debug_alloc_secure( size_t n, const char *info ); -void *m_debug_alloc_secure_clear( size_t n, const char *info ); -void *m_debug_realloc( void *a, size_t n, const char *info ); -void m_debug_free( void *p, const char *info ); -void m_debug_check( const void *a, const char *info ); -/*void *m_debug_copy( const void *a, const char *info );*/ -char *m_debug_strdup( const char *a, const char *info ); - -#else -void *m_alloc( size_t n ); -void *m_alloc_clear( size_t n ); -void *m_alloc_secure( size_t n ); -void *m_alloc_secure_clear( size_t n ); -void *m_realloc( void *a, size_t n ); -void m_free( void *p ); -void m_check( const void *a ); -/*void *m_copy( const void *a );*/ -char *m_strdup( const char * a); -#endif - -size_t m_size( const void *a ); -void m_print_stats(const char *prefix); - -/*-- secmem.c --*/ -void secmem_init( size_t npool ); -void secmem_term( void ); -void *secmem_malloc( size_t size ); -void *secmem_realloc( void *a, size_t newsize ); -void secmem_free( void *a ); -int m_is_secure( const void *p ); -void secmem_dump_stats(void); -void secmem_set_flags( unsigned flags ); -unsigned secmem_get_flags(void); - - -#define DBG_MEMORY memory_debug_mode -#define DBG_MEMSTAT memory_stat_debug_mode - -#ifndef EXTERN_UNLESS_MAIN_MODULE -#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE) -#define EXTERN_UNLESS_MAIN_MODULE extern -#else -#define EXTERN_UNLESS_MAIN_MODULE -#endif -#endif -EXTERN_UNLESS_MAIN_MODULE int memory_debug_mode; -EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; - -#endif /*G10_MEMORY_H*/ diff --git a/include/mpi.h b/include/mpi.h deleted file mode 100644 index 424e591a0..000000000 --- a/include/mpi.h +++ /dev/null @@ -1,201 +0,0 @@ -/* mpi.h - Multi Precision Integers - * Copyright (C) 1994, 1996, 1998, 1999, - * 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - * The GNU MP Library itself is published under the LGPL; - * however I decided to publish this code under the plain GPL. - */ - -#ifndef G10_MPI_H -#define G10_MPI_H - -#include <gcrypt.h> - -#if 0 - - -#include <config.h> -#include <stdio.h> -#include "iobuf.h" -#include "types.h" -#include "memory.h" - -#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT - typedef unsigned int mpi_limb_t; - typedef signed int mpi_limb_signed_t; -#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG - typedef unsigned long int mpi_limb_t; - typedef signed long int mpi_limb_signed_t; -#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG - typedef unsigned long long int mpi_limb_t; - typedef signed long long int mpi_limb_signed_t; -#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT - typedef unsigned short int mpi_limb_t; - typedef signed short int mpi_limb_signed_t; -#else -#error BYTES_PER_MPI_LIMB does not match any C type -#endif -#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB) - -#ifndef EXTERN_UNLESS_MAIN_MODULE -#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE) -#define EXTERN_UNLESS_MAIN_MODULE extern -#else -#define EXTERN_UNLESS_MAIN_MODULE -#endif -#endif - -#define DBG_MPI mpi_debug_mode -EXTERN_UNLESS_MAIN_MODULE int mpi_debug_mode; - - -struct gcry_mpi { - int alloced; /* array size (# of allocated limbs) */ - int nlimbs; /* number of valid limbs */ - int nbits; /* the real number of valid bits (info only) */ - int sign; /* indicates a negative number */ - unsigned flags; /* bit 0: array must be allocated in secure memory space */ - /* bit 1: not used */ - /* bit 2: the limb is a pointer to some m_alloced data */ - mpi_limb_t *d; /* array with the limbs */ -}; - -typedef struct gcry_mpi *MPI; - -#define MPI_NULL NULL - -#define mpi_get_nlimbs(a) ((a)->nlimbs) -#define mpi_is_neg(a) ((a)->sign) - -/*-- mpiutil.c --*/ - -#ifdef M_DEBUG -#define mpi_alloc(n) mpi_debug_alloc((n), M_DBGINFO( __LINE__ ) ) -#define mpi_alloc_secure(n) mpi_debug_alloc_secure((n), M_DBGINFO( __LINE__ ) ) -#define mpi_alloc_like(n) mpi_debug_alloc_like((n), M_DBGINFO( __LINE__ ) ) -#define mpi_free(a) mpi_debug_free((a), M_DBGINFO(__LINE__) ) -#define mpi_resize(a,b) mpi_debug_resize((a),(b), M_DBGINFO(__LINE__) ) -#define mpi_copy(a) mpi_debug_copy((a), M_DBGINFO(__LINE__) ) -MPI mpi_debug_alloc( unsigned nlimbs, const char *info ); -MPI mpi_debug_alloc_secure( unsigned nlimbs, const char *info ); -MPI mpi_debug_alloc_like( MPI a, const char *info ); -void mpi_debug_free( MPI a, const char *info ); -void mpi_debug_resize( MPI a, unsigned nlimbs, const char *info ); -MPI mpi_debug_copy( MPI a, const char *info ); -#else -MPI mpi_alloc( unsigned nlimbs ); -MPI mpi_alloc_secure( unsigned nlimbs ); -MPI mpi_alloc_like( MPI a ); -void mpi_free( MPI a ); -void mpi_resize( MPI a, unsigned nlimbs ); -MPI mpi_copy( MPI a ); -#endif -#define mpi_is_opaque(a) ((a) && ((a)->flags&4)) -MPI mpi_set_opaque( MPI a, void *p, int len ); -void *mpi_get_opaque( MPI a, int *len ); -#define mpi_is_secure(a) ((a) && ((a)->flags&1)) -void mpi_set_secure( MPI a ); -void mpi_clear( MPI a ); -void mpi_set( MPI w, MPI u); -void mpi_set_ui( MPI w, ulong u); -MPI mpi_alloc_set_ui( unsigned long u); -void mpi_m_check( MPI a ); -void mpi_swap( MPI a, MPI b); - -/*-- mpicoder.c --*/ -int mpi_write( IOBUF out, MPI a ); -#ifdef M_DEBUG -#define mpi_read(a,b,c) mpi_debug_read((a),(b),(c), M_DBGINFO( __LINE__ ) ) -MPI mpi_debug_read(IOBUF inp, unsigned *nread, int secure, const char *info); -#else -MPI mpi_read(IOBUF inp, unsigned *nread, int secure); -#endif -MPI mpi_read_from_buffer(byte *buffer, unsigned *ret_nread, int secure); -int mpi_fromstr(MPI val, const char *str); -int mpi_print( FILE *fp, MPI a, int mode ); -void g10_log_mpidump( const char *text, MPI a ); -u32 mpi_get_keyid( MPI a, u32 *keyid ); -byte *mpi_get_buffer( MPI a, unsigned *nbytes, int *sign ); -byte *mpi_get_secure_buffer( MPI a, unsigned *nbytes, int *sign ); -void mpi_set_buffer( MPI a, const byte *buffer, unsigned nbytes, int sign ); - -#define log_mpidump g10_log_mpidump - -/*-- mpi-add.c --*/ -void mpi_add_ui(MPI w, MPI u, ulong v ); -void mpi_add(MPI w, MPI u, MPI v); -void mpi_addm(MPI w, MPI u, MPI v, MPI m); -void mpi_sub_ui(MPI w, MPI u, ulong v ); -void mpi_sub( MPI w, MPI u, MPI v); -void mpi_subm( MPI w, MPI u, MPI v, MPI m); - -/*-- mpi-mul.c --*/ -void mpi_mul_ui(MPI w, MPI u, ulong v ); -void mpi_mul_2exp( MPI w, MPI u, ulong cnt); -void mpi_mul( MPI w, MPI u, MPI v); -void mpi_mulm( MPI w, MPI u, MPI v, MPI m); - -/*-- mpi-div.c --*/ -ulong mpi_fdiv_r_ui( MPI rem, MPI dividend, ulong divisor ); -void mpi_fdiv_r( MPI rem, MPI dividend, MPI divisor ); -void mpi_fdiv_q( MPI quot, MPI dividend, MPI divisor ); -void mpi_fdiv_qr( MPI quot, MPI rem, MPI dividend, MPI divisor ); -void mpi_tdiv_r( MPI rem, MPI num, MPI den); -void mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den); -void mpi_tdiv_q_2exp( MPI w, MPI u, unsigned count ); -int mpi_divisible_ui(MPI dividend, ulong divisor ); - -/*-- mpi-gcd.c --*/ -int mpi_gcd( MPI g, MPI a, MPI b ); - -/*-- mpi-pow.c --*/ -void mpi_pow( MPI w, MPI u, MPI v); -void mpi_powm( MPI res, MPI base, MPI exp, MPI mod); - -/*-- mpi-mpow.c --*/ -void mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI mod); - -/*-- mpi-cmp.c --*/ -int mpi_cmp_ui( MPI u, ulong v ); -int mpi_cmp( MPI u, MPI v ); - -/*-- mpi-scan.c --*/ -int mpi_getbyte( MPI a, unsigned idx ); -void mpi_putbyte( MPI a, unsigned idx, int value ); -unsigned mpi_trailing_zeros( MPI a ); - -/*-- mpi-bit.c --*/ -void mpi_normalize( MPI a ); -unsigned mpi_get_nbits( MPI a ); -int mpi_test_bit( MPI a, unsigned n ); -void mpi_set_bit( MPI a, unsigned n ); -void mpi_set_highbit( MPI a, unsigned n ); -void mpi_clear_highbit( MPI a, unsigned n ); -void mpi_clear_bit( MPI a, unsigned n ); -void mpi_rshift( MPI x, MPI a, unsigned n ); - -/*-- mpi-inv.c --*/ -void mpi_invm( MPI x, MPI u, MPI v ); -#endif -#endif /*G10_MPI_H*/ diff --git a/include/types.h b/include/types.h deleted file mode 100644 index dff512061..000000000 --- a/include/types.h +++ /dev/null @@ -1,135 +0,0 @@ -/* types.h - some common typedefs - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_TYPES_H -#define G10_TYPES_H - -#ifdef HAVE_INTTYPES_H -/* For uint64_t */ -#include <inttypes.h> -#endif - -/* The AC_CHECK_SIZEOF() in configure fails for some machines. - * we provide some fallback values here */ -#if !SIZEOF_UNSIGNED_SHORT -#undef SIZEOF_UNSIGNED_SHORT -#define SIZEOF_UNSIGNED_SHORT 2 -#endif -#if !SIZEOF_UNSIGNED_INT -#undef SIZEOF_UNSIGNED_INT -#define SIZEOF_UNSIGNED_INT 4 -#endif -#if !SIZEOF_UNSIGNED_LONG -#undef SIZEOF_UNSIGNED_LONG -#define SIZEOF_UNSIGNED_LONG 4 -#endif - - -#include <sys/types.h> - - -#ifndef HAVE_BYTE_TYPEDEF -#undef byte /* maybe there is a macro with this name */ -#ifndef __riscos__ -typedef unsigned char byte; -#else -/* Norcroft treats char = unsigned char as legal assignment - but char* = unsigned char* as illegal assignment - and the same applies to the signed variants as well */ -typedef char byte; -#endif -#define HAVE_BYTE_TYPEDEF -#endif - -#ifndef HAVE_USHORT_TYPEDEF -#undef ushort /* maybe there is a macro with this name */ -typedef unsigned short ushort; -#define HAVE_USHORT_TYPEDEF -#endif - -#ifndef HAVE_ULONG_TYPEDEF -#undef ulong /* maybe there is a macro with this name */ -typedef unsigned long ulong; -#define HAVE_ULONG_TYPEDEF -#endif - -#ifndef HAVE_U16_TYPEDEF -#undef u16 /* maybe there is a macro with this name */ -#if SIZEOF_UNSIGNED_INT == 2 -typedef unsigned int u16; -#elif SIZEOF_UNSIGNED_SHORT == 2 -typedef unsigned short u16; -#else -#error no typedef for u16 -#endif -#define HAVE_U16_TYPEDEF -#endif - -#ifndef HAVE_U32_TYPEDEF -#undef u32 /* maybe there is a macro with this name */ -#if SIZEOF_UNSIGNED_INT == 4 -typedef unsigned int u32; -#elif SIZEOF_UNSIGNED_LONG == 4 -typedef unsigned long u32; -#else -#error no typedef for u32 -#endif -#define HAVE_U32_TYPEDEF -#endif - -/**************** - * Warning: Some systems segfault when this u64 typedef and - * the dummy code in cipher/md.c is not available. Examples are - * Solaris and IRIX. - */ -#ifndef HAVE_U64_TYPEDEF -#undef u64 /* maybe there is a macro with this name */ -#if SIZEOF_UINT64_T == 8 -typedef uint64_t u64; -#define U64_C(c) (UINT64_C(c)) -#define HAVE_U64_TYPEDEF -#elif SIZEOF_UNSIGNED_INT == 8 -typedef unsigned int u64; -#define U64_C(c) (c ## U) -#define HAVE_U64_TYPEDEF -#elif SIZEOF_UNSIGNED_LONG == 8 -typedef unsigned long u64; -#define U64_C(c) (c ## UL) -#define HAVE_U64_TYPEDEF -#elif SIZEOF_UNSIGNED_LONG_LONG == 8 -typedef unsigned long long u64; -#define U64_C(c) (c ## ULL) -#define HAVE_U64_TYPEDEF -#endif -#endif - -typedef union { - int a; - short b; - char c[1]; - long d; -#ifdef HAVE_U64_TYPEDEF - u64 e; -#endif - float f; - double g; -} PROPERLY_ALIGNED_TYPE; - -#endif /*G10_TYPES_H*/ diff --git a/include/util.h b/include/util.h deleted file mode 100644 index ca5e5e431..000000000 --- a/include/util.h +++ /dev/null @@ -1,300 +0,0 @@ -/* util.h - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_UTIL_H -#define G10_UTIL_H - -#warning oops, using old util.h -#if 0 /* Dont use it anymore */ - -#if defined (__MINGW32__) || defined (__CYGWIN32__) -#include <stdarg.h> -#endif - -#include "types.h" -#include "errors.h" -#include "types.h" -#include "mpi.h" - - -typedef struct { - int *argc; /* pointer to argc (value subject to change) */ - char ***argv; /* pointer to argv (value subject to change) */ - unsigned flags; /* Global flags (DO NOT CHANGE) */ - int err; /* print error about last option */ - /* 1 = warning, 2 = abort */ - int r_opt; /* return option */ - int r_type; /* type of return value (0 = no argument found)*/ - union { - int ret_int; - long ret_long; - ulong ret_ulong; - char *ret_str; - } r; /* Return values */ - struct { - int idx; - int inarg; - int stopped; - const char *last; - void *aliases; - const void *cur_alias; - } internal; /* DO NOT CHANGE */ -} ARGPARSE_ARGS; - -typedef struct { - int short_opt; - const char *long_opt; - unsigned flags; - const char *description; /* optional option description */ -} ARGPARSE_OPTS; - -/*-- logger.c --*/ -void log_set_logfile( const char *name, int fd ); -FILE *log_stream(void); -void g10_log_print_prefix(const char *text); -void log_set_name( const char *name ); -const char *log_get_name(void); -void log_set_pid( int pid ); -int log_get_errorcount( int clear ); -void log_inc_errorcount(void); -int log_set_strict(int val); -void g10_log_hexdump( const char *text, const char *buf, size_t len ); - -#if defined (__riscos__) \ - || (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )) - void g10_log_bug( const char *fmt, ... ) - __attribute__ ((noreturn, format (printf,1,2))); - void g10_log_bug0( const char *, int, const char * ) __attribute__ ((noreturn)); - void g10_log_fatal( const char *fmt, ... ) - __attribute__ ((noreturn, format (printf,1,2))); - void g10_log_error( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); - 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 -#define BUG() g10_log_bug0( __FILE__ , __LINE__, __func__ ) -#endif -#else - void g10_log_bug( const char *fmt, ... ); - void g10_log_bug0( const char *, int ); - void g10_log_fatal( const char *fmt, ... ); - void g10_log_error( const char *fmt, ... ); - 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 - -#define log_hexdump g10_log_hexdump -#define log_bug g10_log_bug -#define log_bug0 g10_log_bug0 -#define log_fatal g10_log_fatal -#define log_error g10_log_error -#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 - - -/*-- argparse.c --*/ -int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); -int optfile_parse( FILE *fp, const char *filename, unsigned *lineno, - ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); -void usage( int level ); -const char *default_strusage( int level ); - - -/*-- (main program) --*/ -const char *strusage( int level ); - - -/*-- dotlock.c --*/ -struct dotlock_handle; -typedef struct dotlock_handle *DOTLOCK; - -void disable_dotlock(void); -DOTLOCK create_dotlock( const char *file_to_lock ); -int make_dotlock( DOTLOCK h, long timeout ); -int release_dotlock( DOTLOCK h ); -void remove_lockfiles (void); - -/*-- fileutil.c --*/ -char * make_basename(const char *filepath, const char *inputpath); -char * make_dirname(const char *filepath); -char *make_filename( const char *first_part, ... ); -int compare_filenames( const char *a, const char *b ); -const char *print_fname_stdin( const char *s ); -const char *print_fname_stdout( const char *s ); -int is_file_compressed(const char *s, int *r_status); - - -/*-- miscutil.c --*/ -u32 make_timestamp(void); -u32 scan_isodatestr( const char *string ); -u32 add_days_to_timestamp( u32 stamp, u16 days ); -const char *strtimevalue( u32 stamp ); -const char *strtimestamp( u32 stamp ); /* GMT */ -const char *asctimestamp( u32 stamp ); /* localized */ -void print_string( FILE *fp, const byte *p, size_t n, int delim ); -void print_utf8_string( FILE *fp, const byte *p, size_t n ); -void print_utf8_string2( FILE *fp, const byte *p, size_t n, int delim); -char *make_printable_string( const byte *p, size_t n, int delim ); -int answer_is_yes_no_default( const char *s, int def_answer ); -int answer_is_yes( const char *s ); -int answer_is_yes_no_quit( const char *s ); - -/*-- strgutil.c --*/ - -#include "../jnlib/strlist.h" - -const char *memistr( const char *buf, size_t buflen, const char *sub ); -const char *ascii_memistr( const char *buf, size_t buflen, const char *sub ); -char *mem2str( char *, const void *, size_t); -char *trim_spaces( char *string ); -unsigned int trim_trailing_chars( byte *line, unsigned int len, - const char *trimchars); -unsigned int trim_trailing_ws( byte *line, unsigned len ); -unsigned int check_trailing_chars( const byte *line, unsigned int len, - const char *trimchars ); -unsigned int check_trailing_ws( const byte *line, unsigned int len ); -int string_count_chr( const char *string, int c ); -int set_native_charset( const char *newset ); -const char* get_native_charset(void); -char *native_to_utf8( const char *string ); -char *utf8_to_native( const char *string, size_t length, int delim); -int check_utf8_string( const char *string ); - -int ascii_isupper (int c); -int ascii_islower (int c); -int ascii_toupper (int c); -int ascii_tolower (int c); -int ascii_strcasecmp( const char *a, const char *b ); -int ascii_strncasecmp( const char *a, const char *b, size_t n); -int ascii_memcasecmp( const char *a, const char *b, size_t n); - -#ifndef HAVE_STPCPY -char *stpcpy(char *a,const char *b); -#endif -#ifndef HAVE_STRLWR -char *strlwr(char *a); -#endif -#ifndef HAVE_STRSEP -char *strsep (char **stringp, const char *delim); -#endif -#ifndef HAVE_STRCASECMP -int strcasecmp( const char *, const char *b); -#endif -#ifndef HAVE_STRNCASECMP -int strncasecmp (const char *, const char *b, size_t n); -#endif -#ifndef HAVE_STRTOUL -#define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c))) -#endif -#ifndef HAVE_MEMMOVE -#define memmove(d, s, n) bcopy((s), (d), (n)) -#endif - -#if defined (__MINGW32__) -/*-- w32reg.c --*/ -char *read_w32_registry_string( const char *root, - const char *dir, const char *name ); -int write_w32_registry_string(const char *root, const char *dir, - const char *name, const char *value); - -/*-- strgutil.c --*/ -int vasprintf ( char **result, const char *format, va_list args); -#endif - -/**** other missing stuff ****/ -#ifndef HAVE_ATEXIT /* For SunOS */ -#define atexit(a) (on_exit((a),0)) -#endif - -#ifndef HAVE_RAISE -#define raise(a) kill(getpid(), (a)) -#endif - -/******** some macros ************/ -#ifndef STR -#define STR(v) #v -#endif -#define STR2(v) STR(v) -#define DIM(v) (sizeof(v)/sizeof((v)[0])) -#define DIMof(type,member) DIM(((type *)0)->member) - -#define wipememory2(_ptr,_set,_len) do { volatile char *_vptr=(volatile char *)(_ptr); size_t _vlen=(_len); while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } } while(0) -#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) - -/******* RISC OS stuff ***********/ -#ifdef __riscos__ -/* needed for strcasecmp() */ -#include <strings.h> -/* needed for filename munging */ -#include <unixlib/local.h> -/* needed for image file system feature */ -#include <unixlib/features.h> -void riscos_global_defaults(void); -#define RISCOS_GLOBAL_STATICS(a) const char *__dynamic_da_name = (a); -int riscos_load_module(const char *name, const char * const path[], int fatal); -int riscos_get_filetype_from_string(const char *string, int len); -int riscos_get_filetype(const char *filename); -void riscos_set_filetype_by_number(const char *filename, int type); -void riscos_set_filetype_by_mimetype(const char *filename, const char *mimetype); -pid_t riscos_getpid(void); -int riscos_kill(pid_t pid, int sig); -int riscos_access(const char *path, int amode); -int riscos_getchar(void); -char *riscos_make_basename(const char *filepath, const char *inputpath); -int riscos_check_regexp(const char *exp, const char *string, int debug); -int riscos_fdopenfile(const char *filename, const int allow_write); -void riscos_close_fds(void); -int riscos_renamefile(const char *old, const char *new); -char *riscos_gstrans(const char *old); -void riscos_not_implemented(const char *feature); -#ifdef DEBUG -void riscos_dump_fdlist(void); -void riscos_list_openfiles(void); -#endif -#ifndef __RISCOS__C__ -#define getpid riscos_getpid -#define kill(a,b) riscos_kill((a),(b)) -#define access(a,b) riscos_access((a),(b)) -#endif /* !__RISCOS__C__ */ -#endif /* __riscos__ */ - -#endif - -#endif /*G10_UTIL_H*/ diff --git a/include/zlib-riscos.h b/include/zlib-riscos.h deleted file mode 100644 index fad556bcb..000000000 --- a/include/zlib-riscos.h +++ /dev/null @@ -1,134 +0,0 @@ -/* zlib-riscos.h - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_ZLIB_RISCOS_H -#define G10_ZLIB_RISCOS_H - -#include <kernel.h> -#include <swis.h> - -static const char * const zlib_path[] = { - "System:310.Modules.ZLib", - NULL -}; - -#define ZLib_Compress 0x53AC0 -#define ZLib_Decompress 0x53AC1 -#define ZLib_CRC32 0x53AC2 -#define ZLib_Adler32 0x53AC3 -#define ZLib_Version 0x53AC4 -#define ZLib_ZCompress 0x53AC5 -#define ZLib_ZCompress2 0x53AC6 -#define ZLib_ZUncompress 0x53AC7 -#define ZLib_DeflateInit 0x53AC8 -#define ZLib_InflateInit 0x53AC9 -#define ZLib_DeflateInit2 0x53ACA -#define ZLib_InflateInit2 0x53ACB -#define ZLib_Deflate 0x53ACC -#define ZLib_DeflateEnd 0x53ACD -#define ZLib_Inflate 0x53ACE -#define ZLib_InflateEnd 0x53ACF -#define ZLib_DeflateSetDictionary 0x53AD0 -#define ZLib_DeflateCopy 0x53AD1 -#define ZLib_DeflateReset 0x53AD2 -#define ZLib_DeflateParams 0x53AD3 -#define ZLib_InflateSetDictionary 0x53AD4 -#define ZLib_InflateSync 0x53AD5 -#define ZLib_InflateReset 0x53AD6 -#define ZLib_GZOpen 0x53AD7 -#define ZLib_GZRead 0x53AD8 -#define ZLib_GRWrite 0x53AD9 -#define ZLib_GZFlush 0x53ADA -#define ZLib_GZClose 0x53ADB -#define ZLib_GZError 0x53ADC -#define ZLib_GZSeek 0x53ADD -#define ZLib_GZTell 0x53ADE -#define ZLib_GZEOF 0x53ADF -#define ZLib_TaskAssociate 0x53AE0 - -#define crc32(r0,r1,r2) \ - _swi(ZLib_CRC32, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define adler32(r0,r1,r2) \ - _swi(ZLib_Adler32, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define zlibVersion() \ - _swi(ZLib_Version, _RETURN(0)) -#define compress(r0,r1,r2,r3) \ - _swi(ZLib_ZCompress, _INR(0,3) | _RETURN(0)|_OUT(1), r0,r1,r2,r3, &r1) -#define compress2(r0,r1,r2,r3,r4) \ - _swi(ZLib_ZCompress2, _INR(0,4) | _RETURN(0)|_OUT(1), r0,r1,r2,r3,r4, &r1) -#define uncompress(r0,r1,r2,r3) \ - _swi(ZLib_ZUncompress, _INR(0,3) | _RETURN(0)|_OUT(1), r0,r1,r2,r3, &r1) -#define deflateInit_(r0,r1,r2,r3) \ - _swi(ZLib_DeflateInit, _INR(0,3) | _RETURN(0), r0,r1,r2,r3) -#define inflateInit_(r0,r1,r2) \ - _swi(ZLib_InflateInit, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define deflateInit2_(r0,r1,r2,r3,r4,r5,r6,r7) \ - _swi(ZLib_DeflateInit2, _INR(0,7) | _RETURN(0), r0,r1,r2,r3,r4,r5,r6,r7) -#define inflateInit2_(r0,r1,r2,r3) \ - _swi(ZLib_InflateInit2, _INR(0,3) | _RETURN(0), r0,r1,r2,r3) -#define deflate(r0,r1) \ - _swi(ZLib_Deflate, _INR(0,1) | _RETURN(0), r0,r1) -#define deflateEnd(r0) \ - _swi(ZLib_DeflateEnd, _IN(0) | _RETURN(0), r0) -#define inflate(r0,r1) \ - _swi(ZLib_Inflate, _INR(0,1) | _RETURN(0), r0,r1) -#define inflateEnd(r0) \ - _swi(ZLib_InflateEnd, _IN(0) | _RETURN(0), r0) -#define deflateSetDictionary(r0,r1,r2) \ - _swi(ZLib_DeflateSetDictionary, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define deflateCopy(r0,r1) \ - _swi(ZLib_DeflateCopy, _INR(0,1) | _RETURN(0), r0,r1) -#define deflateReset(r0) \ - _swi(ZLib_DeflateReset, _IN(0) | _RETURN(0), r0) -#define deflateParams(r0,r1,r2) \ - _swi(ZLib_DeflateParams, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define inflateSetDictionary(r0,r1,r2) \ - _swi(ZLib_InflateSetDictionary, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define inflateSync(r0) \ - _swi(ZLib_InflateSync, _IN(0) | _RETURN(0), r0) -#define inflateReset(r0) \ - _swi(ZLib_InflateReset, _IN(0) | _RETURN(0), r0) -#define gzopen(r0,r1) \ - _swi(ZLib_GZOpen, _INR(0,1) | _RETURN(0), r0) -#define gzdopen(r0,r1) BUG() -#define gzsetparams(r0,r1,r2) BUG() -#define gzread(r0,r1,r2) \ - _swi(ZLib_GZRead, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define gzwrite(r0,r1,r2) \ - _swi(ZLib_GZWrite, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define gzprintf(r0,r1,...) BUG() -#define gzputs(r0,r1) BUG() -#define gzgets(r0,r1,r2) BUG() -#define gzputc(r0,r1) BUG() -#define gzgetc(r0) BUG() -#define gzflush(r0,r1) \ - _swi(ZLib_GZFlush, _INR(0,1) | _RETURN(0), r0,r1) -#define gzclose(r0) \ - _swi(ZLib_GZClose, _IN(0) | _RETURN(0), r0) -#define gzerror(r0,r1) \ - _swi(ZLib_GZError, _IN(0) | _RETURN(0)|_OUT(1), r0, &r1) -#define gzseek(r0,r1,r2) \ - _swi(ZLib_GZSeek, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define gzrewind(r0) BUG() -#define gztell(r0) \ - _swi(ZLib_GZTell, _IN(0) | _RETURN(0), r0) -#define gzeof(r0) \ - _swi(ZLib_GZEOF, _IN(0) | _RETURN(0), r0) - -#endif /* G10_ZLIB_RISCOS_H */ diff --git a/intl/ChangeLog b/intl/ChangeLog deleted file mode 100644 index eed2d21a4..000000000 --- a/intl/ChangeLog +++ /dev/null @@ -1,4 +0,0 @@ -2003-05-22 GNU <bug-gnu-gettext@gnu.org> - - * Version 0.12.1 released. - diff --git a/intl/Makefile.in b/intl/Makefile.in deleted file mode 100644 index 882396481..000000000 --- a/intl/Makefile.in +++ /dev/null @@ -1,479 +0,0 @@ -# Makefile for directory with message catalog handling library of GNU gettext -# Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Library General Public License as published -# by the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA. - -PACKAGE = @PACKAGE@ -VERSION = @VERSION@ - -SHELL = /bin/sh - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -top_builddir = .. -VPATH = $(srcdir) - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -transform = @program_transform_name@ -libdir = @libdir@ -includedir = @includedir@ -datadir = @datadir@ -localedir = $(datadir)/locale -gettextsrcdir = $(datadir)/gettext/intl -aliaspath = $(localedir) -subdir = intl - -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -mkinstalldirs = $(SHELL) $(MKINSTALLDIRS) - -l = @INTL_LIBTOOL_SUFFIX_PREFIX@ - -AR = ar -CC = @CC@ -LIBTOOL = @LIBTOOL@ -RANLIB = @RANLIB@ -YACC = @INTLBISON@ -y -d -YFLAGS = --name-prefix=__gettext - -DEFS = -DLOCALEDIR=\"$(localedir)\" -DLOCALE_ALIAS_PATH=\"$(aliaspath)\" \ --DLIBDIR=\"$(libdir)\" -DIN_LIBINTL \ --DENABLE_RELOCATABLE=1 -DIN_LIBRARY -DINSTALLDIR=\"$(libdir)\" -DNO_XMALLOC \ --Dset_relocation_prefix=libintl_set_relocation_prefix \ --Drelocate=libintl_relocate \ --DDEPENDS_ON_LIBICONV=1 @DEFS@ -CPPFLAGS = @CPPFLAGS@ -CFLAGS = @CFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ - -COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) - -HEADERS = \ - gmo.h \ - gettextP.h \ - hash-string.h \ - loadinfo.h \ - plural-exp.h \ - eval-plural.h \ - localcharset.h \ - relocatable.h \ - os2compat.h \ - libgnuintl.h.in -SOURCES = \ - bindtextdom.c \ - dcgettext.c \ - dgettext.c \ - gettext.c \ - finddomain.c \ - loadmsgcat.c \ - localealias.c \ - textdomain.c \ - l10nflist.c \ - explodename.c \ - dcigettext.c \ - dcngettext.c \ - dngettext.c \ - ngettext.c \ - plural.y \ - plural-exp.c \ - localcharset.c \ - relocatable.c \ - localename.c \ - log.c \ - osdep.c \ - os2compat.c \ - intl-compat.c -OBJECTS = \ - bindtextdom.$lo \ - dcgettext.$lo \ - dgettext.$lo \ - gettext.$lo \ - finddomain.$lo \ - loadmsgcat.$lo \ - localealias.$lo \ - textdomain.$lo \ - l10nflist.$lo \ - explodename.$lo \ - dcigettext.$lo \ - dcngettext.$lo \ - dngettext.$lo \ - ngettext.$lo \ - plural.$lo \ - plural-exp.$lo \ - localcharset.$lo \ - relocatable.$lo \ - localename.$lo \ - log.$lo \ - osdep.$lo \ - intl-compat.$lo -DISTFILES.common = Makefile.in \ -config.charset locale.alias ref-add.sin ref-del.sin $(HEADERS) $(SOURCES) -DISTFILES.generated = plural.c -DISTFILES.normal = VERSION -DISTFILES.gettext = COPYING.LIB-2.0 COPYING.LIB-2.1 libintl.glibc \ -Makefile.vms libgnuintl.h.msvc-shared README.woe32 Makefile.msvc -DISTFILES.obsolete = xopen-msg.sed linux-msg.sed po2tbl.sed.in cat-compat.c \ -COPYING.LIB-2 gettext.h libgettext.h plural-eval.c libgnuintl.h - -all: all-@USE_INCLUDED_LIBINTL@ -all-yes: libintl.$la libintl.h charset.alias ref-add.sed ref-del.sed -all-no: all-no-@BUILD_INCLUDED_LIBINTL@ -all-no-yes: libgnuintl.$la -all-no-no: - -libintl.a libgnuintl.a: $(OBJECTS) - rm -f $@ - $(AR) cru $@ $(OBJECTS) - $(RANLIB) $@ - -libintl.la libgnuintl.la: $(OBJECTS) - $(LIBTOOL) --mode=link \ - $(CC) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) $(LDFLAGS) -o $@ \ - $(OBJECTS) @LTLIBICONV@ $(LIBS) -lc \ - -version-info $(LTV_CURRENT):$(LTV_REVISION):$(LTV_AGE) \ - -rpath $(libdir) \ - -no-undefined - -# Libtool's library version information for libintl. -# Before making a gettext release, the gettext maintainer must change this -# according to the libtool documentation, section "Library interface versions". -# Maintainers of other packages that include the intl directory must *not* -# change these values. -LTV_CURRENT=5 -LTV_REVISION=0 -LTV_AGE=3 - -.SUFFIXES: -.SUFFIXES: .c .y .o .lo .sin .sed - -.c.o: - $(COMPILE) $< - -.y.c: - $(YACC) $(YFLAGS) --output $@ $< - rm -f $*.h - -bindtextdom.lo: $(srcdir)/bindtextdom.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/bindtextdom.c -dcgettext.lo: $(srcdir)/dcgettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcgettext.c -dgettext.lo: $(srcdir)/dgettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dgettext.c -gettext.lo: $(srcdir)/gettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/gettext.c -finddomain.lo: $(srcdir)/finddomain.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/finddomain.c -loadmsgcat.lo: $(srcdir)/loadmsgcat.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/loadmsgcat.c -localealias.lo: $(srcdir)/localealias.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localealias.c -textdomain.lo: $(srcdir)/textdomain.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/textdomain.c -l10nflist.lo: $(srcdir)/l10nflist.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/l10nflist.c -explodename.lo: $(srcdir)/explodename.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/explodename.c -dcigettext.lo: $(srcdir)/dcigettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcigettext.c -dcngettext.lo: $(srcdir)/dcngettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcngettext.c -dngettext.lo: $(srcdir)/dngettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dngettext.c -ngettext.lo: $(srcdir)/ngettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/ngettext.c -plural.lo: $(srcdir)/plural.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/plural.c -plural-exp.lo: $(srcdir)/plural-exp.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/plural-exp.c -localcharset.lo: $(srcdir)/localcharset.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localcharset.c -relocatable.lo: $(srcdir)/relocatable.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/relocatable.c -localename.lo: $(srcdir)/localename.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localename.c -log.lo: $(srcdir)/log.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/log.c -osdep.lo: $(srcdir)/osdep.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/osdep.c -intl-compat.lo: $(srcdir)/intl-compat.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/intl-compat.c - -ref-add.sed: $(srcdir)/ref-add.sin - sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-add.sin > t-ref-add.sed - mv t-ref-add.sed ref-add.sed -ref-del.sed: $(srcdir)/ref-del.sin - sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-del.sin > t-ref-del.sed - mv t-ref-del.sed ref-del.sed - -INCLUDES = -I. -I$(srcdir) -I.. - -libgnuintl.h: $(srcdir)/libgnuintl.h.in - cp $(srcdir)/libgnuintl.h.in libgnuintl.h - -libintl.h: libgnuintl.h - cp libgnuintl.h libintl.h - -charset.alias: $(srcdir)/config.charset - $(SHELL) $(srcdir)/config.charset '@host@' > t-$@ - mv t-$@ $@ - -check: all - -# We must not install the libintl.h/libintl.a files if we are on a -# system which has the GNU gettext() function in its C library or in a -# separate library. -# If you want to use the one which comes with this version of the -# package, you have to use `configure --with-included-gettext'. -install: install-exec install-data -install-exec: all - if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \ - && test '@USE_INCLUDED_LIBINTL@' = yes; then \ - $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \ - $(INSTALL_DATA) libintl.h $(DESTDIR)$(includedir)/libintl.h; \ - $(LIBTOOL) --mode=install \ - $(INSTALL_DATA) libintl.$la $(DESTDIR)$(libdir)/libintl.$la; \ - if test "@RELOCATABLE@" = yes; then \ - dependencies=`sed -n -e 's,^dependency_libs=\(.*\),\1,p' < $(DESTDIR)$(libdir)/libintl.la | sed -e "s,^',," -e "s,'\$$,,"`; \ - if test -n "$dependencies"; then \ - rm -f $(DESTDIR)$(libdir)/libintl.la; \ - fi; \ - fi; \ - else \ - : ; \ - fi - if test "$(PACKAGE)" = "gettext-tools" \ - && test '@USE_INCLUDED_LIBINTL@' = no; then \ - $(mkinstalldirs) $(DESTDIR)$(libdir); \ - $(LIBTOOL) --mode=install \ - $(INSTALL_DATA) libgnuintl.$la $(DESTDIR)$(libdir)/libgnuintl.$la; \ - rm -f $(DESTDIR)$(libdir)/preloadable_libintl.so; \ - $(INSTALL_DATA) $(DESTDIR)$(libdir)/libgnuintl.so $(DESTDIR)$(libdir)/preloadable_libintl.so; \ - $(LIBTOOL) --mode=uninstall \ - rm -f $(DESTDIR)$(libdir)/libgnuintl.$la; \ - else \ - : ; \ - fi - if test '@USE_INCLUDED_LIBINTL@' = yes; then \ - test @GLIBC21@ != no || $(mkinstalldirs) $(DESTDIR)$(libdir); \ - temp=$(DESTDIR)$(libdir)/t-charset.alias; \ - dest=$(DESTDIR)$(libdir)/charset.alias; \ - if test -f $(DESTDIR)$(libdir)/charset.alias; then \ - orig=$(DESTDIR)$(libdir)/charset.alias; \ - sed -f ref-add.sed $$orig > $$temp; \ - $(INSTALL_DATA) $$temp $$dest; \ - rm -f $$temp; \ - else \ - if test @GLIBC21@ = no; then \ - orig=charset.alias; \ - sed -f ref-add.sed $$orig > $$temp; \ - $(INSTALL_DATA) $$temp $$dest; \ - rm -f $$temp; \ - fi; \ - fi; \ - $(mkinstalldirs) $(DESTDIR)$(localedir); \ - test -f $(DESTDIR)$(localedir)/locale.alias \ - && orig=$(DESTDIR)$(localedir)/locale.alias \ - || orig=$(srcdir)/locale.alias; \ - temp=$(DESTDIR)$(localedir)/t-locale.alias; \ - dest=$(DESTDIR)$(localedir)/locale.alias; \ - sed -f ref-add.sed $$orig > $$temp; \ - $(INSTALL_DATA) $$temp $$dest; \ - rm -f $$temp; \ - else \ - : ; \ - fi -install-data: all - if test "$(PACKAGE)" = "gettext-tools"; then \ - $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ - $(INSTALL_DATA) VERSION $(DESTDIR)$(gettextsrcdir)/VERSION; \ - $(INSTALL_DATA) ChangeLog.inst $(DESTDIR)$(gettextsrcdir)/ChangeLog; \ - dists="COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common)"; \ - for file in $$dists; do \ - $(INSTALL_DATA) $(srcdir)/$$file \ - $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - chmod a+x $(DESTDIR)$(gettextsrcdir)/config.charset; \ - dists="$(DISTFILES.generated)"; \ - for file in $$dists; do \ - if test -f $$file; then dir=.; else dir=$(srcdir); fi; \ - $(INSTALL_DATA) $$dir/$$file \ - $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - dists="$(DISTFILES.obsolete)"; \ - for file in $$dists; do \ - rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - else \ - : ; \ - fi - -install-strip: install - -installdirs: - if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \ - && test '@USE_INCLUDED_LIBINTL@' = yes; then \ - $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \ - else \ - : ; \ - fi - if test "$(PACKAGE)" = "gettext-tools" \ - && test '@USE_INCLUDED_LIBINTL@' = no; then \ - $(mkinstalldirs) $(DESTDIR)$(libdir); \ - else \ - : ; \ - fi - if test '@USE_INCLUDED_LIBINTL@' = yes; then \ - test @GLIBC21@ != no || $(mkinstalldirs) $(DESTDIR)$(libdir); \ - $(mkinstalldirs) $(DESTDIR)$(localedir); \ - else \ - : ; \ - fi - if test "$(PACKAGE)" = "gettext-tools"; then \ - $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ - else \ - : ; \ - fi - -# Define this as empty until I found a useful application. -installcheck: - -uninstall: - if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \ - && test '@USE_INCLUDED_LIBINTL@' = yes; then \ - rm -f $(DESTDIR)$(includedir)/libintl.h; \ - $(LIBTOOL) --mode=uninstall \ - rm -f $(DESTDIR)$(libdir)/libintl.$la; \ - else \ - : ; \ - fi - if test "$(PACKAGE)" = "gettext-tools" \ - && test '@USE_INCLUDED_LIBINTL@' = no; then \ - rm -f $(DESTDIR)$(libdir)/preloadable_libintl.so; \ - else \ - : ; \ - fi - if test '@USE_INCLUDED_LIBINTL@' = yes; then \ - if test -f $(DESTDIR)$(libdir)/charset.alias; then \ - temp=$(DESTDIR)$(libdir)/t-charset.alias; \ - dest=$(DESTDIR)$(libdir)/charset.alias; \ - sed -f ref-del.sed $$dest > $$temp; \ - if grep '^# Packages using this file: $$' $$temp > /dev/null; then \ - rm -f $$dest; \ - else \ - $(INSTALL_DATA) $$temp $$dest; \ - fi; \ - rm -f $$temp; \ - fi; \ - if test -f $(DESTDIR)$(localedir)/locale.alias; then \ - temp=$(DESTDIR)$(localedir)/t-locale.alias; \ - dest=$(DESTDIR)$(localedir)/locale.alias; \ - sed -f ref-del.sed $$dest > $$temp; \ - if grep '^# Packages using this file: $$' $$temp > /dev/null; then \ - rm -f $$dest; \ - else \ - $(INSTALL_DATA) $$temp $$dest; \ - fi; \ - rm -f $$temp; \ - fi; \ - else \ - : ; \ - fi - if test "$(PACKAGE)" = "gettext-tools"; then \ - for file in VERSION ChangeLog COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common) $(DISTFILES.generated); do \ - rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - else \ - : ; \ - fi - -info dvi ps pdf html: - -$(OBJECTS): ../config.h libgnuintl.h -bindtextdom.$lo dcgettext.$lo dcigettext.$lo dcngettext.$lo dgettext.$lo dngettext.$lo finddomain.$lo gettext.$lo intl-compat.$lo loadmsgcat.$lo localealias.$lo ngettext.$lo textdomain.$lo: $(srcdir)/gettextP.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h -dcigettext.$lo loadmsgcat.$lo: $(srcdir)/hash-string.h -explodename.$lo l10nflist.$lo: $(srcdir)/loadinfo.h -dcigettext.$lo loadmsgcat.$lo plural.$lo plural-exp.$lo: $(srcdir)/plural-exp.h -dcigettext.$lo: $(srcdir)/eval-plural.h -localcharset.$lo: $(srcdir)/localcharset.h -localealias.$lo localcharset.$lo relocatable.$lo: $(srcdir)/relocatable.h - -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) - here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES) - -ctags: CTAGS - -CTAGS: $(HEADERS) $(SOURCES) - here=`pwd`; cd $(srcdir) && ctags -o $$here/CTAGS $(HEADERS) $(SOURCES) - -id: ID - -ID: $(HEADERS) $(SOURCES) - here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES) - - -mostlyclean: - rm -f *.a *.la *.o *.obj *.lo core core.* - rm -f libgnuintl.h libintl.h charset.alias ref-add.sed ref-del.sed - rm -f -r .libs _libs - -clean: mostlyclean - -distclean: clean - rm -f Makefile ID TAGS - if test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; then \ - rm -f ChangeLog.inst $(DISTFILES.normal); \ - else \ - : ; \ - fi - -maintainer-clean: distclean - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - - -# GNU gettext needs not contain the file `VERSION' but contains some -# other files which should not be distributed in other packages. -distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) -dist distdir: Makefile - if test "$(PACKAGE)" = "gettext-tools"; then \ - : ; \ - else \ - if test "$(PACKAGE)" = "gettext-runtime"; then \ - additional="$(DISTFILES.gettext)"; \ - else \ - additional="$(DISTFILES.normal)"; \ - fi; \ - $(MAKE) $(DISTFILES.common) $(DISTFILES.generated) $$additional; \ - for file in ChangeLog $(DISTFILES.common) $(DISTFILES.generated) $$additional; do \ - if test -f $$file; then dir=.; else dir=$(srcdir); fi; \ - cp -p $$dir/$$file $(distdir); \ - done; \ - fi - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status -# This would be more efficient, but doesn't work any more with autoconf-2.57, -# when AC_CONFIG_FILES([intl/Makefile:somedir/Makefile.in]) is used. -# cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - -# Tell versions [3.59,3.63) of GNU make not to export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/intl/VERSION b/intl/VERSION deleted file mode 100644 index 130318357..000000000 --- a/intl/VERSION +++ /dev/null @@ -1 +0,0 @@ -GNU gettext library from gettext-0.12.1 diff --git a/intl/bindtextdom.c b/intl/bindtextdom.c deleted file mode 100644 index 250f5e863..000000000 --- a/intl/bindtextdom.c +++ /dev/null @@ -1,374 +0,0 @@ -/* Implementation of the bindtextdomain(3) function - Copyright (C) 1995-1998, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif -#include "gettextP.h" - -#ifdef _LIBC -/* We have to handle multi-threaded applications. */ -# include <bits/libc-lock.h> -#else -/* Provide dummy implementation if this is outside glibc. */ -# define __libc_rwlock_define(CLASS, NAME) -# define __libc_rwlock_wrlock(NAME) -# define __libc_rwlock_unlock(NAME) -#endif - -/* The internal variables in the standalone libintl.a must have different - names than the internal variables in GNU libc, otherwise programs - using libintl.a cannot be linked statically. */ -#if !defined _LIBC -# define _nl_default_dirname libintl_nl_default_dirname -# define _nl_domain_bindings libintl_nl_domain_bindings -#endif - -/* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */ -#ifndef offsetof -# define offsetof(type,ident) ((size_t)&(((type*)0)->ident)) -#endif - -/* @@ end of prolog @@ */ - -/* Contains the default location of the message catalogs. */ -extern const char _nl_default_dirname[]; -#ifdef _LIBC -extern const char _nl_default_dirname_internal[] attribute_hidden; -#else -# define INTUSE(name) name -#endif - -/* List with bindings of specific domains. */ -extern struct binding *_nl_domain_bindings; - -/* Lock variable to protect the global data in the gettext implementation. */ -__libc_rwlock_define (extern, _nl_state_lock attribute_hidden) - - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define BINDTEXTDOMAIN __bindtextdomain -# define BIND_TEXTDOMAIN_CODESET __bind_textdomain_codeset -# ifndef strdup -# define strdup(str) __strdup (str) -# endif -#else -# define BINDTEXTDOMAIN libintl_bindtextdomain -# define BIND_TEXTDOMAIN_CODESET libintl_bind_textdomain_codeset -#endif - -/* Prototypes for local functions. */ -static void set_binding_values PARAMS ((const char *domainname, - const char **dirnamep, - const char **codesetp)); - -/* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP - to be used for the DOMAINNAME message catalog. - If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not - modified, only the current value is returned. - If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither - modified nor returned. */ -static void -set_binding_values (domainname, dirnamep, codesetp) - const char *domainname; - const char **dirnamep; - const char **codesetp; -{ - struct binding *binding; - int modified; - - /* Some sanity checks. */ - if (domainname == NULL || domainname[0] == '\0') - { - if (dirnamep) - *dirnamep = NULL; - if (codesetp) - *codesetp = NULL; - return; - } - - __libc_rwlock_wrlock (_nl_state_lock); - - modified = 0; - - for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) - { - int compare = strcmp (domainname, binding->domainname); - if (compare == 0) - /* We found it! */ - break; - if (compare < 0) - { - /* It is not in the list. */ - binding = NULL; - break; - } - } - - if (binding != NULL) - { - if (dirnamep) - { - const char *dirname = *dirnamep; - - if (dirname == NULL) - /* The current binding has be to returned. */ - *dirnamep = binding->dirname; - else - { - /* The domain is already bound. If the new value and the old - one are equal we simply do nothing. Otherwise replace the - old binding. */ - char *result = binding->dirname; - if (strcmp (dirname, result) != 0) - { - if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0) - result = (char *) INTUSE(_nl_default_dirname); - else - { -#if defined _LIBC || defined HAVE_STRDUP - result = strdup (dirname); -#else - size_t len = strlen (dirname) + 1; - result = (char *) malloc (len); - if (__builtin_expect (result != NULL, 1)) - memcpy (result, dirname, len); -#endif - } - - if (__builtin_expect (result != NULL, 1)) - { - if (binding->dirname != INTUSE(_nl_default_dirname)) - free (binding->dirname); - - binding->dirname = result; - modified = 1; - } - } - *dirnamep = result; - } - } - - if (codesetp) - { - const char *codeset = *codesetp; - - if (codeset == NULL) - /* The current binding has be to returned. */ - *codesetp = binding->codeset; - else - { - /* The domain is already bound. If the new value and the old - one are equal we simply do nothing. Otherwise replace the - old binding. */ - char *result = binding->codeset; - if (result == NULL || strcmp (codeset, result) != 0) - { -#if defined _LIBC || defined HAVE_STRDUP - result = strdup (codeset); -#else - size_t len = strlen (codeset) + 1; - result = (char *) malloc (len); - if (__builtin_expect (result != NULL, 1)) - memcpy (result, codeset, len); -#endif - - if (__builtin_expect (result != NULL, 1)) - { - if (binding->codeset != NULL) - free (binding->codeset); - - binding->codeset = result; - binding->codeset_cntr++; - modified = 1; - } - } - *codesetp = result; - } - } - } - else if ((dirnamep == NULL || *dirnamep == NULL) - && (codesetp == NULL || *codesetp == NULL)) - { - /* Simply return the default values. */ - if (dirnamep) - *dirnamep = INTUSE(_nl_default_dirname); - if (codesetp) - *codesetp = NULL; - } - else - { - /* We have to create a new binding. */ - size_t len = strlen (domainname) + 1; - struct binding *new_binding = - (struct binding *) malloc (offsetof (struct binding, domainname) + len); - - if (__builtin_expect (new_binding == NULL, 0)) - goto failed; - - memcpy (new_binding->domainname, domainname, len); - - if (dirnamep) - { - const char *dirname = *dirnamep; - - if (dirname == NULL) - /* The default value. */ - dirname = INTUSE(_nl_default_dirname); - else - { - if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0) - dirname = INTUSE(_nl_default_dirname); - else - { - char *result; -#if defined _LIBC || defined HAVE_STRDUP - result = strdup (dirname); - if (__builtin_expect (result == NULL, 0)) - goto failed_dirname; -#else - size_t len = strlen (dirname) + 1; - result = (char *) malloc (len); - if (__builtin_expect (result == NULL, 0)) - goto failed_dirname; - memcpy (result, dirname, len); -#endif - dirname = result; - } - } - *dirnamep = dirname; - new_binding->dirname = (char *) dirname; - } - else - /* The default value. */ - new_binding->dirname = (char *) INTUSE(_nl_default_dirname); - - new_binding->codeset_cntr = 0; - - if (codesetp) - { - const char *codeset = *codesetp; - - if (codeset != NULL) - { - char *result; - -#if defined _LIBC || defined HAVE_STRDUP - result = strdup (codeset); - if (__builtin_expect (result == NULL, 0)) - goto failed_codeset; -#else - size_t len = strlen (codeset) + 1; - result = (char *) malloc (len); - if (__builtin_expect (result == NULL, 0)) - goto failed_codeset; - memcpy (result, codeset, len); -#endif - codeset = result; - new_binding->codeset_cntr++; - } - *codesetp = codeset; - new_binding->codeset = (char *) codeset; - } - else - new_binding->codeset = NULL; - - /* Now enqueue it. */ - if (_nl_domain_bindings == NULL - || strcmp (domainname, _nl_domain_bindings->domainname) < 0) - { - new_binding->next = _nl_domain_bindings; - _nl_domain_bindings = new_binding; - } - else - { - binding = _nl_domain_bindings; - while (binding->next != NULL - && strcmp (domainname, binding->next->domainname) > 0) - binding = binding->next; - - new_binding->next = binding->next; - binding->next = new_binding; - } - - modified = 1; - - /* Here we deal with memory allocation failures. */ - if (0) - { - failed_codeset: - if (new_binding->dirname != INTUSE(_nl_default_dirname)) - free (new_binding->dirname); - failed_dirname: - free (new_binding); - failed: - if (dirnamep) - *dirnamep = NULL; - if (codesetp) - *codesetp = NULL; - } - } - - /* If we modified any binding, we flush the caches. */ - if (modified) - ++_nl_msg_cat_cntr; - - __libc_rwlock_unlock (_nl_state_lock); -} - -/* Specify that the DOMAINNAME message catalog will be found - in DIRNAME rather than in the system locale data base. */ -char * -BINDTEXTDOMAIN (domainname, dirname) - const char *domainname; - const char *dirname; -{ - set_binding_values (domainname, &dirname, NULL); - return (char *) dirname; -} - -/* Specify the character encoding in which the messages from the - DOMAINNAME message catalog will be returned. */ -char * -BIND_TEXTDOMAIN_CODESET (domainname, codeset) - const char *domainname; - const char *codeset; -{ - set_binding_values (domainname, NULL, &codeset); - return (char *) codeset; -} - -#ifdef _LIBC -/* Aliases for function names in GNU C Library. */ -weak_alias (__bindtextdomain, bindtextdomain); -weak_alias (__bind_textdomain_codeset, bind_textdomain_codeset); -#endif diff --git a/intl/config.charset b/intl/config.charset deleted file mode 100755 index 32becece9..000000000 --- a/intl/config.charset +++ /dev/null @@ -1,467 +0,0 @@ -#! /bin/sh -# Output a system dependent table of character encoding aliases. -# -# Copyright (C) 2000-2003 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Library General Public License as published -# by the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA. -# -# The table consists of lines of the form -# ALIAS CANONICAL -# -# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)". -# ALIAS is compared in a case sensitive way. -# -# CANONICAL is the GNU canonical name for this character encoding. -# It must be an encoding supported by libiconv. Support by GNU libc is -# also desirable. CANONICAL is case insensitive. Usually an upper case -# MIME charset name is preferred. -# The current list of GNU canonical charset names is as follows. -# -# name used by which systems a MIME name? -# ASCII, ANSI_X3.4-1968 glibc solaris freebsd -# ISO-8859-1 glibc aix hpux irix osf solaris freebsd yes -# ISO-8859-2 glibc aix hpux irix osf solaris freebsd yes -# ISO-8859-3 glibc solaris yes -# ISO-8859-4 osf solaris freebsd yes -# ISO-8859-5 glibc aix hpux irix osf solaris freebsd yes -# ISO-8859-6 glibc aix hpux solaris yes -# ISO-8859-7 glibc aix hpux irix osf solaris yes -# ISO-8859-8 glibc aix hpux osf solaris yes -# ISO-8859-9 glibc aix hpux irix osf solaris yes -# ISO-8859-13 glibc -# ISO-8859-14 glibc -# ISO-8859-15 glibc aix osf solaris freebsd -# KOI8-R glibc solaris freebsd yes -# KOI8-U glibc freebsd yes -# KOI8-T glibc -# CP437 dos -# CP775 dos -# CP850 aix osf dos -# CP852 dos -# CP855 dos -# CP856 aix -# CP857 dos -# CP861 dos -# CP862 dos -# CP864 dos -# CP865 dos -# CP866 freebsd dos -# CP869 dos -# CP874 woe32 dos -# CP922 aix -# CP932 aix woe32 dos -# CP943 aix -# CP949 osf woe32 dos -# CP950 woe32 dos -# CP1046 aix -# CP1124 aix -# CP1125 dos -# CP1129 aix -# CP1250 woe32 -# CP1251 glibc solaris woe32 -# CP1252 aix woe32 -# CP1253 woe32 -# CP1254 woe32 -# CP1255 glibc woe32 -# CP1256 woe32 -# CP1257 woe32 -# GB2312 glibc aix hpux irix solaris freebsd yes -# EUC-JP glibc aix hpux irix osf solaris freebsd yes -# EUC-KR glibc aix hpux irix osf solaris freebsd yes -# EUC-TW glibc aix hpux irix osf solaris -# BIG5 glibc aix hpux osf solaris freebsd yes -# BIG5-HKSCS glibc solaris -# GBK glibc aix osf solaris woe32 dos -# GB18030 glibc solaris -# SHIFT_JIS hpux osf solaris freebsd yes -# JOHAB glibc solaris woe32 -# TIS-620 glibc aix hpux osf solaris -# VISCII glibc yes -# TCVN5712-1 glibc -# GEORGIAN-PS glibc -# HP-ROMAN8 hpux -# HP-ARABIC8 hpux -# HP-GREEK8 hpux -# HP-HEBREW8 hpux -# HP-TURKISH8 hpux -# HP-KANA8 hpux -# DEC-KANJI osf -# DEC-HANYU osf -# UTF-8 glibc aix hpux osf solaris yes -# -# Note: Names which are not marked as being a MIME name should not be used in -# Internet protocols for information interchange (mail, news, etc.). -# -# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications -# must understand both names and treat them as equivalent. -# -# The first argument passed to this file is the canonical host specification, -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM - -host="$1" -os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'` -echo "# This file contains a table of character encoding aliases," -echo "# suitable for operating system '${os}'." -echo "# It was automatically generated from config.charset." -# List of references, updated during installation: -echo "# Packages using this file: " -case "$os" in - linux* | *-gnu*) - # With glibc-2.1 or newer, we don't need any canonicalization, - # because glibc has iconv and both glibc and libiconv support all - # GNU canonical names directly. Therefore, the Makefile does not - # need to install the alias file at all. - # The following applies only to glibc-2.0.x and older libcs. - echo "ISO_646.IRV:1983 ASCII" - ;; - aix*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-6 ISO-8859-6" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "IBM-850 CP850" - echo "IBM-856 CP856" - echo "IBM-921 ISO-8859-13" - echo "IBM-922 CP922" - echo "IBM-932 CP932" - echo "IBM-943 CP943" - echo "IBM-1046 CP1046" - echo "IBM-1124 CP1124" - echo "IBM-1129 CP1129" - echo "IBM-1252 CP1252" - echo "IBM-eucCN GB2312" - echo "IBM-eucJP EUC-JP" - echo "IBM-eucKR EUC-KR" - echo "IBM-eucTW EUC-TW" - echo "big5 BIG5" - echo "GBK GBK" - echo "TIS-620 TIS-620" - echo "UTF-8 UTF-8" - ;; - hpux*) - echo "iso88591 ISO-8859-1" - echo "iso88592 ISO-8859-2" - echo "iso88595 ISO-8859-5" - echo "iso88596 ISO-8859-6" - echo "iso88597 ISO-8859-7" - echo "iso88598 ISO-8859-8" - echo "iso88599 ISO-8859-9" - echo "iso885915 ISO-8859-15" - echo "roman8 HP-ROMAN8" - echo "arabic8 HP-ARABIC8" - echo "greek8 HP-GREEK8" - echo "hebrew8 HP-HEBREW8" - echo "turkish8 HP-TURKISH8" - echo "kana8 HP-KANA8" - echo "tis620 TIS-620" - echo "big5 BIG5" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "hp15CN GB2312" - #echo "ccdc ?" # what is this? - echo "SJIS SHIFT_JIS" - echo "utf8 UTF-8" - ;; - irix*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-9 ISO-8859-9" - echo "eucCN GB2312" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - ;; - osf*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "cp850 CP850" - echo "big5 BIG5" - echo "dechanyu DEC-HANYU" - echo "dechanzi GB2312" - echo "deckanji DEC-KANJI" - echo "deckorean EUC-KR" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "GBK GBK" - echo "KSC5601 CP949" - echo "sdeckanji EUC-JP" - echo "SJIS SHIFT_JIS" - echo "TACTIS TIS-620" - echo "UTF-8 UTF-8" - ;; - solaris*) - echo "646 ASCII" - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-3 ISO-8859-3" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-6 ISO-8859-6" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "koi8-r KOI8-R" - echo "ansi-1251 CP1251" - echo "BIG5 BIG5" - echo "Big5-HKSCS BIG5-HKSCS" - echo "gb2312 GB2312" - echo "GBK GBK" - echo "GB18030 GB18030" - echo "cns11643 EUC-TW" - echo "5601 EUC-KR" - echo "ko_KR.johap92 JOHAB" - echo "eucJP EUC-JP" - echo "PCK SHIFT_JIS" - echo "TIS620.2533 TIS-620" - #echo "sun_eu_greek ?" # what is this? - echo "UTF-8 UTF-8" - ;; - freebsd* | os2*) - # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just - # reuse FreeBSD's locale data for OS/2. - echo "C ASCII" - echo "US-ASCII ASCII" - for l in la_LN lt_LN; do - echo "$l.ASCII ASCII" - done - for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ - fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \ - lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do - echo "$l.ISO_8859-1 ISO-8859-1" - echo "$l.DIS_8859-15 ISO-8859-15" - done - for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do - echo "$l.ISO_8859-2 ISO-8859-2" - done - for l in la_LN lt_LT; do - echo "$l.ISO_8859-4 ISO-8859-4" - done - for l in ru_RU ru_SU; do - echo "$l.KOI8-R KOI8-R" - echo "$l.ISO_8859-5 ISO-8859-5" - echo "$l.CP866 CP866" - done - echo "uk_UA.KOI8-U KOI8-U" - echo "zh_TW.BIG5 BIG5" - echo "zh_TW.Big5 BIG5" - echo "zh_CN.EUC GB2312" - echo "ja_JP.EUC EUC-JP" - echo "ja_JP.SJIS SHIFT_JIS" - echo "ja_JP.Shift_JIS SHIFT_JIS" - echo "ko_KR.EUC EUC-KR" - ;; - netbsd*) - echo "646 ASCII" - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-15 ISO-8859-15" - echo "eucCN GB2312" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "BIG5 BIG5" - echo "SJIS SHIFT_JIS" - ;; - beos*) - # BeOS has a single locale, and it has UTF-8 encoding. - echo "* UTF-8" - ;; - msdosdjgpp*) - # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - echo "#" - echo "# The encodings given here may not all be correct." - echo "# If you find that the encoding given for your language and" - echo "# country is not the one your DOS machine actually uses, just" - echo "# correct it in this file, and send a mail to" - echo "# Juan Manuel Guerrero <st001906@hrz1.hrz.tu-darmstadt.de>" - echo "# and Bruno Haible <bruno@clisp.org>." - echo "#" - echo "C ASCII" - # ISO-8859-1 languages - echo "ca CP850" - echo "ca_ES CP850" - echo "da CP865" # not CP850 ?? - echo "da_DK CP865" # not CP850 ?? - echo "de CP850" - echo "de_AT CP850" - echo "de_CH CP850" - echo "de_DE CP850" - echo "en CP850" - echo "en_AU CP850" # not CP437 ?? - echo "en_CA CP850" - echo "en_GB CP850" - echo "en_NZ CP437" - echo "en_US CP437" - echo "en_ZA CP850" # not CP437 ?? - echo "es CP850" - echo "es_AR CP850" - echo "es_BO CP850" - echo "es_CL CP850" - echo "es_CO CP850" - echo "es_CR CP850" - echo "es_CU CP850" - echo "es_DO CP850" - echo "es_EC CP850" - echo "es_ES CP850" - echo "es_GT CP850" - echo "es_HN CP850" - echo "es_MX CP850" - echo "es_NI CP850" - echo "es_PA CP850" - echo "es_PY CP850" - echo "es_PE CP850" - echo "es_SV CP850" - echo "es_UY CP850" - echo "es_VE CP850" - echo "et CP850" - echo "et_EE CP850" - echo "eu CP850" - echo "eu_ES CP850" - echo "fi CP850" - echo "fi_FI CP850" - echo "fr CP850" - echo "fr_BE CP850" - echo "fr_CA CP850" - echo "fr_CH CP850" - echo "fr_FR CP850" - echo "ga CP850" - echo "ga_IE CP850" - echo "gd CP850" - echo "gd_GB CP850" - echo "gl CP850" - echo "gl_ES CP850" - echo "id CP850" # not CP437 ?? - echo "id_ID CP850" # not CP437 ?? - echo "is CP861" # not CP850 ?? - echo "is_IS CP861" # not CP850 ?? - echo "it CP850" - echo "it_CH CP850" - echo "it_IT CP850" - echo "lt CP775" - echo "lt_LT CP775" - echo "lv CP775" - echo "lv_LV CP775" - echo "nb CP865" # not CP850 ?? - echo "nb_NO CP865" # not CP850 ?? - echo "nl CP850" - echo "nl_BE CP850" - echo "nl_NL CP850" - echo "nn CP865" # not CP850 ?? - echo "nn_NO CP865" # not CP850 ?? - echo "no CP865" # not CP850 ?? - echo "no_NO CP865" # not CP850 ?? - echo "pt CP850" - echo "pt_BR CP850" - echo "pt_PT CP850" - echo "sv CP850" - echo "sv_SE CP850" - # ISO-8859-2 languages - echo "cs CP852" - echo "cs_CZ CP852" - echo "hr CP852" - echo "hr_HR CP852" - echo "hu CP852" - echo "hu_HU CP852" - echo "pl CP852" - echo "pl_PL CP852" - echo "ro CP852" - echo "ro_RO CP852" - echo "sk CP852" - echo "sk_SK CP852" - echo "sl CP852" - echo "sl_SI CP852" - echo "sq CP852" - echo "sq_AL CP852" - echo "sr CP852" # CP852 or CP866 or CP855 ?? - echo "sr_YU CP852" # CP852 or CP866 or CP855 ?? - # ISO-8859-3 languages - echo "mt CP850" - echo "mt_MT CP850" - # ISO-8859-5 languages - echo "be CP866" - echo "be_BE CP866" - echo "bg CP866" # not CP855 ?? - echo "bg_BG CP866" # not CP855 ?? - echo "mk CP866" # not CP855 ?? - echo "mk_MK CP866" # not CP855 ?? - echo "ru CP866" - echo "ru_RU CP866" - echo "uk CP1125" - echo "uk_UA CP1125" - # ISO-8859-6 languages - echo "ar CP864" - echo "ar_AE CP864" - echo "ar_DZ CP864" - echo "ar_EG CP864" - echo "ar_IQ CP864" - echo "ar_IR CP864" - echo "ar_JO CP864" - echo "ar_KW CP864" - echo "ar_MA CP864" - echo "ar_OM CP864" - echo "ar_QA CP864" - echo "ar_SA CP864" - echo "ar_SY CP864" - # ISO-8859-7 languages - echo "el CP869" - echo "el_GR CP869" - # ISO-8859-8 languages - echo "he CP862" - echo "he_IL CP862" - # ISO-8859-9 languages - echo "tr CP857" - echo "tr_TR CP857" - # Japanese - echo "ja CP932" - echo "ja_JP CP932" - # Chinese - echo "zh_CN GBK" - echo "zh_TW CP950" # not CP938 ?? - # Korean - echo "kr CP949" # not CP934 ?? - echo "kr_KR CP949" # not CP934 ?? - # Thai - echo "th CP874" - echo "th_TH CP874" - # Other - echo "eo CP850" - echo "eo_EO CP850" - ;; -esac diff --git a/intl/dcgettext.c b/intl/dcgettext.c deleted file mode 100644 index ca6a1c82d..000000000 --- a/intl/dcgettext.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Implementation of the dcgettext(3) function. - Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define DCGETTEXT __dcgettext -# define DCIGETTEXT __dcigettext -#else -# define DCGETTEXT libintl_dcgettext -# define DCIGETTEXT libintl_dcigettext -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY - locale. */ -char * -DCGETTEXT (domainname, msgid, category) - const char *domainname; - const char *msgid; - int category; -{ - return DCIGETTEXT (domainname, msgid, NULL, 0, 0, category); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -INTDEF(__dcgettext) -weak_alias (__dcgettext, dcgettext); -#endif diff --git a/intl/dcigettext.c b/intl/dcigettext.c deleted file mode 100644 index f6edb95c0..000000000 --- a/intl/dcigettext.c +++ /dev/null @@ -1,1238 +0,0 @@ -/* Implementation of the internal dcigettext function. - Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Tell glibc's <string.h> to provide a prototype for mempcpy(). - This must come before <config.h> because <config.h> may include - <features.h>, and once <features.h> has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <sys/types.h> - -#ifdef __GNUC__ -# define alloca __builtin_alloca -# define HAVE_ALLOCA 1 -#else -# ifdef _MSC_VER -# include <malloc.h> -# define alloca _alloca -# else -# if defined HAVE_ALLOCA_H || defined _LIBC -# include <alloca.h> -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca -char *alloca (); -# endif -# endif -# endif -# endif -#endif - -#include <errno.h> -#ifndef errno -extern int errno; -#endif -#ifndef __set_errno -# define __set_errno(val) errno = (val) -#endif - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -#if defined HAVE_UNISTD_H || defined _LIBC -# include <unistd.h> -#endif - -#include <locale.h> - -#ifdef _LIBC - /* Guess whether integer division by zero raises signal SIGFPE. - Set to 1 only if you know for sure. In case of doubt, set to 0. */ -# if defined __alpha__ || defined __arm__ || defined __i386__ \ - || defined __m68k__ || defined __s390__ -# define INTDIV0_RAISES_SIGFPE 1 -# else -# define INTDIV0_RAISES_SIGFPE 0 -# endif -#endif -#if !INTDIV0_RAISES_SIGFPE -# include <signal.h> -#endif - -#if defined HAVE_SYS_PARAM_H || defined _LIBC -# include <sys/param.h> -#endif - -#include "gettextP.h" -#include "plural-exp.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif -#include "hash-string.h" - -/* Thread safetyness. */ -#ifdef _LIBC -# include <bits/libc-lock.h> -#else -/* Provide dummy implementation if this is outside glibc. */ -# define __libc_lock_define_initialized(CLASS, NAME) -# define __libc_lock_lock(NAME) -# define __libc_lock_unlock(NAME) -# define __libc_rwlock_define_initialized(CLASS, NAME) -# define __libc_rwlock_rdlock(NAME) -# define __libc_rwlock_unlock(NAME) -#endif - -/* Alignment of types. */ -#if defined __GNUC__ && __GNUC__ >= 2 -# define alignof(TYPE) __alignof__ (TYPE) -#else -# define alignof(TYPE) \ - ((int) &((struct { char dummy1; TYPE dummy2; } *) 0)->dummy2) -#endif - -/* The internal variables in the standalone libintl.a must have different - names than the internal variables in GNU libc, otherwise programs - using libintl.a cannot be linked statically. */ -#if !defined _LIBC -# define _nl_default_default_domain libintl_nl_default_default_domain -# define _nl_current_default_domain libintl_nl_current_default_domain -# define _nl_default_dirname libintl_nl_default_dirname -# define _nl_domain_bindings libintl_nl_domain_bindings -#endif - -/* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */ -#ifndef offsetof -# define offsetof(type,ident) ((size_t)&(((type*)0)->ident)) -#endif - -/* @@ end of prolog @@ */ - -#ifdef _LIBC -/* Rename the non ANSI C functions. This is required by the standard - because some ANSI C functions will require linking with this object - file and the name space must not be polluted. */ -# define getcwd __getcwd -# ifndef stpcpy -# define stpcpy __stpcpy -# endif -# define tfind __tfind -#else -# if !defined HAVE_GETCWD -char *getwd (); -# define getcwd(buf, max) getwd (buf) -# else -char *getcwd (); -# endif -# ifndef HAVE_STPCPY -static char *stpcpy PARAMS ((char *dest, const char *src)); -# endif -# ifndef HAVE_MEMPCPY -static void *mempcpy PARAMS ((void *dest, const void *src, size_t n)); -# endif -#endif - -/* Amount to increase buffer size by in each try. */ -#define PATH_INCR 32 - -/* The following is from pathmax.h. */ -/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define - PATH_MAX but might cause redefinition warnings when sys/param.h is - later included (as on MORE/BSD 4.3). */ -#if defined _POSIX_VERSION || (defined HAVE_LIMITS_H && !defined __GNUC__) -# include <limits.h> -#endif - -#ifndef _POSIX_PATH_MAX -# define _POSIX_PATH_MAX 255 -#endif - -#if !defined PATH_MAX && defined _PC_PATH_MAX -# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX)) -#endif - -/* Don't include sys/param.h if it already has been. */ -#if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN -# include <sys/param.h> -#endif - -#if !defined PATH_MAX && defined MAXPATHLEN -# define PATH_MAX MAXPATHLEN -#endif - -#ifndef PATH_MAX -# define PATH_MAX _POSIX_PATH_MAX -#endif - -/* Pathname support. - ISSLASH(C) tests whether C is a directory separator character. - IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not, - it may be concatenated to a directory pathname. - IS_PATH_WITH_DIR(P) tests whether P contains a directory specification. - */ -#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS */ -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -# define HAS_DEVICE(P) \ - ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ - && (P)[1] == ':') -# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P)) -# define IS_PATH_WITH_DIR(P) \ - (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P)) -#else - /* Unix */ -# define ISSLASH(C) ((C) == '/') -# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0]) -# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL) -#endif - -/* This is the type used for the search tree where known translations - are stored. */ -struct known_translation_t -{ - /* Domain in which to search. */ - char *domainname; - - /* The category. */ - int category; - - /* State of the catalog counter at the point the string was found. */ - int counter; - - /* Catalog where the string was found. */ - struct loaded_l10nfile *domain; - - /* And finally the translation. */ - const char *translation; - size_t translation_length; - - /* Pointer to the string in question. */ - char msgid[ZERO]; -}; - -/* Root of the search tree with known translations. We can use this - only if the system provides the `tsearch' function family. */ -#if defined HAVE_TSEARCH || defined _LIBC -# include <search.h> - -static void *root; - -# ifdef _LIBC -# define tsearch __tsearch -# endif - -/* Function to compare two entries in the table of known translations. */ -static int transcmp PARAMS ((const void *p1, const void *p2)); -static int -transcmp (p1, p2) - const void *p1; - const void *p2; -{ - const struct known_translation_t *s1; - const struct known_translation_t *s2; - int result; - - s1 = (const struct known_translation_t *) p1; - s2 = (const struct known_translation_t *) p2; - - result = strcmp (s1->msgid, s2->msgid); - if (result == 0) - { - result = strcmp (s1->domainname, s2->domainname); - if (result == 0) - /* We compare the category last (though this is the cheapest - operation) since it is hopefully always the same (namely - LC_MESSAGES). */ - result = s1->category - s2->category; - } - - return result; -} -#endif - -#ifndef INTVARDEF -# define INTVARDEF(name) -#endif -#ifndef INTUSE -# define INTUSE(name) name -#endif - -/* Name of the default domain used for gettext(3) prior any call to - textdomain(3). The default value for this is "messages". */ -const char _nl_default_default_domain[] attribute_hidden = "messages"; - -/* Value used as the default domain for gettext(3). */ -const char *_nl_current_default_domain attribute_hidden - = _nl_default_default_domain; - -/* Contains the default location of the message catalogs. */ -#if defined __EMX__ -extern const char _nl_default_dirname[]; -#else -const char _nl_default_dirname[] = LOCALEDIR; -INTVARDEF (_nl_default_dirname) -#endif - -/* List with bindings of specific domains created by bindtextdomain() - calls. */ -struct binding *_nl_domain_bindings; - -/* Prototypes for local functions. */ -static char *plural_lookup PARAMS ((struct loaded_l10nfile *domain, - unsigned long int n, - const char *translation, - size_t translation_len)) - internal_function; -static const char *guess_category_value PARAMS ((int category, - const char *categoryname)) - internal_function; -#ifdef _LIBC -# include "../locale/localeinfo.h" -# define category_to_name(category) _nl_category_names[category] -#else -static const char *category_to_name PARAMS ((int category)) internal_function; -#endif - - -/* For those loosing systems which don't have `alloca' we have to add - some additional code emulating it. */ -#ifdef HAVE_ALLOCA -/* Nothing has to be done. */ -# define freea(p) /* nothing */ -# define ADD_BLOCK(list, address) /* nothing */ -# define FREE_BLOCKS(list) /* nothing */ -#else -struct block_list -{ - void *address; - struct block_list *next; -}; -# define ADD_BLOCK(list, addr) \ - do { \ - struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \ - /* If we cannot get a free block we cannot add the new element to \ - the list. */ \ - if (newp != NULL) { \ - newp->address = (addr); \ - newp->next = (list); \ - (list) = newp; \ - } \ - } while (0) -# define FREE_BLOCKS(list) \ - do { \ - while (list != NULL) { \ - struct block_list *old = list; \ - list = list->next; \ - free (old->address); \ - free (old); \ - } \ - } while (0) -# undef alloca -# define alloca(size) (malloc (size)) -# define freea(p) free (p) -#endif /* have alloca */ - - -#ifdef _LIBC -/* List of blocks allocated for translations. */ -typedef struct transmem_list -{ - struct transmem_list *next; - char data[ZERO]; -} transmem_block_t; -static struct transmem_list *transmem_list; -#else -typedef unsigned char transmem_block_t; -#endif - - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define DCIGETTEXT __dcigettext -#else -# define DCIGETTEXT libintl_dcigettext -#endif - -/* Lock variable to protect the global data in the gettext implementation. */ -#ifdef _LIBC -__libc_rwlock_define_initialized (, _nl_state_lock attribute_hidden) -#endif - -/* Checking whether the binaries runs SUID must be done and glibc provides - easier methods therefore we make a difference here. */ -#ifdef _LIBC -# define ENABLE_SECURE __libc_enable_secure -# define DETERMINE_SECURE -#else -# ifndef HAVE_GETUID -# define getuid() 0 -# endif -# ifndef HAVE_GETGID -# define getgid() 0 -# endif -# ifndef HAVE_GETEUID -# define geteuid() getuid() -# endif -# ifndef HAVE_GETEGID -# define getegid() getgid() -# endif -static int enable_secure; -# define ENABLE_SECURE (enable_secure == 1) -# define DETERMINE_SECURE \ - if (enable_secure == 0) \ - { \ - if (getuid () != geteuid () || getgid () != getegid ()) \ - enable_secure = 1; \ - else \ - enable_secure = -1; \ - } -#endif - -/* Get the function to evaluate the plural expression. */ -#include "eval-plural.h" - -/* Look up MSGID in the DOMAINNAME message catalog for the current - CATEGORY locale and, if PLURAL is nonzero, search over string - depending on the plural form determined by N. */ -char * -DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) - const char *domainname; - const char *msgid1; - const char *msgid2; - int plural; - unsigned long int n; - int category; -{ -#ifndef HAVE_ALLOCA - struct block_list *block_list = NULL; -#endif - struct loaded_l10nfile *domain; - struct binding *binding; - const char *categoryname; - const char *categoryvalue; - char *dirname, *xdomainname; - char *single_locale; - char *retval; - size_t retlen; - int saved_errno; -#if defined HAVE_TSEARCH || defined _LIBC - struct known_translation_t *search; - struct known_translation_t **foundp = NULL; - size_t msgid_len; -#endif - size_t domainname_len; - - /* If no real MSGID is given return NULL. */ - if (msgid1 == NULL) - return NULL; - -#ifdef _LIBC - if (category < 0 || category >= __LC_LAST || category == LC_ALL) - /* Bogus. */ - return (plural == 0 - ? (char *) msgid1 - /* Use the Germanic plural rule. */ - : n == 1 ? (char *) msgid1 : (char *) msgid2); -#endif - - __libc_rwlock_rdlock (_nl_state_lock); - - /* If DOMAINNAME is NULL, we are interested in the default domain. If - CATEGORY is not LC_MESSAGES this might not make much sense but the - definition left this undefined. */ - if (domainname == NULL) - domainname = _nl_current_default_domain; - - /* OS/2 specific: backward compatibility with older libintl versions */ -#ifdef LC_MESSAGES_COMPAT - if (category == LC_MESSAGES_COMPAT) - category = LC_MESSAGES; -#endif - -#if defined HAVE_TSEARCH || defined _LIBC - msgid_len = strlen (msgid1) + 1; - - /* Try to find the translation among those which we found at - some time. */ - search = (struct known_translation_t *) - alloca (offsetof (struct known_translation_t, msgid) + msgid_len); - memcpy (search->msgid, msgid1, msgid_len); - search->domainname = (char *) domainname; - search->category = category; - - foundp = (struct known_translation_t **) tfind (search, &root, transcmp); - freea (search); - if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr) - { - /* Now deal with plural. */ - if (plural) - retval = plural_lookup ((*foundp)->domain, n, (*foundp)->translation, - (*foundp)->translation_length); - else - retval = (char *) (*foundp)->translation; - - __libc_rwlock_unlock (_nl_state_lock); - return retval; - } -#endif - - /* Preserve the `errno' value. */ - saved_errno = errno; - - /* See whether this is a SUID binary or not. */ - DETERMINE_SECURE; - - /* First find matching binding. */ - for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) - { - int compare = strcmp (domainname, binding->domainname); - if (compare == 0) - /* We found it! */ - break; - if (compare < 0) - { - /* It is not in the list. */ - binding = NULL; - break; - } - } - - if (binding == NULL) - dirname = (char *) INTUSE(_nl_default_dirname); - else if (IS_ABSOLUTE_PATH (binding->dirname)) - dirname = binding->dirname; - else - { - /* We have a relative path. Make it absolute now. */ - size_t dirname_len = strlen (binding->dirname) + 1; - size_t path_max; - char *ret; - - path_max = (unsigned int) PATH_MAX; - path_max += 2; /* The getcwd docs say to do this. */ - - for (;;) - { - dirname = (char *) alloca (path_max + dirname_len); - ADD_BLOCK (block_list, dirname); - - __set_errno (0); - ret = getcwd (dirname, path_max); - if (ret != NULL || errno != ERANGE) - break; - - path_max += path_max / 2; - path_max += PATH_INCR; - } - - if (ret == NULL) - /* We cannot get the current working directory. Don't signal an - error but simply return the default string. */ - goto return_untranslated; - - stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname); - } - - /* Now determine the symbolic name of CATEGORY and its value. */ - categoryname = category_to_name (category); - categoryvalue = guess_category_value (category, categoryname); - - domainname_len = strlen (domainname); - xdomainname = (char *) alloca (strlen (categoryname) - + domainname_len + 5); - ADD_BLOCK (block_list, xdomainname); - - stpcpy (mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"), - domainname, domainname_len), - ".mo"); - - /* Creating working area. */ - single_locale = (char *) alloca (strlen (categoryvalue) + 1); - ADD_BLOCK (block_list, single_locale); - - - /* Search for the given string. This is a loop because we perhaps - got an ordered list of languages to consider for the translation. */ - while (1) - { - /* Make CATEGORYVALUE point to the next element of the list. */ - while (categoryvalue[0] != '\0' && categoryvalue[0] == ':') - ++categoryvalue; - if (categoryvalue[0] == '\0') - { - /* The whole contents of CATEGORYVALUE has been searched but - no valid entry has been found. We solve this situation - by implicitly appending a "C" entry, i.e. no translation - will take place. */ - single_locale[0] = 'C'; - single_locale[1] = '\0'; - } - else - { - char *cp = single_locale; - while (categoryvalue[0] != '\0' && categoryvalue[0] != ':') - *cp++ = *categoryvalue++; - *cp = '\0'; - - /* When this is a SUID binary we must not allow accessing files - outside the dedicated directories. */ - if (ENABLE_SECURE && IS_PATH_WITH_DIR (single_locale)) - /* Ingore this entry. */ - continue; - } - - /* If the current locale value is C (or POSIX) we don't load a - domain. Return the MSGID. */ - if (strcmp (single_locale, "C") == 0 - || strcmp (single_locale, "POSIX") == 0) - break; - - /* Find structure describing the message catalog matching the - DOMAINNAME and CATEGORY. */ - domain = _nl_find_domain (dirname, single_locale, xdomainname, binding); - - if (domain != NULL) - { - retval = _nl_find_msg (domain, binding, msgid1, &retlen); - - if (retval == NULL) - { - int cnt; - - for (cnt = 0; domain->successor[cnt] != NULL; ++cnt) - { - retval = _nl_find_msg (domain->successor[cnt], binding, - msgid1, &retlen); - - if (retval != NULL) - { - domain = domain->successor[cnt]; - break; - } - } - } - - if (retval != NULL) - { - /* Found the translation of MSGID1 in domain DOMAIN: - starting at RETVAL, RETLEN bytes. */ - FREE_BLOCKS (block_list); -#if defined HAVE_TSEARCH || defined _LIBC - if (foundp == NULL) - { - /* Create a new entry and add it to the search tree. */ - struct known_translation_t *newp; - - newp = (struct known_translation_t *) - malloc (offsetof (struct known_translation_t, msgid) - + msgid_len + domainname_len + 1); - if (newp != NULL) - { - newp->domainname = - mempcpy (newp->msgid, msgid1, msgid_len); - memcpy (newp->domainname, domainname, domainname_len + 1); - newp->category = category; - newp->counter = _nl_msg_cat_cntr; - newp->domain = domain; - newp->translation = retval; - newp->translation_length = retlen; - - /* Insert the entry in the search tree. */ - foundp = (struct known_translation_t **) - tsearch (newp, &root, transcmp); - if (foundp == NULL - || __builtin_expect (*foundp != newp, 0)) - /* The insert failed. */ - free (newp); - } - } - else - { - /* We can update the existing entry. */ - (*foundp)->counter = _nl_msg_cat_cntr; - (*foundp)->domain = domain; - (*foundp)->translation = retval; - (*foundp)->translation_length = retlen; - } -#endif - __set_errno (saved_errno); - - /* Now deal with plural. */ - if (plural) - retval = plural_lookup (domain, n, retval, retlen); - - __libc_rwlock_unlock (_nl_state_lock); - return retval; - } - } - } - - return_untranslated: - /* Return the untranslated MSGID. */ - FREE_BLOCKS (block_list); - __libc_rwlock_unlock (_nl_state_lock); -#ifndef _LIBC - if (!ENABLE_SECURE) - { - extern void _nl_log_untranslated PARAMS ((const char *logfilename, - const char *domainname, - const char *msgid1, - const char *msgid2, - int plural)); - const char *logfilename = getenv ("GETTEXT_LOG_UNTRANSLATED"); - - if (logfilename != NULL && logfilename[0] != '\0') - _nl_log_untranslated (logfilename, domainname, msgid1, msgid2, plural); - } -#endif - __set_errno (saved_errno); - return (plural == 0 - ? (char *) msgid1 - /* Use the Germanic plural rule. */ - : n == 1 ? (char *) msgid1 : (char *) msgid2); -} - - -char * -internal_function -_nl_find_msg (domain_file, domainbinding, msgid, lengthp) - struct loaded_l10nfile *domain_file; - struct binding *domainbinding; - const char *msgid; - size_t *lengthp; -{ - struct loaded_domain *domain; - nls_uint32 nstrings; - size_t act; - char *result; - size_t resultlen; - - if (domain_file->decided == 0) - _nl_load_domain (domain_file, domainbinding); - - if (domain_file->data == NULL) - return NULL; - - domain = (struct loaded_domain *) domain_file->data; - - nstrings = domain->nstrings; - - /* Locate the MSGID and its translation. */ - if (domain->hash_tab != NULL) - { - /* Use the hashing table. */ - nls_uint32 len = strlen (msgid); - nls_uint32 hash_val = hash_string (msgid); - nls_uint32 idx = hash_val % domain->hash_size; - nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); - - while (1) - { - nls_uint32 nstr = - W (domain->must_swap_hash_tab, domain->hash_tab[idx]); - - if (nstr == 0) - /* Hash table entry is empty. */ - return NULL; - - nstr--; - - /* Compare msgid with the original string at index nstr. - We compare the lengths with >=, not ==, because plural entries - are represented by strings with an embedded NUL. */ - if (nstr < nstrings - ? W (domain->must_swap, domain->orig_tab[nstr].length) >= len - && (strcmp (msgid, - domain->data + W (domain->must_swap, - domain->orig_tab[nstr].offset)) - == 0) - : domain->orig_sysdep_tab[nstr - nstrings].length > len - && (strcmp (msgid, - domain->orig_sysdep_tab[nstr - nstrings].pointer) - == 0)) - { - act = nstr; - goto found; - } - - if (idx >= domain->hash_size - incr) - idx -= domain->hash_size - incr; - else - idx += incr; - } - /* NOTREACHED */ - } - else - { - /* Try the default method: binary search in the sorted array of - messages. */ - size_t top, bottom; - - bottom = 0; - top = nstrings; - while (bottom < top) - { - int cmp_val; - - act = (bottom + top) / 2; - cmp_val = strcmp (msgid, (domain->data - + W (domain->must_swap, - domain->orig_tab[act].offset))); - if (cmp_val < 0) - top = act; - else if (cmp_val > 0) - bottom = act + 1; - else - goto found; - } - /* No translation was found. */ - return NULL; - } - - found: - /* The translation was found at index ACT. If we have to convert the - string to use a different character set, this is the time. */ - if (act < nstrings) - { - result = (char *) - (domain->data + W (domain->must_swap, domain->trans_tab[act].offset)); - resultlen = W (domain->must_swap, domain->trans_tab[act].length) + 1; - } - else - { - result = (char *) domain->trans_sysdep_tab[act - nstrings].pointer; - resultlen = domain->trans_sysdep_tab[act - nstrings].length; - } - -#if defined _LIBC || HAVE_ICONV - if (domain->codeset_cntr - != (domainbinding != NULL ? domainbinding->codeset_cntr : 0)) - { - /* The domain's codeset has changed through bind_textdomain_codeset() - since the message catalog was initialized or last accessed. We - have to reinitialize the converter. */ - _nl_free_domain_conv (domain); - _nl_init_domain_conv (domain_file, domain, domainbinding); - } - - if ( -# ifdef _LIBC - domain->conv != (__gconv_t) -1 -# else -# if HAVE_ICONV - domain->conv != (iconv_t) -1 -# endif -# endif - ) - { - /* We are supposed to do a conversion. First allocate an - appropriate table with the same structure as the table - of translations in the file, where we can put the pointers - to the converted strings in. - There is a slight complication with plural entries. They - are represented by consecutive NUL terminated strings. We - handle this case by converting RESULTLEN bytes, including - NULs. */ - - if (domain->conv_tab == NULL - && ((domain->conv_tab = - (char **) calloc (nstrings + domain->n_sysdep_strings, - sizeof (char *))) - == NULL)) - /* Mark that we didn't succeed allocating a table. */ - domain->conv_tab = (char **) -1; - - if (__builtin_expect (domain->conv_tab == (char **) -1, 0)) - /* Nothing we can do, no more memory. */ - goto converted; - - if (domain->conv_tab[act] == NULL) - { - /* We haven't used this string so far, so it is not - translated yet. Do this now. */ - /* We use a bit more efficient memory handling. - We allocate always larger blocks which get used over - time. This is faster than many small allocations. */ - __libc_lock_define_initialized (static, lock) -# define INITIAL_BLOCK_SIZE 4080 - static unsigned char *freemem; - static size_t freemem_size; - - const unsigned char *inbuf; - unsigned char *outbuf; - int malloc_count; -# ifndef _LIBC - transmem_block_t *transmem_list = NULL; -# endif - - __libc_lock_lock (lock); - - inbuf = (const unsigned char *) result; - outbuf = freemem + sizeof (size_t); - - malloc_count = 0; - while (1) - { - transmem_block_t *newmem; -# ifdef _LIBC - size_t non_reversible; - int res; - - if (freemem_size < sizeof (size_t)) - goto resize_freemem; - - res = __gconv (domain->conv, - &inbuf, inbuf + resultlen, - &outbuf, - outbuf + freemem_size - sizeof (size_t), - &non_reversible); - - if (res == __GCONV_OK || res == __GCONV_EMPTY_INPUT) - break; - - if (res != __GCONV_FULL_OUTPUT) - { - __libc_lock_unlock (lock); - goto converted; - } - - inbuf = result; -# else -# if HAVE_ICONV - const char *inptr = (const char *) inbuf; - size_t inleft = resultlen; - char *outptr = (char *) outbuf; - size_t outleft; - - if (freemem_size < sizeof (size_t)) - goto resize_freemem; - - outleft = freemem_size - sizeof (size_t); - if (iconv (domain->conv, - (ICONV_CONST char **) &inptr, &inleft, - &outptr, &outleft) - != (size_t) (-1)) - { - outbuf = (unsigned char *) outptr; - break; - } - if (errno != E2BIG) - { - __libc_lock_unlock (lock); - goto converted; - } -# endif -# endif - - resize_freemem: - /* We must allocate a new buffer or resize the old one. */ - if (malloc_count > 0) - { - ++malloc_count; - freemem_size = malloc_count * INITIAL_BLOCK_SIZE; - newmem = (transmem_block_t *) realloc (transmem_list, - freemem_size); -# ifdef _LIBC - if (newmem != NULL) - transmem_list = transmem_list->next; - else - { - struct transmem_list *old = transmem_list; - - transmem_list = transmem_list->next; - free (old); - } -# endif - } - else - { - malloc_count = 1; - freemem_size = INITIAL_BLOCK_SIZE; - newmem = (transmem_block_t *) malloc (freemem_size); - } - if (__builtin_expect (newmem == NULL, 0)) - { - freemem = NULL; - freemem_size = 0; - __libc_lock_unlock (lock); - goto converted; - } - -# ifdef _LIBC - /* Add the block to the list of blocks we have to free - at some point. */ - newmem->next = transmem_list; - transmem_list = newmem; - - freemem = newmem->data; - freemem_size -= offsetof (struct transmem_list, data); -# else - transmem_list = newmem; - freemem = newmem; -# endif - - outbuf = freemem + sizeof (size_t); - } - - /* We have now in our buffer a converted string. Put this - into the table of conversions. */ - *(size_t *) freemem = outbuf - freemem - sizeof (size_t); - domain->conv_tab[act] = (char *) freemem; - /* Shrink freemem, but keep it aligned. */ - freemem_size -= outbuf - freemem; - freemem = outbuf; - freemem += freemem_size & (alignof (size_t) - 1); - freemem_size = freemem_size & ~ (alignof (size_t) - 1); - - __libc_lock_unlock (lock); - } - - /* Now domain->conv_tab[act] contains the translation of all - the plural variants. */ - result = domain->conv_tab[act] + sizeof (size_t); - resultlen = *(size_t *) domain->conv_tab[act]; - } - - converted: - /* The result string is converted. */ - -#endif /* _LIBC || HAVE_ICONV */ - - *lengthp = resultlen; - return result; -} - - -/* Look up a plural variant. */ -static char * -internal_function -plural_lookup (domain, n, translation, translation_len) - struct loaded_l10nfile *domain; - unsigned long int n; - const char *translation; - size_t translation_len; -{ - struct loaded_domain *domaindata = (struct loaded_domain *) domain->data; - unsigned long int index; - const char *p; - - index = plural_eval (domaindata->plural, n); - if (index >= domaindata->nplurals) - /* This should never happen. It means the plural expression and the - given maximum value do not match. */ - index = 0; - - /* Skip INDEX strings at TRANSLATION. */ - p = translation; - while (index-- > 0) - { -#ifdef _LIBC - p = __rawmemchr (p, '\0'); -#else - p = strchr (p, '\0'); -#endif - /* And skip over the NUL byte. */ - p++; - - if (p >= translation + translation_len) - /* This should never happen. It means the plural expression - evaluated to a value larger than the number of variants - available for MSGID1. */ - return (char *) translation; - } - return (char *) p; -} - -#ifndef _LIBC -/* Return string representation of locale CATEGORY. */ -static const char * -internal_function -category_to_name (category) - int category; -{ - const char *retval; - - switch (category) - { -#ifdef LC_COLLATE - case LC_COLLATE: - retval = "LC_COLLATE"; - break; -#endif -#ifdef LC_CTYPE - case LC_CTYPE: - retval = "LC_CTYPE"; - break; -#endif -#ifdef LC_MONETARY - case LC_MONETARY: - retval = "LC_MONETARY"; - break; -#endif -#ifdef LC_NUMERIC - case LC_NUMERIC: - retval = "LC_NUMERIC"; - break; -#endif -#ifdef LC_TIME - case LC_TIME: - retval = "LC_TIME"; - break; -#endif -#ifdef LC_MESSAGES - case LC_MESSAGES: - retval = "LC_MESSAGES"; - break; -#endif -#ifdef LC_RESPONSE - case LC_RESPONSE: - retval = "LC_RESPONSE"; - break; -#endif -#ifdef LC_ALL - case LC_ALL: - /* This might not make sense but is perhaps better than any other - value. */ - retval = "LC_ALL"; - break; -#endif - default: - /* If you have a better idea for a default value let me know. */ - retval = "LC_XXX"; - } - - return retval; -} -#endif - -/* Guess value of current locale from value of the environment variables. */ -static const char * -internal_function -guess_category_value (category, categoryname) - int category; - const char *categoryname; -{ - const char *language; - const char *retval; - - /* The highest priority value is the `LANGUAGE' environment - variable. But we don't use the value if the currently selected - locale is the C locale. This is a GNU extension. */ - language = getenv ("LANGUAGE"); - if (language != NULL && language[0] == '\0') - language = NULL; - - /* We have to proceed with the POSIX methods of looking to `LC_ALL', - `LC_xxx', and `LANG'. On some systems this can be done by the - `setlocale' function itself. */ -#ifdef _LIBC - retval = __current_locale_name (category); -#else - retval = _nl_locale_name (category, categoryname); -#endif - - /* Ignore LANGUAGE if the locale is set to "C" because - 1. "C" locale usually uses the ASCII encoding, and most international - messages use non-ASCII characters. These characters get displayed - as question marks (if using glibc's iconv()) or as invalid 8-bit - characters (because other iconv()s refuse to convert most non-ASCII - characters to ASCII). In any case, the output is ugly. - 2. The precise output of some programs in the "C" locale is specified - by POSIX and should not depend on environment variables like - "LANGUAGE". We allow such programs to use gettext(). */ - return language != NULL && strcmp (retval, "C") != 0 ? language : retval; -} - -/* @@ begin of epilog @@ */ - -/* We don't want libintl.a to depend on any other library. So we - avoid the non-standard function stpcpy. In GNU C Library this - function is available, though. Also allow the symbol HAVE_STPCPY - to be defined. */ -#if !_LIBC && !HAVE_STPCPY -static char * -stpcpy (dest, src) - char *dest; - const char *src; -{ - while ((*dest++ = *src++) != '\0') - /* Do nothing. */ ; - return dest - 1; -} -#endif - -#if !_LIBC && !HAVE_MEMPCPY -static void * -mempcpy (dest, src, n) - void *dest; - const void *src; - size_t n; -{ - return (void *) ((char *) memcpy (dest, src, n) + n); -} -#endif - - -#ifdef _LIBC -/* If we want to free all resources we have to do some work at - program's end. */ -libc_freeres_fn (free_mem) -{ - void *old; - - while (_nl_domain_bindings != NULL) - { - struct binding *oldp = _nl_domain_bindings; - _nl_domain_bindings = _nl_domain_bindings->next; - if (oldp->dirname != INTUSE(_nl_default_dirname)) - /* Yes, this is a pointer comparison. */ - free (oldp->dirname); - free (oldp->codeset); - free (oldp); - } - - if (_nl_current_default_domain != _nl_default_default_domain) - /* Yes, again a pointer comparison. */ - free ((char *) _nl_current_default_domain); - - /* Remove the search tree with the known translations. */ - __tdestroy (root, free); - root = NULL; - - while (transmem_list != NULL) - { - old = transmem_list; - transmem_list = transmem_list->next; - free (old); - } -} -#endif diff --git a/intl/dcngettext.c b/intl/dcngettext.c deleted file mode 100644 index 3a3404e2c..000000000 --- a/intl/dcngettext.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Implementation of the dcngettext(3) function. - Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define DCNGETTEXT __dcngettext -# define DCIGETTEXT __dcigettext -#else -# define DCNGETTEXT libintl_dcngettext -# define DCIGETTEXT libintl_dcigettext -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY - locale. */ -char * -DCNGETTEXT (domainname, msgid1, msgid2, n, category) - const char *domainname; - const char *msgid1; - const char *msgid2; - unsigned long int n; - int category; -{ - return DCIGETTEXT (domainname, msgid1, msgid2, 1, n, category); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__dcngettext, dcngettext); -#endif diff --git a/intl/dgettext.c b/intl/dgettext.c deleted file mode 100644 index cf5b4037f..000000000 --- a/intl/dgettext.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Implementation of the dgettext(3) function. - Copyright (C) 1995-1997, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <locale.h> - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define DGETTEXT __dgettext -# define DCGETTEXT INTUSE(__dcgettext) -#else -# define DGETTEXT libintl_dgettext -# define DCGETTEXT libintl_dcgettext -#endif - -/* Look up MSGID in the DOMAINNAME message catalog of the current - LC_MESSAGES locale. */ -char * -DGETTEXT (domainname, msgid) - const char *domainname; - const char *msgid; -{ - return DCGETTEXT (domainname, msgid, LC_MESSAGES); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__dgettext, dgettext); -#endif diff --git a/intl/dngettext.c b/intl/dngettext.c deleted file mode 100644 index 67fd030f2..000000000 --- a/intl/dngettext.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Implementation of the dngettext(3) function. - Copyright (C) 1995-1997, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <locale.h> - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define DNGETTEXT __dngettext -# define DCNGETTEXT __dcngettext -#else -# define DNGETTEXT libintl_dngettext -# define DCNGETTEXT libintl_dcngettext -#endif - -/* Look up MSGID in the DOMAINNAME message catalog of the current - LC_MESSAGES locale and skip message according to the plural form. */ -char * -DNGETTEXT (domainname, msgid1, msgid2, n) - const char *domainname; - const char *msgid1; - const char *msgid2; - unsigned long int n; -{ - return DCNGETTEXT (domainname, msgid1, msgid2, n, LC_MESSAGES); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__dngettext, dngettext); -#endif diff --git a/intl/eval-plural.h b/intl/eval-plural.h deleted file mode 100644 index 19c7ca6ae..000000000 --- a/intl/eval-plural.h +++ /dev/null @@ -1,114 +0,0 @@ -/* Plural expression evaluation. - Copyright (C) 2000-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef STATIC -#define STATIC static -#endif - -/* Evaluate the plural expression and return an index value. */ -STATIC unsigned long int plural_eval PARAMS ((struct expression *pexp, - unsigned long int n)) - internal_function; - -STATIC -unsigned long int -internal_function -plural_eval (pexp, n) - struct expression *pexp; - unsigned long int n; -{ - switch (pexp->nargs) - { - case 0: - switch (pexp->operation) - { - case var: - return n; - case num: - return pexp->val.num; - default: - break; - } - /* NOTREACHED */ - break; - case 1: - { - /* pexp->operation must be lnot. */ - unsigned long int arg = plural_eval (pexp->val.args[0], n); - return ! arg; - } - case 2: - { - unsigned long int leftarg = plural_eval (pexp->val.args[0], n); - if (pexp->operation == lor) - return leftarg || plural_eval (pexp->val.args[1], n); - else if (pexp->operation == land) - return leftarg && plural_eval (pexp->val.args[1], n); - else - { - unsigned long int rightarg = plural_eval (pexp->val.args[1], n); - - switch (pexp->operation) - { - case mult: - return leftarg * rightarg; - case divide: -#if !INTDIV0_RAISES_SIGFPE - if (rightarg == 0) - raise (SIGFPE); -#endif - return leftarg / rightarg; - case module: -#if !INTDIV0_RAISES_SIGFPE - if (rightarg == 0) - raise (SIGFPE); -#endif - return leftarg % rightarg; - case plus: - return leftarg + rightarg; - case minus: - return leftarg - rightarg; - case less_than: - return leftarg < rightarg; - case greater_than: - return leftarg > rightarg; - case less_or_equal: - return leftarg <= rightarg; - case greater_or_equal: - return leftarg >= rightarg; - case equal: - return leftarg == rightarg; - case not_equal: - return leftarg != rightarg; - default: - break; - } - } - /* NOTREACHED */ - break; - } - case 3: - { - /* pexp->operation must be qmop. */ - unsigned long int boolarg = plural_eval (pexp->val.args[0], n); - return plural_eval (pexp->val.args[boolarg ? 1 : 2], n); - } - } - /* NOTREACHED */ - return 0; -} diff --git a/intl/explodename.c b/intl/explodename.c deleted file mode 100644 index 2985064c9..000000000 --- a/intl/explodename.c +++ /dev/null @@ -1,192 +0,0 @@ -/* Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. - Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> - -#include "loadinfo.h" - -/* On some strange systems still no definition of NULL is found. Sigh! */ -#ifndef NULL -# if defined __STDC__ && __STDC__ -# define NULL ((void *) 0) -# else -# define NULL 0 -# endif -#endif - -/* @@ end of prolog @@ */ - -char * -_nl_find_language (name) - const char *name; -{ - while (name[0] != '\0' && name[0] != '_' && name[0] != '@' - && name[0] != '+' && name[0] != ',') - ++name; - - return (char *) name; -} - - -int -_nl_explode_name (name, language, modifier, territory, codeset, - normalized_codeset, special, sponsor, revision) - char *name; - const char **language; - const char **modifier; - const char **territory; - const char **codeset; - const char **normalized_codeset; - const char **special; - const char **sponsor; - const char **revision; -{ - enum { undecided, xpg, cen } syntax; - char *cp; - int mask; - - *modifier = NULL; - *territory = NULL; - *codeset = NULL; - *normalized_codeset = NULL; - *special = NULL; - *sponsor = NULL; - *revision = NULL; - - /* Now we determine the single parts of the locale name. First - look for the language. Termination symbols are `_' and `@' if - we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ - mask = 0; - syntax = undecided; - *language = cp = name; - cp = _nl_find_language (*language); - - if (*language == cp) - /* This does not make sense: language has to be specified. Use - this entry as it is without exploding. Perhaps it is an alias. */ - cp = strchr (*language, '\0'); - else if (cp[0] == '_') - { - /* Next is the territory. */ - cp[0] = '\0'; - *territory = ++cp; - - while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@' - && cp[0] != '+' && cp[0] != ',' && cp[0] != '_') - ++cp; - - mask |= TERRITORY; - - if (cp[0] == '.') - { - /* Next is the codeset. */ - syntax = xpg; - cp[0] = '\0'; - *codeset = ++cp; - - while (cp[0] != '\0' && cp[0] != '@') - ++cp; - - mask |= XPG_CODESET; - - if (*codeset != cp && (*codeset)[0] != '\0') - { - *normalized_codeset = _nl_normalize_codeset (*codeset, - cp - *codeset); - if (strcmp (*codeset, *normalized_codeset) == 0) - free ((char *) *normalized_codeset); - else - mask |= XPG_NORM_CODESET; - } - } - } - - if (cp[0] == '@' || (syntax != xpg && cp[0] == '+')) - { - /* Next is the modifier. */ - syntax = cp[0] == '@' ? xpg : cen; - cp[0] = '\0'; - *modifier = ++cp; - - while (syntax == cen && cp[0] != '\0' && cp[0] != '+' - && cp[0] != ',' && cp[0] != '_') - ++cp; - - mask |= XPG_MODIFIER | CEN_AUDIENCE; - } - - if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_')) - { - syntax = cen; - - if (cp[0] == '+') - { - /* Next is special application (CEN syntax). */ - cp[0] = '\0'; - *special = ++cp; - - while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_') - ++cp; - - mask |= CEN_SPECIAL; - } - - if (cp[0] == ',') - { - /* Next is sponsor (CEN syntax). */ - cp[0] = '\0'; - *sponsor = ++cp; - - while (cp[0] != '\0' && cp[0] != '_') - ++cp; - - mask |= CEN_SPONSOR; - } - - if (cp[0] == '_') - { - /* Next is revision (CEN syntax). */ - cp[0] = '\0'; - *revision = ++cp; - - mask |= CEN_REVISION; - } - } - - /* For CEN syntax values it might be important to have the - separator character in the file name, not for XPG syntax. */ - if (syntax == xpg) - { - if (*territory != NULL && (*territory)[0] == '\0') - mask &= ~TERRITORY; - - if (*codeset != NULL && (*codeset)[0] == '\0') - mask &= ~XPG_CODESET; - - if (*modifier != NULL && (*modifier)[0] == '\0') - mask &= ~XPG_MODIFIER; - } - - return mask; -} diff --git a/intl/finddomain.c b/intl/finddomain.c deleted file mode 100644 index d24276442..000000000 --- a/intl/finddomain.c +++ /dev/null @@ -1,195 +0,0 @@ -/* Handle list of needed message catalogs - Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. - Written by Ulrich Drepper <drepper@gnu.org>, 1995. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdio.h> -#include <sys/types.h> -#include <stdlib.h> -#include <string.h> - -#if defined HAVE_UNISTD_H || defined _LIBC -# include <unistd.h> -#endif - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -/* @@ end of prolog @@ */ -/* List of already loaded domains. */ -static struct loaded_l10nfile *_nl_loaded_domains; - - -/* Return a data structure describing the message catalog described by - the DOMAINNAME and CATEGORY parameters with respect to the currently - established bindings. */ -struct loaded_l10nfile * -internal_function -_nl_find_domain (dirname, locale, domainname, domainbinding) - const char *dirname; - char *locale; - const char *domainname; - struct binding *domainbinding; -{ - struct loaded_l10nfile *retval; - const char *language; - const char *modifier; - const char *territory; - const char *codeset; - const char *normalized_codeset; - const char *special; - const char *sponsor; - const char *revision; - const char *alias_value; - int mask; - - /* LOCALE can consist of up to four recognized parts for the XPG syntax: - - language[_territory[.codeset]][@modifier] - - and six parts for the CEN syntax: - - language[_territory][+audience][+special][,[sponsor][_revision]] - - Beside the first part all of them are allowed to be missing. If - the full specified locale is not found, the less specific one are - looked for. The various parts will be stripped off according to - the following order: - (1) revision - (2) sponsor - (3) special - (4) codeset - (5) normalized codeset - (6) territory - (7) audience/modifier - */ - - /* If we have already tested for this locale entry there has to - be one data set in the list of loaded domains. */ - retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, - strlen (dirname) + 1, 0, locale, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, domainname, 0); - if (retval != NULL) - { - /* We know something about this locale. */ - int cnt; - - if (retval->decided == 0) - _nl_load_domain (retval, domainbinding); - - if (retval->data != NULL) - return retval; - - for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) - { - if (retval->successor[cnt]->decided == 0) - _nl_load_domain (retval->successor[cnt], domainbinding); - - if (retval->successor[cnt]->data != NULL) - break; - } - return cnt >= 0 ? retval : NULL; - /* NOTREACHED */ - } - - /* See whether the locale value is an alias. If yes its value - *overwrites* the alias name. No test for the original value is - done. */ - alias_value = _nl_expand_alias (locale); - if (alias_value != NULL) - { -#if defined _LIBC || defined HAVE_STRDUP - locale = strdup (alias_value); - if (locale == NULL) - return NULL; -#else - size_t len = strlen (alias_value) + 1; - locale = (char *) malloc (len); - if (locale == NULL) - return NULL; - - memcpy (locale, alias_value, len); -#endif - } - - /* Now we determine the single parts of the locale name. First - look for the language. Termination symbols are `_' and `@' if - we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ - mask = _nl_explode_name (locale, &language, &modifier, &territory, - &codeset, &normalized_codeset, &special, - &sponsor, &revision); - - /* Create all possible locale entries which might be interested in - generalization. */ - retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, - strlen (dirname) + 1, mask, language, territory, - codeset, normalized_codeset, modifier, special, - sponsor, revision, domainname, 1); - if (retval == NULL) - /* This means we are out of core. */ - return NULL; - - if (retval->decided == 0) - _nl_load_domain (retval, domainbinding); - if (retval->data == NULL) - { - int cnt; - for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) - { - if (retval->successor[cnt]->decided == 0) - _nl_load_domain (retval->successor[cnt], domainbinding); - if (retval->successor[cnt]->data != NULL) - break; - } - } - - /* The room for an alias was dynamically allocated. Free it now. */ - if (alias_value != NULL) - free (locale); - - /* The space for normalized_codeset is dynamically allocated. Free it. */ - if (mask & XPG_NORM_CODESET) - free ((void *) normalized_codeset); - - return retval; -} - - -#ifdef _LIBC -libc_freeres_fn (free_mem) -{ - struct loaded_l10nfile *runp = _nl_loaded_domains; - - while (runp != NULL) - { - struct loaded_l10nfile *here = runp; - if (runp->data != NULL) - _nl_unload_domain ((struct loaded_domain *) runp->data); - runp = runp->next; - free ((char *) here->filename); - free (here); - } -} -#endif diff --git a/intl/gettext.c b/intl/gettext.c deleted file mode 100644 index 43d689f55..000000000 --- a/intl/gettext.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Implementation of gettext(3) function. - Copyright (C) 1995, 1997, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#ifdef _LIBC -# define __need_NULL -# include <stddef.h> -#else -# include <stdlib.h> /* Just for NULL. */ -#endif - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define GETTEXT __gettext -# define DCGETTEXT INTUSE(__dcgettext) -#else -# define GETTEXT libintl_gettext -# define DCGETTEXT libintl_dcgettext -#endif - -/* Look up MSGID in the current default message catalog for the current - LC_MESSAGES locale. If not found, returns MSGID itself (the default - text). */ -char * -GETTEXT (msgid) - const char *msgid; -{ - return DCGETTEXT (NULL, msgid, LC_MESSAGES); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__gettext, gettext); -#endif diff --git a/intl/gettextP.h b/intl/gettextP.h deleted file mode 100644 index f1748a356..000000000 --- a/intl/gettextP.h +++ /dev/null @@ -1,224 +0,0 @@ -/* Header describing internals of libintl library. - Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc. - Written by Ulrich Drepper <drepper@cygnus.com>, 1995. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _GETTEXTP_H -#define _GETTEXTP_H - -#include <stddef.h> /* Get size_t. */ - -#ifdef _LIBC -# include "../iconv/gconv_int.h" -#else -# if HAVE_ICONV -# include <iconv.h> -# endif -#endif - -#include "loadinfo.h" - -#include "gmo.h" /* Get nls_uint32. */ - -/* @@ end of prolog @@ */ - -#ifndef PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - -#ifndef internal_function -# define internal_function -#endif - -#ifndef attribute_hidden -# define attribute_hidden -#endif - -/* Tell the compiler when a conditional or integer expression is - almost always true or almost always false. */ -#ifndef HAVE_BUILTIN_EXPECT -# define __builtin_expect(expr, val) (expr) -#endif - -#ifndef W -# define W(flag, data) ((flag) ? SWAP (data) : (data)) -#endif - - -#ifdef _LIBC -# include <byteswap.h> -# define SWAP(i) bswap_32 (i) -#else -static inline nls_uint32 -SWAP (i) - nls_uint32 i; -{ - return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24); -} -#endif - - -/* In-memory representation of system dependent string. */ -struct sysdep_string_desc -{ - /* Length of addressed string, including the trailing NUL. */ - size_t length; - /* Pointer to addressed string. */ - const char *pointer; -}; - -/* The representation of an opened message catalog. */ -struct loaded_domain -{ - /* Pointer to memory containing the .mo file. */ - const char *data; - /* 1 if the memory is mmap()ed, 0 if the memory is malloc()ed. */ - int use_mmap; - /* Size of mmap()ed memory. */ - size_t mmap_size; - /* 1 if the .mo file uses a different endianness than this machine. */ - int must_swap; - /* Pointer to additional malloc()ed memory. */ - void *malloced; - - /* Number of static strings pairs. */ - nls_uint32 nstrings; - /* Pointer to descriptors of original strings in the file. */ - const struct string_desc *orig_tab; - /* Pointer to descriptors of translated strings in the file. */ - const struct string_desc *trans_tab; - - /* Number of system dependent strings pairs. */ - nls_uint32 n_sysdep_strings; - /* Pointer to descriptors of original sysdep strings. */ - const struct sysdep_string_desc *orig_sysdep_tab; - /* Pointer to descriptors of translated sysdep strings. */ - const struct sysdep_string_desc *trans_sysdep_tab; - - /* Size of hash table. */ - nls_uint32 hash_size; - /* Pointer to hash table. */ - const nls_uint32 *hash_tab; - /* 1 if the hash table uses a different endianness than this machine. */ - int must_swap_hash_tab; - - int codeset_cntr; -#ifdef _LIBC - __gconv_t conv; -#else -# if HAVE_ICONV - iconv_t conv; -# endif -#endif - char **conv_tab; - - struct expression *plural; - unsigned long int nplurals; -}; - -/* We want to allocate a string at the end of the struct. But ISO C - doesn't allow zero sized arrays. */ -#ifdef __GNUC__ -# define ZERO 0 -#else -# define ZERO 1 -#endif - -/* A set of settings bound to a message domain. Used to store settings - from bindtextdomain() and bind_textdomain_codeset(). */ -struct binding -{ - struct binding *next; - char *dirname; - int codeset_cntr; /* Incremented each time codeset changes. */ - char *codeset; - char domainname[ZERO]; -}; - -/* A counter which is incremented each time some previous translations - become invalid. - This variable is part of the external ABI of the GNU libintl. */ -extern int _nl_msg_cat_cntr; - -#ifndef _LIBC -const char *_nl_locale_name PARAMS ((int category, const char *categoryname)); -#endif - -struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname, - char *__locale, - const char *__domainname, - struct binding *__domainbinding)) - internal_function; -void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain, - struct binding *__domainbinding)) - internal_function; -void _nl_unload_domain PARAMS ((struct loaded_domain *__domain)) - internal_function; -const char *_nl_init_domain_conv PARAMS ((struct loaded_l10nfile *__domain_file, - struct loaded_domain *__domain, - struct binding *__domainbinding)) - internal_function; -void _nl_free_domain_conv PARAMS ((struct loaded_domain *__domain)) - internal_function; - -char *_nl_find_msg PARAMS ((struct loaded_l10nfile *domain_file, - struct binding *domainbinding, - const char *msgid, size_t *lengthp)) - internal_function; - -#ifdef _LIBC -extern char *__gettext PARAMS ((const char *__msgid)); -extern char *__dgettext PARAMS ((const char *__domainname, - const char *__msgid)); -extern char *__dcgettext PARAMS ((const char *__domainname, - const char *__msgid, int __category)); -extern char *__ngettext PARAMS ((const char *__msgid1, const char *__msgid2, - unsigned long int __n)); -extern char *__dngettext PARAMS ((const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int n)); -extern char *__dcngettext PARAMS ((const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int __n, int __category)); -extern char *__dcigettext PARAMS ((const char *__domainname, - const char *__msgid1, const char *__msgid2, - int __plural, unsigned long int __n, - int __category)); -extern char *__textdomain PARAMS ((const char *__domainname)); -extern char *__bindtextdomain PARAMS ((const char *__domainname, - const char *__dirname)); -extern char *__bind_textdomain_codeset PARAMS ((const char *__domainname, - const char *__codeset)); -#else -/* Declare the exported libintl_* functions, in a way that allows us to - call them under their real name. */ -# define _INTL_REDIRECT_MACROS -# include "libgnuintl.h" -extern char *libintl_dcigettext PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - int __plural, unsigned long int __n, - int __category)); -#endif - -/* @@ begin of epilog @@ */ - -#endif /* gettextP.h */ diff --git a/intl/gmo.h b/intl/gmo.h deleted file mode 100644 index d1fe4d6b8..000000000 --- a/intl/gmo.h +++ /dev/null @@ -1,148 +0,0 @@ -/* Description of GNU message catalog format: general file layout. - Copyright (C) 1995, 1997, 2000-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _GETTEXT_H -#define _GETTEXT_H 1 - -#include <limits.h> - -/* @@ end of prolog @@ */ - -/* The magic number of the GNU message catalog format. */ -#define _MAGIC 0x950412de -#define _MAGIC_SWAPPED 0xde120495 - -/* Revision number of the currently used .mo (binary) file format. */ -#define MO_REVISION_NUMBER 0 - -/* The following contortions are an attempt to use the C preprocessor - to determine an unsigned integral type that is 32 bits wide. An - alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but - as of version autoconf-2.13, the AC_CHECK_SIZEOF macro doesn't work - when cross-compiling. */ - -#if __STDC__ -# define UINT_MAX_32_BITS 4294967295U -#else -# define UINT_MAX_32_BITS 0xFFFFFFFF -#endif - -/* If UINT_MAX isn't defined, assume it's a 32-bit type. - This should be valid for all systems GNU cares about because - that doesn't include 16-bit systems, and only modern systems - (that certainly have <limits.h>) have 64+-bit integral types. */ - -#ifndef UINT_MAX -# define UINT_MAX UINT_MAX_32_BITS -#endif - -#if UINT_MAX == UINT_MAX_32_BITS -typedef unsigned nls_uint32; -#else -# if USHRT_MAX == UINT_MAX_32_BITS -typedef unsigned short nls_uint32; -# else -# if ULONG_MAX == UINT_MAX_32_BITS -typedef unsigned long nls_uint32; -# else - /* The following line is intended to throw an error. Using #error is - not portable enough. */ - "Cannot determine unsigned 32-bit data type." -# endif -# endif -#endif - - -/* Header for binary .mo file format. */ -struct mo_file_header -{ - /* The magic number. */ - nls_uint32 magic; - /* The revision number of the file format. */ - nls_uint32 revision; - - /* The following are only used in .mo files with major revision 0. */ - - /* The number of strings pairs. */ - nls_uint32 nstrings; - /* Offset of table with start offsets of original strings. */ - nls_uint32 orig_tab_offset; - /* Offset of table with start offsets of translated strings. */ - nls_uint32 trans_tab_offset; - /* Size of hash table. */ - nls_uint32 hash_tab_size; - /* Offset of first hash table entry. */ - nls_uint32 hash_tab_offset; - - /* The following are only used in .mo files with minor revision >= 1. */ - - /* The number of system dependent segments. */ - nls_uint32 n_sysdep_segments; - /* Offset of table describing system dependent segments. */ - nls_uint32 sysdep_segments_offset; - /* The number of system dependent strings pairs. */ - nls_uint32 n_sysdep_strings; - /* Offset of table with start offsets of original sysdep strings. */ - nls_uint32 orig_sysdep_tab_offset; - /* Offset of table with start offsets of translated sysdep strings. */ - nls_uint32 trans_sysdep_tab_offset; -}; - -/* Descriptor for static string contained in the binary .mo file. */ -struct string_desc -{ - /* Length of addressed string, not including the trailing NUL. */ - nls_uint32 length; - /* Offset of string in file. */ - nls_uint32 offset; -}; - -/* The following are only used in .mo files with minor revision >= 1. */ - -/* Descriptor for system dependent string segment. */ -struct sysdep_segment -{ - /* Length of addressed string, including the trailing NUL. */ - nls_uint32 length; - /* Offset of string in file. */ - nls_uint32 offset; -}; - -/* Descriptor for system dependent string. */ -struct sysdep_string -{ - /* Offset of static string segments in file. */ - nls_uint32 offset; - /* Alternating sequence of static and system dependent segments. - The last segment is a static segment, including the trailing NUL. */ - struct segment_pair - { - /* Size of static segment. */ - nls_uint32 segsize; - /* Reference to system dependent string segment, or ~0 at the end. */ - nls_uint32 sysdepref; - } segments[1]; -}; - -/* Marker for the end of the segments[] array. This has the value 0xFFFFFFFF, - regardless whether 'int' is 16 bit, 32 bit, or 64 bit. */ -#define SEGMENTS_END ((nls_uint32) ~0) - -/* @@ begin of epilog @@ */ - -#endif /* gettext.h */ diff --git a/intl/hash-string.h b/intl/hash-string.h deleted file mode 100644 index b267a8778..000000000 --- a/intl/hash-string.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Description of GNU message catalog format: string hashing function. - Copyright (C) 1995, 1997, 1998, 2000, 2001 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* @@ end of prolog @@ */ - -#ifndef PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -#endif - -/* We assume to have `unsigned long int' value with at least 32 bits. */ -#define HASHWORDBITS 32 - - -/* Defines the so called `hashpjw' function by P.J. Weinberger - [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, - 1986, 1987 Bell Telephone Laboratories, Inc.] */ -static unsigned long int hash_string PARAMS ((const char *__str_param)); - -static inline unsigned long int -hash_string (str_param) - const char *str_param; -{ - unsigned long int hval, g; - const char *str = str_param; - - /* Compute the hash value for the given string. */ - hval = 0; - while (*str != '\0') - { - hval <<= 4; - hval += (unsigned long int) *str++; - g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4)); - if (g != 0) - { - hval ^= g >> (HASHWORDBITS - 8); - hval ^= g; - } - } - return hval; -} diff --git a/intl/intl-compat.c b/intl/intl-compat.c deleted file mode 100644 index 36b7af0f8..000000000 --- a/intl/intl-compat.c +++ /dev/null @@ -1,151 +0,0 @@ -/* intl-compat.c - Stub functions to call gettext functions from GNU gettext - Library. - Copyright (C) 1995, 2000-2003 Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include "gettextP.h" - -/* @@ end of prolog @@ */ - -/* This file redirects the gettext functions (without prefix) to those - defined in the included GNU libintl library (with "libintl_" prefix). - It is compiled into libintl in order to make the AM_GNU_GETTEXT test - of gettext <= 0.11.2 work with the libintl library >= 0.11.3 which - has the redirections primarily in the <libintl.h> include file. - It is also compiled into libgnuintl so that libgnuintl.so can be used - as LD_PRELOADable library on glibc systems, to provide the extra - features that the functions in the libc don't have (namely, logging). */ - - -#undef gettext -#undef dgettext -#undef dcgettext -#undef ngettext -#undef dngettext -#undef dcngettext -#undef textdomain -#undef bindtextdomain -#undef bind_textdomain_codeset - - -/* When building a DLL, we must export some functions. Note that because - the functions are only defined for binary backward compatibility, we - don't need to use __declspec(dllimport) in any case. */ -#if defined _MSC_VER && BUILDING_DLL -# define DLL_EXPORTED __declspec(dllexport) -#else -# define DLL_EXPORTED -#endif - - -DLL_EXPORTED -char * -gettext (msgid) - const char *msgid; -{ - return libintl_gettext (msgid); -} - - -DLL_EXPORTED -char * -dgettext (domainname, msgid) - const char *domainname; - const char *msgid; -{ - return libintl_dgettext (domainname, msgid); -} - - -DLL_EXPORTED -char * -dcgettext (domainname, msgid, category) - const char *domainname; - const char *msgid; - int category; -{ - return libintl_dcgettext (domainname, msgid, category); -} - - -DLL_EXPORTED -char * -ngettext (msgid1, msgid2, n) - const char *msgid1; - const char *msgid2; - unsigned long int n; -{ - return libintl_ngettext (msgid1, msgid2, n); -} - - -DLL_EXPORTED -char * -dngettext (domainname, msgid1, msgid2, n) - const char *domainname; - const char *msgid1; - const char *msgid2; - unsigned long int n; -{ - return libintl_dngettext (domainname, msgid1, msgid2, n); -} - - -DLL_EXPORTED -char * -dcngettext (domainname, msgid1, msgid2, n, category) - const char *domainname; - const char *msgid1; - const char *msgid2; - unsigned long int n; - int category; -{ - return libintl_dcngettext (domainname, msgid1, msgid2, n, category); -} - - -DLL_EXPORTED -char * -textdomain (domainname) - const char *domainname; -{ - return libintl_textdomain (domainname); -} - - -DLL_EXPORTED -char * -bindtextdomain (domainname, dirname) - const char *domainname; - const char *dirname; -{ - return libintl_bindtextdomain (domainname, dirname); -} - - -DLL_EXPORTED -char * -bind_textdomain_codeset (domainname, codeset) - const char *domainname; - const char *codeset; -{ - return libintl_bind_textdomain_codeset (domainname, codeset); -} diff --git a/intl/l10nflist.c b/intl/l10nflist.c deleted file mode 100644 index ec8713f8e..000000000 --- a/intl/l10nflist.c +++ /dev/null @@ -1,453 +0,0 @@ -/* Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc. - Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Tell glibc's <string.h> to provide a prototype for stpcpy(). - This must come before <config.h> because <config.h> may include - <features.h>, and once <features.h> has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <string.h> - -#if defined _LIBC || defined HAVE_ARGZ_H -# include <argz.h> -#endif -#include <ctype.h> -#include <sys/types.h> -#include <stdlib.h> - -#include "loadinfo.h" - -/* On some strange systems still no definition of NULL is found. Sigh! */ -#ifndef NULL -# if defined __STDC__ && __STDC__ -# define NULL ((void *) 0) -# else -# define NULL 0 -# endif -#endif - -/* @@ end of prolog @@ */ - -#ifdef _LIBC -/* Rename the non ANSI C functions. This is required by the standard - because some ANSI C functions will require linking with this object - file and the name space must not be polluted. */ -# ifndef stpcpy -# define stpcpy(dest, src) __stpcpy(dest, src) -# endif -#else -# ifndef HAVE_STPCPY -static char *stpcpy PARAMS ((char *dest, const char *src)); -# endif -#endif - -/* Pathname support. - ISSLASH(C) tests whether C is a directory separator character. - IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not, - it may be concatenated to a directory pathname. - */ -#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS */ -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -# define HAS_DEVICE(P) \ - ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ - && (P)[1] == ':') -# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P)) -#else - /* Unix */ -# define ISSLASH(C) ((C) == '/') -# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0]) -#endif - -/* Define function which are usually not available. */ - -#if !defined _LIBC && !defined HAVE___ARGZ_COUNT -/* Returns the number of strings in ARGZ. */ -static size_t argz_count__ PARAMS ((const char *argz, size_t len)); - -static size_t -argz_count__ (argz, len) - const char *argz; - size_t len; -{ - size_t count = 0; - while (len > 0) - { - size_t part_len = strlen (argz); - argz += part_len + 1; - len -= part_len + 1; - count++; - } - return count; -} -# undef __argz_count -# define __argz_count(argz, len) argz_count__ (argz, len) -#else -# ifdef _LIBC -# define __argz_count(argz, len) INTUSE(__argz_count) (argz, len) -# endif -#endif /* !_LIBC && !HAVE___ARGZ_COUNT */ - -#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY -/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's - except the last into the character SEP. */ -static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep)); - -static void -argz_stringify__ (argz, len, sep) - char *argz; - size_t len; - int sep; -{ - while (len > 0) - { - size_t part_len = strlen (argz); - argz += part_len; - len -= part_len + 1; - if (len > 0) - *argz++ = sep; - } -} -# undef __argz_stringify -# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep) -#else -# ifdef _LIBC -# define __argz_stringify(argz, len, sep) \ - INTUSE(__argz_stringify) (argz, len, sep) -# endif -#endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */ - -#if !defined _LIBC && !defined HAVE___ARGZ_NEXT -static char *argz_next__ PARAMS ((char *argz, size_t argz_len, - const char *entry)); - -static char * -argz_next__ (argz, argz_len, entry) - char *argz; - size_t argz_len; - const char *entry; -{ - if (entry) - { - if (entry < argz + argz_len) - entry = strchr (entry, '\0') + 1; - - return entry >= argz + argz_len ? NULL : (char *) entry; - } - else - if (argz_len > 0) - return argz; - else - return 0; -} -# undef __argz_next -# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry) -#endif /* !_LIBC && !HAVE___ARGZ_NEXT */ - - -/* Return number of bits set in X. */ -static int pop PARAMS ((int x)); - -static inline int -pop (x) - int x; -{ - /* We assume that no more than 16 bits are used. */ - x = ((x & ~0x5555) >> 1) + (x & 0x5555); - x = ((x & ~0x3333) >> 2) + (x & 0x3333); - x = ((x >> 4) + x) & 0x0f0f; - x = ((x >> 8) + x) & 0xff; - - return x; -} - - -struct loaded_l10nfile * -_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language, - territory, codeset, normalized_codeset, modifier, special, - sponsor, revision, filename, do_allocate) - struct loaded_l10nfile **l10nfile_list; - const char *dirlist; - size_t dirlist_len; - int mask; - const char *language; - const char *territory; - const char *codeset; - const char *normalized_codeset; - const char *modifier; - const char *special; - const char *sponsor; - const char *revision; - const char *filename; - int do_allocate; -{ - char *abs_filename; - struct loaded_l10nfile **lastp; - struct loaded_l10nfile *retval; - char *cp; - size_t dirlist_count; - size_t entries; - int cnt; - - /* If LANGUAGE contains an absolute directory specification, we ignore - DIRLIST. */ - if (IS_ABSOLUTE_PATH (language)) - dirlist_len = 0; - - /* Allocate room for the full file name. */ - abs_filename = (char *) malloc (dirlist_len - + strlen (language) - + ((mask & TERRITORY) != 0 - ? strlen (territory) + 1 : 0) - + ((mask & XPG_CODESET) != 0 - ? strlen (codeset) + 1 : 0) - + ((mask & XPG_NORM_CODESET) != 0 - ? strlen (normalized_codeset) + 1 : 0) - + (((mask & XPG_MODIFIER) != 0 - || (mask & CEN_AUDIENCE) != 0) - ? strlen (modifier) + 1 : 0) - + ((mask & CEN_SPECIAL) != 0 - ? strlen (special) + 1 : 0) - + (((mask & CEN_SPONSOR) != 0 - || (mask & CEN_REVISION) != 0) - ? (1 + ((mask & CEN_SPONSOR) != 0 - ? strlen (sponsor) : 0) - + ((mask & CEN_REVISION) != 0 - ? strlen (revision) + 1 : 0)) : 0) - + 1 + strlen (filename) + 1); - - if (abs_filename == NULL) - return NULL; - - /* Construct file name. */ - cp = abs_filename; - if (dirlist_len > 0) - { - memcpy (cp, dirlist, dirlist_len); - __argz_stringify (cp, dirlist_len, PATH_SEPARATOR); - cp += dirlist_len; - cp[-1] = '/'; - } - - cp = stpcpy (cp, language); - - if ((mask & TERRITORY) != 0) - { - *cp++ = '_'; - cp = stpcpy (cp, territory); - } - if ((mask & XPG_CODESET) != 0) - { - *cp++ = '.'; - cp = stpcpy (cp, codeset); - } - if ((mask & XPG_NORM_CODESET) != 0) - { - *cp++ = '.'; - cp = stpcpy (cp, normalized_codeset); - } - if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0) - { - /* This component can be part of both syntaces but has different - leading characters. For CEN we use `+', else `@'. */ - *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@'; - cp = stpcpy (cp, modifier); - } - if ((mask & CEN_SPECIAL) != 0) - { - *cp++ = '+'; - cp = stpcpy (cp, special); - } - if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0) - { - *cp++ = ','; - if ((mask & CEN_SPONSOR) != 0) - cp = stpcpy (cp, sponsor); - if ((mask & CEN_REVISION) != 0) - { - *cp++ = '_'; - cp = stpcpy (cp, revision); - } - } - - *cp++ = '/'; - stpcpy (cp, filename); - - /* Look in list of already loaded domains whether it is already - available. */ - lastp = l10nfile_list; - for (retval = *l10nfile_list; retval != NULL; retval = retval->next) - if (retval->filename != NULL) - { - int compare = strcmp (retval->filename, abs_filename); - if (compare == 0) - /* We found it! */ - break; - if (compare < 0) - { - /* It's not in the list. */ - retval = NULL; - break; - } - - lastp = &retval->next; - } - - if (retval != NULL || do_allocate == 0) - { - free (abs_filename); - return retval; - } - - dirlist_count = (dirlist_len > 0 ? __argz_count (dirlist, dirlist_len) : 1); - - /* Allocate a new loaded_l10nfile. */ - retval = - (struct loaded_l10nfile *) - malloc (sizeof (*retval) - + (((dirlist_count << pop (mask)) + (dirlist_count > 1 ? 1 : 0)) - * sizeof (struct loaded_l10nfile *))); - if (retval == NULL) - return NULL; - - retval->filename = abs_filename; - - /* We set retval->data to NULL here; it is filled in later. - Setting retval->decided to 1 here means that retval does not - correspond to a real file (dirlist_count > 1) or is not worth - looking up (if an unnormalized codeset was specified). */ - retval->decided = (dirlist_count > 1 - || ((mask & XPG_CODESET) != 0 - && (mask & XPG_NORM_CODESET) != 0)); - retval->data = NULL; - - retval->next = *lastp; - *lastp = retval; - - entries = 0; - /* Recurse to fill the inheritance list of RETVAL. - If the DIRLIST is a real list (i.e. DIRLIST_COUNT > 1), the RETVAL - entry does not correspond to a real file; retval->filename contains - colons. In this case we loop across all elements of DIRLIST and - across all bit patterns dominated by MASK. - If the DIRLIST is a single directory or entirely redundant (i.e. - DIRLIST_COUNT == 1), we loop across all bit patterns dominated by - MASK, excluding MASK itself. - In either case, we loop down from MASK to 0. This has the effect - that the extra bits in the locale name are dropped in this order: - first the modifier, then the territory, then the codeset, then the - normalized_codeset. */ - for (cnt = dirlist_count > 1 ? mask : mask - 1; cnt >= 0; --cnt) - if ((cnt & ~mask) == 0 - && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0) - && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0)) - { - if (dirlist_count > 1) - { - /* Iterate over all elements of the DIRLIST. */ - char *dir = NULL; - - while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir)) - != NULL) - retval->successor[entries++] - = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, - cnt, language, territory, codeset, - normalized_codeset, modifier, special, - sponsor, revision, filename, 1); - } - else - retval->successor[entries++] - = _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, - cnt, language, territory, codeset, - normalized_codeset, modifier, special, - sponsor, revision, filename, 1); - } - retval->successor[entries] = NULL; - - return retval; -} - -/* Normalize codeset name. There is no standard for the codeset - names. Normalization allows the user to use any of the common - names. The return value is dynamically allocated and has to be - freed by the caller. */ -const char * -_nl_normalize_codeset (codeset, name_len) - const char *codeset; - size_t name_len; -{ - int len = 0; - int only_digit = 1; - char *retval; - char *wp; - size_t cnt; - - for (cnt = 0; cnt < name_len; ++cnt) - if (isalnum ((unsigned char) codeset[cnt])) - { - ++len; - - if (isalpha ((unsigned char) codeset[cnt])) - only_digit = 0; - } - - retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1); - - if (retval != NULL) - { - if (only_digit) - wp = stpcpy (retval, "iso"); - else - wp = retval; - - for (cnt = 0; cnt < name_len; ++cnt) - if (isalpha ((unsigned char) codeset[cnt])) - *wp++ = tolower ((unsigned char) codeset[cnt]); - else if (isdigit ((unsigned char) codeset[cnt])) - *wp++ = codeset[cnt]; - - *wp = '\0'; - } - - return (const char *) retval; -} - - -/* @@ begin of epilog @@ */ - -/* We don't want libintl.a to depend on any other library. So we - avoid the non-standard function stpcpy. In GNU C Library this - function is available, though. Also allow the symbol HAVE_STPCPY - to be defined. */ -#if !_LIBC && !HAVE_STPCPY -static char * -stpcpy (dest, src) - char *dest; - const char *src; -{ - while ((*dest++ = *src++) != '\0') - /* Do nothing. */ ; - return dest - 1; -} -#endif diff --git a/intl/libgnuintl.h b/intl/libgnuintl.h deleted file mode 100644 index ed25fe9f5..000000000 --- a/intl/libgnuintl.h +++ /dev/null @@ -1,296 +0,0 @@ -/* Message catalogs for internationalization. - Copyright (C) 1995-1997, 2000-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _LIBINTL_H -#define _LIBINTL_H 1 - -#include <locale.h> - -/* The LC_MESSAGES locale category is the category used by the functions - gettext() and dgettext(). It is specified in POSIX, but not in ANSI C. - On systems that don't define it, use an arbitrary value instead. - On Solaris, <locale.h> defines __LOCALE_H (or _LOCALE_H in Solaris 2.5) - then includes <libintl.h> (i.e. this file!) and then only defines - LC_MESSAGES. To avoid a redefinition warning, don't define LC_MESSAGES - in this case. */ -#if !defined LC_MESSAGES && !(defined __LOCALE_H || (defined _LOCALE_H && defined __sun)) -# define LC_MESSAGES 1729 -#endif - -/* We define an additional symbol to signal that we use the GNU - implementation of gettext. */ -#define __USE_GNU_GETTEXT 1 - -/* Provide information about the supported file formats. Returns the - maximum minor revision number supported for a given major revision. */ -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) \ - ((major) == 0 ? 1 : -1) - -/* Resolve a platform specific conflict on DJGPP. GNU gettext takes - precedence over _conio_gettext. */ -#ifdef __DJGPP__ -# undef gettext -#endif - -/* Use _INTL_PARAMS, not PARAMS, in order to avoid clashes with identifiers - used by programs. Similarly, test __PROTOTYPES, not PROTOTYPES. */ -#ifndef _INTL_PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define _INTL_PARAMS(args) args -# else -# define _INTL_PARAMS(args) () -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/* We redirect the functions to those prefixed with "libintl_". This is - necessary, because some systems define gettext/textdomain/... in the C - library (namely, Solaris 2.4 and newer, and GNU libc 2.0 and newer). - If we used the unprefixed names, there would be cases where the - definition in the C library would override the one in the libintl.so - shared library. Recall that on ELF systems, the symbols are looked - up in the following order: - 1. in the executable, - 2. in the shared libraries specified on the link command line, in order, - 3. in the dependencies of the shared libraries specified on the link - command line, - 4. in the dlopen()ed shared libraries, in the order in which they were - dlopen()ed. - The definition in the C library would override the one in libintl.so if - either - * -lc is given on the link command line and -lintl isn't, or - * -lc is given on the link command line before -lintl, or - * libintl.so is a dependency of a dlopen()ed shared library but not - linked to the executable at link time. - Since Solaris gettext() behaves differently than GNU gettext(), this - would be unacceptable. - - The redirection happens by default through macros in C, so that &gettext - is independent of the compilation unit, but through inline functions in - C++, in order not to interfere with the name mangling of class fields or - class methods called 'gettext'. */ - -/* The user can define _INTL_REDIRECT_INLINE or _INTL_REDIRECT_MACROS. - If he doesn't, we choose the method. A third possible method is - _INTL_REDIRECT_ASM, supported only by GCC. */ -#if !(defined _INTL_REDIRECT_INLINE || defined _INTL_REDIRECT_MACROS) -# if __GNUC__ >= 2 && (defined __STDC__ || defined __cplusplus) -# define _INTL_REDIRECT_ASM -# else -# ifdef __cplusplus -# define _INTL_REDIRECT_INLINE -# else -# define _INTL_REDIRECT_MACROS -# endif -# endif -#endif -/* Auxiliary macros. */ -#ifdef _INTL_REDIRECT_ASM -# define _INTL_ASM(cname) __asm__ (_INTL_ASMNAME (__USER_LABEL_PREFIX__, #cname)) -# define _INTL_ASMNAME(prefix,cnamestring) _INTL_STRINGIFY (prefix) cnamestring -# define _INTL_STRINGIFY(prefix) #prefix -#else -# define _INTL_ASM(cname) -#endif - -/* Look up MSGID in the current default message catalog for the current - LC_MESSAGES locale. If not found, returns MSGID itself (the default - text). */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_gettext (const char *__msgid); -static inline char *gettext (const char *__msgid) -{ - return libintl_gettext (__msgid); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define gettext libintl_gettext -#endif -extern char *gettext _INTL_PARAMS ((const char *__msgid)) - _INTL_ASM (libintl_gettext); -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current - LC_MESSAGES locale. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dgettext (const char *__domainname, const char *__msgid); -static inline char *dgettext (const char *__domainname, const char *__msgid) -{ - return libintl_dgettext (__domainname, __msgid); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dgettext libintl_dgettext -#endif -extern char *dgettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid)) - _INTL_ASM (libintl_dgettext); -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY - locale. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dcgettext (const char *__domainname, const char *__msgid, - int __category); -static inline char *dcgettext (const char *__domainname, const char *__msgid, - int __category) -{ - return libintl_dcgettext (__domainname, __msgid, __category); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dcgettext libintl_dcgettext -#endif -extern char *dcgettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid, - int __category)) - _INTL_ASM (libintl_dcgettext); -#endif - - -/* Similar to `gettext' but select the plural form corresponding to the - number N. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_ngettext (const char *__msgid1, const char *__msgid2, - unsigned long int __n); -static inline char *ngettext (const char *__msgid1, const char *__msgid2, - unsigned long int __n) -{ - return libintl_ngettext (__msgid1, __msgid2, __n); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define ngettext libintl_ngettext -#endif -extern char *ngettext _INTL_PARAMS ((const char *__msgid1, - const char *__msgid2, - unsigned long int __n)) - _INTL_ASM (libintl_ngettext); -#endif - -/* Similar to `dgettext' but select the plural form corresponding to the - number N. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dngettext (const char *__domainname, const char *__msgid1, - const char *__msgid2, unsigned long int __n); -static inline char *dngettext (const char *__domainname, const char *__msgid1, - const char *__msgid2, unsigned long int __n) -{ - return libintl_dngettext (__domainname, __msgid1, __msgid2, __n); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dngettext libintl_dngettext -#endif -extern char *dngettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - unsigned long int __n)) - _INTL_ASM (libintl_dngettext); -#endif - -/* Similar to `dcgettext' but select the plural form corresponding to the - number N. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dcngettext (const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int __n, int __category); -static inline char *dcngettext (const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int __n, int __category) -{ - return libintl_dcngettext (__domainname, __msgid1, __msgid2, __n, __category); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dcngettext libintl_dcngettext -#endif -extern char *dcngettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - unsigned long int __n, - int __category)) - _INTL_ASM (libintl_dcngettext); -#endif - - -/* Set the current default message catalog to DOMAINNAME. - If DOMAINNAME is null, return the current default. - If DOMAINNAME is "", reset to the default of "messages". */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_textdomain (const char *__domainname); -static inline char *textdomain (const char *__domainname) -{ - return libintl_textdomain (__domainname); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define textdomain libintl_textdomain -#endif -extern char *textdomain _INTL_PARAMS ((const char *__domainname)) - _INTL_ASM (libintl_textdomain); -#endif - -/* Specify that the DOMAINNAME message catalog will be found - in DIRNAME rather than in the system locale data base. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_bindtextdomain (const char *__domainname, - const char *__dirname); -static inline char *bindtextdomain (const char *__domainname, - const char *__dirname) -{ - return libintl_bindtextdomain (__domainname, __dirname); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define bindtextdomain libintl_bindtextdomain -#endif -extern char *bindtextdomain _INTL_PARAMS ((const char *__domainname, - const char *__dirname)) - _INTL_ASM (libintl_bindtextdomain); -#endif - -/* Specify the character encoding in which the messages from the - DOMAINNAME message catalog will be returned. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_bind_textdomain_codeset (const char *__domainname, - const char *__codeset); -static inline char *bind_textdomain_codeset (const char *__domainname, - const char *__codeset) -{ - return libintl_bind_textdomain_codeset (__domainname, __codeset); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define bind_textdomain_codeset libintl_bind_textdomain_codeset -#endif -extern char *bind_textdomain_codeset _INTL_PARAMS ((const char *__domainname, - const char *__codeset)) - _INTL_ASM (libintl_bind_textdomain_codeset); -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* libintl.h */ diff --git a/intl/libgnuintl.h.in b/intl/libgnuintl.h.in deleted file mode 100644 index f596cfcb2..000000000 --- a/intl/libgnuintl.h.in +++ /dev/null @@ -1,309 +0,0 @@ -/* Message catalogs for internationalization. - Copyright (C) 1995-1997, 2000-2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _LIBINTL_H -#define _LIBINTL_H 1 - -#include <locale.h> - -/* The LC_MESSAGES locale category is the category used by the functions - gettext() and dgettext(). It is specified in POSIX, but not in ANSI C. - On systems that don't define it, use an arbitrary value instead. - On Solaris, <locale.h> defines __LOCALE_H (or _LOCALE_H in Solaris 2.5) - then includes <libintl.h> (i.e. this file!) and then only defines - LC_MESSAGES. To avoid a redefinition warning, don't define LC_MESSAGES - in this case. */ -#if !defined LC_MESSAGES && !(defined __LOCALE_H || (defined _LOCALE_H && defined __sun)) -# define LC_MESSAGES 1729 -#endif - -/* We define an additional symbol to signal that we use the GNU - implementation of gettext. */ -#define __USE_GNU_GETTEXT 1 - -/* Provide information about the supported file formats. Returns the - maximum minor revision number supported for a given major revision. */ -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) \ - ((major) == 0 ? 1 : -1) - -/* Resolve a platform specific conflict on DJGPP. GNU gettext takes - precedence over _conio_gettext. */ -#ifdef __DJGPP__ -# undef gettext -#endif - -/* Use _INTL_PARAMS, not PARAMS, in order to avoid clashes with identifiers - used by programs. Similarly, test __PROTOTYPES, not PROTOTYPES. */ -#ifndef _INTL_PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define _INTL_PARAMS(args) args -# else -# define _INTL_PARAMS(args) () -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/* We redirect the functions to those prefixed with "libintl_". This is - necessary, because some systems define gettext/textdomain/... in the C - library (namely, Solaris 2.4 and newer, and GNU libc 2.0 and newer). - If we used the unprefixed names, there would be cases where the - definition in the C library would override the one in the libintl.so - shared library. Recall that on ELF systems, the symbols are looked - up in the following order: - 1. in the executable, - 2. in the shared libraries specified on the link command line, in order, - 3. in the dependencies of the shared libraries specified on the link - command line, - 4. in the dlopen()ed shared libraries, in the order in which they were - dlopen()ed. - The definition in the C library would override the one in libintl.so if - either - * -lc is given on the link command line and -lintl isn't, or - * -lc is given on the link command line before -lintl, or - * libintl.so is a dependency of a dlopen()ed shared library but not - linked to the executable at link time. - Since Solaris gettext() behaves differently than GNU gettext(), this - would be unacceptable. - - The redirection happens by default through macros in C, so that &gettext - is independent of the compilation unit, but through inline functions in - C++, in order not to interfere with the name mangling of class fields or - class methods called 'gettext'. */ - -/* The user can define _INTL_REDIRECT_INLINE or _INTL_REDIRECT_MACROS. - If he doesn't, we choose the method. A third possible method is - _INTL_REDIRECT_ASM, supported only by GCC. */ -#if !(defined _INTL_REDIRECT_INLINE || defined _INTL_REDIRECT_MACROS) -# if __GNUC__ >= 2 && !defined __APPLE_CC__ && (defined __STDC__ || defined __cplusplus) -# define _INTL_REDIRECT_ASM -# else -# ifdef __cplusplus -# define _INTL_REDIRECT_INLINE -# else -# define _INTL_REDIRECT_MACROS -# endif -# endif -#endif -/* Auxiliary macros. */ -#ifdef _INTL_REDIRECT_ASM -# define _INTL_ASM(cname) __asm__ (_INTL_ASMNAME (__USER_LABEL_PREFIX__, #cname)) -# define _INTL_ASMNAME(prefix,cnamestring) _INTL_STRINGIFY (prefix) cnamestring -# define _INTL_STRINGIFY(prefix) #prefix -#else -# define _INTL_ASM(cname) -#endif - -/* Look up MSGID in the current default message catalog for the current - LC_MESSAGES locale. If not found, returns MSGID itself (the default - text). */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_gettext (const char *__msgid); -static inline char *gettext (const char *__msgid) -{ - return libintl_gettext (__msgid); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define gettext libintl_gettext -#endif -extern char *gettext _INTL_PARAMS ((const char *__msgid)) - _INTL_ASM (libintl_gettext); -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current - LC_MESSAGES locale. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dgettext (const char *__domainname, const char *__msgid); -static inline char *dgettext (const char *__domainname, const char *__msgid) -{ - return libintl_dgettext (__domainname, __msgid); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dgettext libintl_dgettext -#endif -extern char *dgettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid)) - _INTL_ASM (libintl_dgettext); -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY - locale. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dcgettext (const char *__domainname, const char *__msgid, - int __category); -static inline char *dcgettext (const char *__domainname, const char *__msgid, - int __category) -{ - return libintl_dcgettext (__domainname, __msgid, __category); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dcgettext libintl_dcgettext -#endif -extern char *dcgettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid, - int __category)) - _INTL_ASM (libintl_dcgettext); -#endif - - -/* Similar to `gettext' but select the plural form corresponding to the - number N. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_ngettext (const char *__msgid1, const char *__msgid2, - unsigned long int __n); -static inline char *ngettext (const char *__msgid1, const char *__msgid2, - unsigned long int __n) -{ - return libintl_ngettext (__msgid1, __msgid2, __n); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define ngettext libintl_ngettext -#endif -extern char *ngettext _INTL_PARAMS ((const char *__msgid1, - const char *__msgid2, - unsigned long int __n)) - _INTL_ASM (libintl_ngettext); -#endif - -/* Similar to `dgettext' but select the plural form corresponding to the - number N. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dngettext (const char *__domainname, const char *__msgid1, - const char *__msgid2, unsigned long int __n); -static inline char *dngettext (const char *__domainname, const char *__msgid1, - const char *__msgid2, unsigned long int __n) -{ - return libintl_dngettext (__domainname, __msgid1, __msgid2, __n); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dngettext libintl_dngettext -#endif -extern char *dngettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - unsigned long int __n)) - _INTL_ASM (libintl_dngettext); -#endif - -/* Similar to `dcgettext' but select the plural form corresponding to the - number N. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dcngettext (const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int __n, int __category); -static inline char *dcngettext (const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int __n, int __category) -{ - return libintl_dcngettext (__domainname, __msgid1, __msgid2, __n, __category); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dcngettext libintl_dcngettext -#endif -extern char *dcngettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - unsigned long int __n, - int __category)) - _INTL_ASM (libintl_dcngettext); -#endif - - -/* Set the current default message catalog to DOMAINNAME. - If DOMAINNAME is null, return the current default. - If DOMAINNAME is "", reset to the default of "messages". */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_textdomain (const char *__domainname); -static inline char *textdomain (const char *__domainname) -{ - return libintl_textdomain (__domainname); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define textdomain libintl_textdomain -#endif -extern char *textdomain _INTL_PARAMS ((const char *__domainname)) - _INTL_ASM (libintl_textdomain); -#endif - -/* Specify that the DOMAINNAME message catalog will be found - in DIRNAME rather than in the system locale data base. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_bindtextdomain (const char *__domainname, - const char *__dirname); -static inline char *bindtextdomain (const char *__domainname, - const char *__dirname) -{ - return libintl_bindtextdomain (__domainname, __dirname); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define bindtextdomain libintl_bindtextdomain -#endif -extern char *bindtextdomain _INTL_PARAMS ((const char *__domainname, - const char *__dirname)) - _INTL_ASM (libintl_bindtextdomain); -#endif - -/* Specify the character encoding in which the messages from the - DOMAINNAME message catalog will be returned. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_bind_textdomain_codeset (const char *__domainname, - const char *__codeset); -static inline char *bind_textdomain_codeset (const char *__domainname, - const char *__codeset) -{ - return libintl_bind_textdomain_codeset (__domainname, __codeset); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define bind_textdomain_codeset libintl_bind_textdomain_codeset -#endif -extern char *bind_textdomain_codeset _INTL_PARAMS ((const char *__domainname, - const char *__codeset)) - _INTL_ASM (libintl_bind_textdomain_codeset); -#endif - - -/* Support for relocatable packages. */ - -/* Sets the original and the current installation prefix of the package. - Relocation simply replaces a pathname starting with the original prefix - by the corresponding pathname with the current prefix instead. Both - prefixes should be directory names without trailing slash (i.e. use "" - instead of "/"). */ -#define libintl_set_relocation_prefix libintl_set_relocation_prefix -extern void - libintl_set_relocation_prefix _INTL_PARAMS ((const char *orig_prefix, - const char *curr_prefix)); - - -#ifdef __cplusplus -} -#endif - -#endif /* libintl.h */ diff --git a/intl/loadinfo.h b/intl/loadinfo.h deleted file mode 100644 index 1d3ba6162..000000000 --- a/intl/loadinfo.h +++ /dev/null @@ -1,156 +0,0 @@ -/* Copyright (C) 1996-1999, 2000-2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _LOADINFO_H -#define _LOADINFO_H 1 - -/* Declarations of locale dependent catalog lookup functions. - Implemented in - - localealias.c Possibly replace a locale name by another. - explodename.c Split a locale name into its various fields. - l10nflist.c Generate a list of filenames of possible message catalogs. - finddomain.c Find and open the relevant message catalogs. - - The main function _nl_find_domain() in finddomain.c is declared - in gettextP.h. - */ - -#ifndef PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - -#ifndef internal_function -# define internal_function -#endif - -/* Tell the compiler when a conditional or integer expression is - almost always true or almost always false. */ -#ifndef HAVE_BUILTIN_EXPECT -# define __builtin_expect(expr, val) (expr) -#endif - -/* Separator in PATH like lists of pathnames. */ -#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS */ -# define PATH_SEPARATOR ';' -#else - /* Unix */ -# define PATH_SEPARATOR ':' -#endif - -/* Encoding of locale name parts. */ -#define CEN_REVISION 1 -#define CEN_SPONSOR 2 -#define CEN_SPECIAL 4 -#define XPG_NORM_CODESET 8 -#define XPG_CODESET 16 -#define TERRITORY 32 -#define CEN_AUDIENCE 64 -#define XPG_MODIFIER 128 - -#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE) -#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER) - - -struct loaded_l10nfile -{ - const char *filename; - int decided; - - const void *data; - - struct loaded_l10nfile *next; - struct loaded_l10nfile *successor[1]; -}; - - -/* Normalize codeset name. There is no standard for the codeset - names. Normalization allows the user to use any of the common - names. The return value is dynamically allocated and has to be - freed by the caller. */ -extern const char *_nl_normalize_codeset PARAMS ((const char *codeset, - size_t name_len)); - -/* Lookup a locale dependent file. - *L10NFILE_LIST denotes a pool of lookup results of locale dependent - files of the same kind, sorted in decreasing order of ->filename. - DIRLIST and DIRLIST_LEN are an argz list of directories in which to - look, containing at least one directory (i.e. DIRLIST_LEN > 0). - MASK, LANGUAGE, TERRITORY, CODESET, NORMALIZED_CODESET, MODIFIER, - SPECIAL, SPONSOR, REVISION are the pieces of the locale name, as - produced by _nl_explode_name(). FILENAME is the filename suffix. - The return value is the lookup result, either found in *L10NFILE_LIST, - or - if DO_ALLOCATE is nonzero - freshly allocated, or possibly NULL. - If the return value is non-NULL, it is added to *L10NFILE_LIST, and - its ->next field denotes the chaining inside *L10NFILE_LIST, and - furthermore its ->successor[] field contains a list of other lookup - results from which this lookup result inherits. */ -extern struct loaded_l10nfile * -_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list, - const char *dirlist, size_t dirlist_len, int mask, - const char *language, const char *territory, - const char *codeset, - const char *normalized_codeset, - const char *modifier, const char *special, - const char *sponsor, const char *revision, - const char *filename, int do_allocate)); - -/* Lookup the real locale name for a locale alias NAME, or NULL if - NAME is not a locale alias (but possibly a real locale name). - The return value is statically allocated and must not be freed. */ -extern const char *_nl_expand_alias PARAMS ((const char *name)); - -/* Split a locale name NAME into its pieces: language, modifier, - territory, codeset, special, sponsor, revision. - NAME gets destructively modified: NUL bytes are inserted here and - there. *LANGUAGE gets assigned NAME. Each of *MODIFIER, *TERRITORY, - *CODESET, *SPECIAL, *SPONSOR, *REVISION gets assigned either a - pointer into the old NAME string, or NULL. *NORMALIZED_CODESET - gets assigned the expanded *CODESET, if it is different from *CODESET; - this one is dynamically allocated and has to be freed by the caller. - The return value is a bitmask, where each bit corresponds to one - filled-in value: - XPG_MODIFIER, CEN_AUDIENCE for *MODIFIER, - TERRITORY for *TERRITORY, - XPG_CODESET for *CODESET, - XPG_NORM_CODESET for *NORMALIZED_CODESET, - CEN_SPECIAL for *SPECIAL, - CEN_SPONSOR for *SPONSOR, - CEN_REVISION for *REVISION. - */ -extern int _nl_explode_name PARAMS ((char *name, const char **language, - const char **modifier, - const char **territory, - const char **codeset, - const char **normalized_codeset, - const char **special, - const char **sponsor, - const char **revision)); - -/* Split a locale name NAME into a leading language part and all the - rest. Return a pointer to the first character after the language, - i.e. to the first byte of the rest. */ -extern char *_nl_find_language PARAMS ((const char *name)); - -#endif /* loadinfo.h */ diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c deleted file mode 100644 index 8509bd345..000000000 --- a/intl/loadmsgcat.c +++ /dev/null @@ -1,1322 +0,0 @@ -/* Load needed message catalogs. - Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Tell glibc's <string.h> to provide a prototype for mempcpy(). - This must come before <config.h> because <config.h> may include - <features.h>, and once <features.h> has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef __GNUC__ -# undef alloca -# define alloca __builtin_alloca -# define HAVE_ALLOCA 1 -#else -# ifdef _MSC_VER -# include <malloc.h> -# define alloca _alloca -# else -# if defined HAVE_ALLOCA_H || defined _LIBC -# include <alloca.h> -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca -char *alloca (); -# endif -# endif -# endif -# endif -#endif - -#include <stdlib.h> -#include <string.h> - -#if defined HAVE_UNISTD_H || defined _LIBC -# include <unistd.h> -#endif - -#ifdef _LIBC -# include <langinfo.h> -# include <locale.h> -#endif - -#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ - || (defined _LIBC && defined _POSIX_MAPPED_FILES) -# include <sys/mman.h> -# undef HAVE_MMAP -# define HAVE_MMAP 1 -#else -# undef HAVE_MMAP -#endif - -#if defined HAVE_STDINT_H_WITH_UINTMAX || defined _LIBC -# include <stdint.h> -#endif -#if defined HAVE_INTTYPES_H || defined _LIBC -# include <inttypes.h> -#endif - -#include "gmo.h" -#include "gettextP.h" -#include "hash-string.h" -#include "plural-exp.h" - -#ifdef _LIBC -# include "../locale/localeinfo.h" -#endif - -/* Provide fallback values for macros that ought to be defined in <inttypes.h>. - Note that our fallback values need not be literal strings, because we don't - use them with preprocessor string concatenation. */ -#if !defined PRId8 || PRI_MACROS_BROKEN -# undef PRId8 -# define PRId8 "d" -#endif -#if !defined PRIi8 || PRI_MACROS_BROKEN -# undef PRIi8 -# define PRIi8 "i" -#endif -#if !defined PRIo8 || PRI_MACROS_BROKEN -# undef PRIo8 -# define PRIo8 "o" -#endif -#if !defined PRIu8 || PRI_MACROS_BROKEN -# undef PRIu8 -# define PRIu8 "u" -#endif -#if !defined PRIx8 || PRI_MACROS_BROKEN -# undef PRIx8 -# define PRIx8 "x" -#endif -#if !defined PRIX8 || PRI_MACROS_BROKEN -# undef PRIX8 -# define PRIX8 "X" -#endif -#if !defined PRId16 || PRI_MACROS_BROKEN -# undef PRId16 -# define PRId16 "d" -#endif -#if !defined PRIi16 || PRI_MACROS_BROKEN -# undef PRIi16 -# define PRIi16 "i" -#endif -#if !defined PRIo16 || PRI_MACROS_BROKEN -# undef PRIo16 -# define PRIo16 "o" -#endif -#if !defined PRIu16 || PRI_MACROS_BROKEN -# undef PRIu16 -# define PRIu16 "u" -#endif -#if !defined PRIx16 || PRI_MACROS_BROKEN -# undef PRIx16 -# define PRIx16 "x" -#endif -#if !defined PRIX16 || PRI_MACROS_BROKEN -# undef PRIX16 -# define PRIX16 "X" -#endif -#if !defined PRId32 || PRI_MACROS_BROKEN -# undef PRId32 -# define PRId32 "d" -#endif -#if !defined PRIi32 || PRI_MACROS_BROKEN -# undef PRIi32 -# define PRIi32 "i" -#endif -#if !defined PRIo32 || PRI_MACROS_BROKEN -# undef PRIo32 -# define PRIo32 "o" -#endif -#if !defined PRIu32 || PRI_MACROS_BROKEN -# undef PRIu32 -# define PRIu32 "u" -#endif -#if !defined PRIx32 || PRI_MACROS_BROKEN -# undef PRIx32 -# define PRIx32 "x" -#endif -#if !defined PRIX32 || PRI_MACROS_BROKEN -# undef PRIX32 -# define PRIX32 "X" -#endif -#if !defined PRId64 || PRI_MACROS_BROKEN -# undef PRId64 -# define PRId64 (sizeof (long) == 8 ? "ld" : "lld") -#endif -#if !defined PRIi64 || PRI_MACROS_BROKEN -# undef PRIi64 -# define PRIi64 (sizeof (long) == 8 ? "li" : "lli") -#endif -#if !defined PRIo64 || PRI_MACROS_BROKEN -# undef PRIo64 -# define PRIo64 (sizeof (long) == 8 ? "lo" : "llo") -#endif -#if !defined PRIu64 || PRI_MACROS_BROKEN -# undef PRIu64 -# define PRIu64 (sizeof (long) == 8 ? "lu" : "llu") -#endif -#if !defined PRIx64 || PRI_MACROS_BROKEN -# undef PRIx64 -# define PRIx64 (sizeof (long) == 8 ? "lx" : "llx") -#endif -#if !defined PRIX64 || PRI_MACROS_BROKEN -# undef PRIX64 -# define PRIX64 (sizeof (long) == 8 ? "lX" : "llX") -#endif -#if !defined PRIdLEAST8 || PRI_MACROS_BROKEN -# undef PRIdLEAST8 -# define PRIdLEAST8 "d" -#endif -#if !defined PRIiLEAST8 || PRI_MACROS_BROKEN -# undef PRIiLEAST8 -# define PRIiLEAST8 "i" -#endif -#if !defined PRIoLEAST8 || PRI_MACROS_BROKEN -# undef PRIoLEAST8 -# define PRIoLEAST8 "o" -#endif -#if !defined PRIuLEAST8 || PRI_MACROS_BROKEN -# undef PRIuLEAST8 -# define PRIuLEAST8 "u" -#endif -#if !defined PRIxLEAST8 || PRI_MACROS_BROKEN -# undef PRIxLEAST8 -# define PRIxLEAST8 "x" -#endif -#if !defined PRIXLEAST8 || PRI_MACROS_BROKEN -# undef PRIXLEAST8 -# define PRIXLEAST8 "X" -#endif -#if !defined PRIdLEAST16 || PRI_MACROS_BROKEN -# undef PRIdLEAST16 -# define PRIdLEAST16 "d" -#endif -#if !defined PRIiLEAST16 || PRI_MACROS_BROKEN -# undef PRIiLEAST16 -# define PRIiLEAST16 "i" -#endif -#if !defined PRIoLEAST16 || PRI_MACROS_BROKEN -# undef PRIoLEAST16 -# define PRIoLEAST16 "o" -#endif -#if !defined PRIuLEAST16 || PRI_MACROS_BROKEN -# undef PRIuLEAST16 -# define PRIuLEAST16 "u" -#endif -#if !defined PRIxLEAST16 || PRI_MACROS_BROKEN -# undef PRIxLEAST16 -# define PRIxLEAST16 "x" -#endif -#if !defined PRIXLEAST16 || PRI_MACROS_BROKEN -# undef PRIXLEAST16 -# define PRIXLEAST16 "X" -#endif -#if !defined PRIdLEAST32 || PRI_MACROS_BROKEN -# undef PRIdLEAST32 -# define PRIdLEAST32 "d" -#endif -#if !defined PRIiLEAST32 || PRI_MACROS_BROKEN -# undef PRIiLEAST32 -# define PRIiLEAST32 "i" -#endif -#if !defined PRIoLEAST32 || PRI_MACROS_BROKEN -# undef PRIoLEAST32 -# define PRIoLEAST32 "o" -#endif -#if !defined PRIuLEAST32 || PRI_MACROS_BROKEN -# undef PRIuLEAST32 -# define PRIuLEAST32 "u" -#endif -#if !defined PRIxLEAST32 || PRI_MACROS_BROKEN -# undef PRIxLEAST32 -# define PRIxLEAST32 "x" -#endif -#if !defined PRIXLEAST32 || PRI_MACROS_BROKEN -# undef PRIXLEAST32 -# define PRIXLEAST32 "X" -#endif -#if !defined PRIdLEAST64 || PRI_MACROS_BROKEN -# undef PRIdLEAST64 -# define PRIdLEAST64 PRId64 -#endif -#if !defined PRIiLEAST64 || PRI_MACROS_BROKEN -# undef PRIiLEAST64 -# define PRIiLEAST64 PRIi64 -#endif -#if !defined PRIoLEAST64 || PRI_MACROS_BROKEN -# undef PRIoLEAST64 -# define PRIoLEAST64 PRIo64 -#endif -#if !defined PRIuLEAST64 || PRI_MACROS_BROKEN -# undef PRIuLEAST64 -# define PRIuLEAST64 PRIu64 -#endif -#if !defined PRIxLEAST64 || PRI_MACROS_BROKEN -# undef PRIxLEAST64 -# define PRIxLEAST64 PRIx64 -#endif -#if !defined PRIXLEAST64 || PRI_MACROS_BROKEN -# undef PRIXLEAST64 -# define PRIXLEAST64 PRIX64 -#endif -#if !defined PRIdFAST8 || PRI_MACROS_BROKEN -# undef PRIdFAST8 -# define PRIdFAST8 "d" -#endif -#if !defined PRIiFAST8 || PRI_MACROS_BROKEN -# undef PRIiFAST8 -# define PRIiFAST8 "i" -#endif -#if !defined PRIoFAST8 || PRI_MACROS_BROKEN -# undef PRIoFAST8 -# define PRIoFAST8 "o" -#endif -#if !defined PRIuFAST8 || PRI_MACROS_BROKEN -# undef PRIuFAST8 -# define PRIuFAST8 "u" -#endif -#if !defined PRIxFAST8 || PRI_MACROS_BROKEN -# undef PRIxFAST8 -# define PRIxFAST8 "x" -#endif -#if !defined PRIXFAST8 || PRI_MACROS_BROKEN -# undef PRIXFAST8 -# define PRIXFAST8 "X" -#endif -#if !defined PRIdFAST16 || PRI_MACROS_BROKEN -# undef PRIdFAST16 -# define PRIdFAST16 "d" -#endif -#if !defined PRIiFAST16 || PRI_MACROS_BROKEN -# undef PRIiFAST16 -# define PRIiFAST16 "i" -#endif -#if !defined PRIoFAST16 || PRI_MACROS_BROKEN -# undef PRIoFAST16 -# define PRIoFAST16 "o" -#endif -#if !defined PRIuFAST16 || PRI_MACROS_BROKEN -# undef PRIuFAST16 -# define PRIuFAST16 "u" -#endif -#if !defined PRIxFAST16 || PRI_MACROS_BROKEN -# undef PRIxFAST16 -# define PRIxFAST16 "x" -#endif -#if !defined PRIXFAST16 || PRI_MACROS_BROKEN -# undef PRIXFAST16 -# define PRIXFAST16 "X" -#endif -#if !defined PRIdFAST32 || PRI_MACROS_BROKEN -# undef PRIdFAST32 -# define PRIdFAST32 "d" -#endif -#if !defined PRIiFAST32 || PRI_MACROS_BROKEN -# undef PRIiFAST32 -# define PRIiFAST32 "i" -#endif -#if !defined PRIoFAST32 || PRI_MACROS_BROKEN -# undef PRIoFAST32 -# define PRIoFAST32 "o" -#endif -#if !defined PRIuFAST32 || PRI_MACROS_BROKEN -# undef PRIuFAST32 -# define PRIuFAST32 "u" -#endif -#if !defined PRIxFAST32 || PRI_MACROS_BROKEN -# undef PRIxFAST32 -# define PRIxFAST32 "x" -#endif -#if !defined PRIXFAST32 || PRI_MACROS_BROKEN -# undef PRIXFAST32 -# define PRIXFAST32 "X" -#endif -#if !defined PRIdFAST64 || PRI_MACROS_BROKEN -# undef PRIdFAST64 -# define PRIdFAST64 PRId64 -#endif -#if !defined PRIiFAST64 || PRI_MACROS_BROKEN -# undef PRIiFAST64 -# define PRIiFAST64 PRIi64 -#endif -#if !defined PRIoFAST64 || PRI_MACROS_BROKEN -# undef PRIoFAST64 -# define PRIoFAST64 PRIo64 -#endif -#if !defined PRIuFAST64 || PRI_MACROS_BROKEN -# undef PRIuFAST64 -# define PRIuFAST64 PRIu64 -#endif -#if !defined PRIxFAST64 || PRI_MACROS_BROKEN -# undef PRIxFAST64 -# define PRIxFAST64 PRIx64 -#endif -#if !defined PRIXFAST64 || PRI_MACROS_BROKEN -# undef PRIXFAST64 -# define PRIXFAST64 PRIX64 -#endif -#if !defined PRIdMAX || PRI_MACROS_BROKEN -# undef PRIdMAX -# define PRIdMAX (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld") -#endif -#if !defined PRIiMAX || PRI_MACROS_BROKEN -# undef PRIiMAX -# define PRIiMAX (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli") -#endif -#if !defined PRIoMAX || PRI_MACROS_BROKEN -# undef PRIoMAX -# define PRIoMAX (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo") -#endif -#if !defined PRIuMAX || PRI_MACROS_BROKEN -# undef PRIuMAX -# define PRIuMAX (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu") -#endif -#if !defined PRIxMAX || PRI_MACROS_BROKEN -# undef PRIxMAX -# define PRIxMAX (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx") -#endif -#if !defined PRIXMAX || PRI_MACROS_BROKEN -# undef PRIXMAX -# define PRIXMAX (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX") -#endif -#if !defined PRIdPTR || PRI_MACROS_BROKEN -# undef PRIdPTR -# define PRIdPTR \ - (sizeof (void *) == sizeof (long) ? "ld" : \ - sizeof (void *) == sizeof (int) ? "d" : \ - "lld") -#endif -#if !defined PRIiPTR || PRI_MACROS_BROKEN -# undef PRIiPTR -# define PRIiPTR \ - (sizeof (void *) == sizeof (long) ? "li" : \ - sizeof (void *) == sizeof (int) ? "i" : \ - "lli") -#endif -#if !defined PRIoPTR || PRI_MACROS_BROKEN -# undef PRIoPTR -# define PRIoPTR \ - (sizeof (void *) == sizeof (long) ? "lo" : \ - sizeof (void *) == sizeof (int) ? "o" : \ - "llo") -#endif -#if !defined PRIuPTR || PRI_MACROS_BROKEN -# undef PRIuPTR -# define PRIuPTR \ - (sizeof (void *) == sizeof (long) ? "lu" : \ - sizeof (void *) == sizeof (int) ? "u" : \ - "llu") -#endif -#if !defined PRIxPTR || PRI_MACROS_BROKEN -# undef PRIxPTR -# define PRIxPTR \ - (sizeof (void *) == sizeof (long) ? "lx" : \ - sizeof (void *) == sizeof (int) ? "x" : \ - "llx") -#endif -#if !defined PRIXPTR || PRI_MACROS_BROKEN -# undef PRIXPTR -# define PRIXPTR \ - (sizeof (void *) == sizeof (long) ? "lX" : \ - sizeof (void *) == sizeof (int) ? "X" : \ - "llX") -#endif - -/* @@ end of prolog @@ */ - -#ifdef _LIBC -/* Rename the non ISO C functions. This is required by the standard - because some ISO C functions will require linking with this object - file and the name space must not be polluted. */ -# define open __open -# define close __close -# define read __read -# define mmap __mmap -# define munmap __munmap -#endif - -/* For those losing systems which don't have `alloca' we have to add - some additional code emulating it. */ -#ifdef HAVE_ALLOCA -# define freea(p) /* nothing */ -#else -# define alloca(n) malloc (n) -# define freea(p) free (p) -#endif - -/* For systems that distinguish between text and binary I/O. - O_BINARY is usually declared in <fcntl.h>. */ -#if !defined O_BINARY && defined _O_BINARY - /* For MSC-compatible compilers. */ -# define O_BINARY _O_BINARY -# define O_TEXT _O_TEXT -#endif -#ifdef __BEOS__ - /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */ -# undef O_BINARY -# undef O_TEXT -#endif -/* On reasonable systems, binary I/O is the default. */ -#ifndef O_BINARY -# define O_BINARY 0 -#endif - - -/* Prototypes for local functions. Needed to ensure compiler checking of - function argument counts despite of K&R C function definition syntax. */ -static const char *get_sysdep_segment_value PARAMS ((const char *name)); - - -/* We need a sign, whether a new catalog was loaded, which can be associated - with all translations. This is important if the translations are - cached by one of GCC's features. */ -int _nl_msg_cat_cntr; - - -/* Expand a system dependent string segment. Return NULL if unsupported. */ -static const char * -get_sysdep_segment_value (name) - const char *name; -{ - /* Test for an ISO C 99 section 7.8.1 format string directive. - Syntax: - P R I { d | i | o | u | x | X } - { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR } */ - /* We don't use a table of 14 times 6 'const char *' strings here, because - data relocations cost startup time. */ - if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I') - { - if (name[3] == 'd' || name[3] == 'i' || name[3] == 'o' || name[3] == 'u' - || name[3] == 'x' || name[3] == 'X') - { - if (name[4] == '8' && name[5] == '\0') - { - if (name[3] == 'd') - return PRId8; - if (name[3] == 'i') - return PRIi8; - if (name[3] == 'o') - return PRIo8; - if (name[3] == 'u') - return PRIu8; - if (name[3] == 'x') - return PRIx8; - if (name[3] == 'X') - return PRIX8; - abort (); - } - if (name[4] == '1' && name[5] == '6' && name[6] == '\0') - { - if (name[3] == 'd') - return PRId16; - if (name[3] == 'i') - return PRIi16; - if (name[3] == 'o') - return PRIo16; - if (name[3] == 'u') - return PRIu16; - if (name[3] == 'x') - return PRIx16; - if (name[3] == 'X') - return PRIX16; - abort (); - } - if (name[4] == '3' && name[5] == '2' && name[6] == '\0') - { - if (name[3] == 'd') - return PRId32; - if (name[3] == 'i') - return PRIi32; - if (name[3] == 'o') - return PRIo32; - if (name[3] == 'u') - return PRIu32; - if (name[3] == 'x') - return PRIx32; - if (name[3] == 'X') - return PRIX32; - abort (); - } - if (name[4] == '6' && name[5] == '4' && name[6] == '\0') - { - if (name[3] == 'd') - return PRId64; - if (name[3] == 'i') - return PRIi64; - if (name[3] == 'o') - return PRIo64; - if (name[3] == 'u') - return PRIu64; - if (name[3] == 'x') - return PRIx64; - if (name[3] == 'X') - return PRIX64; - abort (); - } - if (name[4] == 'L' && name[5] == 'E' && name[6] == 'A' - && name[7] == 'S' && name[8] == 'T') - { - if (name[9] == '8' && name[10] == '\0') - { - if (name[3] == 'd') - return PRIdLEAST8; - if (name[3] == 'i') - return PRIiLEAST8; - if (name[3] == 'o') - return PRIoLEAST8; - if (name[3] == 'u') - return PRIuLEAST8; - if (name[3] == 'x') - return PRIxLEAST8; - if (name[3] == 'X') - return PRIXLEAST8; - abort (); - } - if (name[9] == '1' && name[10] == '6' && name[11] == '\0') - { - if (name[3] == 'd') - return PRIdLEAST16; - if (name[3] == 'i') - return PRIiLEAST16; - if (name[3] == 'o') - return PRIoLEAST16; - if (name[3] == 'u') - return PRIuLEAST16; - if (name[3] == 'x') - return PRIxLEAST16; - if (name[3] == 'X') - return PRIXLEAST16; - abort (); - } - if (name[9] == '3' && name[10] == '2' && name[11] == '\0') - { - if (name[3] == 'd') - return PRIdLEAST32; - if (name[3] == 'i') - return PRIiLEAST32; - if (name[3] == 'o') - return PRIoLEAST32; - if (name[3] == 'u') - return PRIuLEAST32; - if (name[3] == 'x') - return PRIxLEAST32; - if (name[3] == 'X') - return PRIXLEAST32; - abort (); - } - if (name[9] == '6' && name[10] == '4' && name[11] == '\0') - { - if (name[3] == 'd') - return PRIdLEAST64; - if (name[3] == 'i') - return PRIiLEAST64; - if (name[3] == 'o') - return PRIoLEAST64; - if (name[3] == 'u') - return PRIuLEAST64; - if (name[3] == 'x') - return PRIxLEAST64; - if (name[3] == 'X') - return PRIXLEAST64; - abort (); - } - } - if (name[4] == 'F' && name[5] == 'A' && name[6] == 'S' - && name[7] == 'T') - { - if (name[8] == '8' && name[9] == '\0') - { - if (name[3] == 'd') - return PRIdFAST8; - if (name[3] == 'i') - return PRIiFAST8; - if (name[3] == 'o') - return PRIoFAST8; - if (name[3] == 'u') - return PRIuFAST8; - if (name[3] == 'x') - return PRIxFAST8; - if (name[3] == 'X') - return PRIXFAST8; - abort (); - } - if (name[8] == '1' && name[9] == '6' && name[10] == '\0') - { - if (name[3] == 'd') - return PRIdFAST16; - if (name[3] == 'i') - return PRIiFAST16; - if (name[3] == 'o') - return PRIoFAST16; - if (name[3] == 'u') - return PRIuFAST16; - if (name[3] == 'x') - return PRIxFAST16; - if (name[3] == 'X') - return PRIXFAST16; - abort (); - } - if (name[8] == '3' && name[9] == '2' && name[10] == '\0') - { - if (name[3] == 'd') - return PRIdFAST32; - if (name[3] == 'i') - return PRIiFAST32; - if (name[3] == 'o') - return PRIoFAST32; - if (name[3] == 'u') - return PRIuFAST32; - if (name[3] == 'x') - return PRIxFAST32; - if (name[3] == 'X') - return PRIXFAST32; - abort (); - } - if (name[8] == '6' && name[9] == '4' && name[10] == '\0') - { - if (name[3] == 'd') - return PRIdFAST64; - if (name[3] == 'i') - return PRIiFAST64; - if (name[3] == 'o') - return PRIoFAST64; - if (name[3] == 'u') - return PRIuFAST64; - if (name[3] == 'x') - return PRIxFAST64; - if (name[3] == 'X') - return PRIXFAST64; - abort (); - } - } - if (name[4] == 'M' && name[5] == 'A' && name[6] == 'X' - && name[7] == '\0') - { - if (name[3] == 'd') - return PRIdMAX; - if (name[3] == 'i') - return PRIiMAX; - if (name[3] == 'o') - return PRIoMAX; - if (name[3] == 'u') - return PRIuMAX; - if (name[3] == 'x') - return PRIxMAX; - if (name[3] == 'X') - return PRIXMAX; - abort (); - } - if (name[4] == 'P' && name[5] == 'T' && name[6] == 'R' - && name[7] == '\0') - { - if (name[3] == 'd') - return PRIdPTR; - if (name[3] == 'i') - return PRIiPTR; - if (name[3] == 'o') - return PRIoPTR; - if (name[3] == 'u') - return PRIuPTR; - if (name[3] == 'x') - return PRIxPTR; - if (name[3] == 'X') - return PRIXPTR; - abort (); - } - } - } - /* Other system dependent strings are not valid. */ - return NULL; -} - -/* Initialize the codeset dependent parts of an opened message catalog. - Return the header entry. */ -const char * -internal_function -_nl_init_domain_conv (domain_file, domain, domainbinding) - struct loaded_l10nfile *domain_file; - struct loaded_domain *domain; - struct binding *domainbinding; -{ - /* Find out about the character set the file is encoded with. - This can be found (in textual form) in the entry "". If this - entry does not exist or if this does not contain the `charset=' - information, we will assume the charset matches the one the - current locale and we don't have to perform any conversion. */ - char *nullentry; - size_t nullentrylen; - - /* Preinitialize fields, to avoid recursion during _nl_find_msg. */ - domain->codeset_cntr = - (domainbinding != NULL ? domainbinding->codeset_cntr : 0); -#ifdef _LIBC - domain->conv = (__gconv_t) -1; -#else -# if HAVE_ICONV - domain->conv = (iconv_t) -1; -# endif -#endif - domain->conv_tab = NULL; - - /* Get the header entry. */ - nullentry = _nl_find_msg (domain_file, domainbinding, "", &nullentrylen); - - if (nullentry != NULL) - { -#if defined _LIBC || HAVE_ICONV - const char *charsetstr; - - charsetstr = strstr (nullentry, "charset="); - if (charsetstr != NULL) - { - size_t len; - char *charset; - const char *outcharset; - - charsetstr += strlen ("charset="); - len = strcspn (charsetstr, " \t\n"); - - charset = (char *) alloca (len + 1); -# if defined _LIBC || HAVE_MEMPCPY - *((char *) mempcpy (charset, charsetstr, len)) = '\0'; -# else - memcpy (charset, charsetstr, len); - charset[len] = '\0'; -# endif - - /* The output charset should normally be determined by the - locale. But sometimes the locale is not used or not correctly - set up, so we provide a possibility for the user to override - this. Moreover, the value specified through - bind_textdomain_codeset overrides both. */ - if (domainbinding != NULL && domainbinding->codeset != NULL) - outcharset = domainbinding->codeset; - else - { - outcharset = getenv ("OUTPUT_CHARSET"); - if (outcharset == NULL || outcharset[0] == '\0') - { -# ifdef _LIBC - outcharset = _NL_CURRENT (LC_CTYPE, CODESET); -# else -# if HAVE_ICONV - extern const char *locale_charset PARAMS ((void)); - outcharset = locale_charset (); -# endif -# endif - } - } - -# ifdef _LIBC - /* We always want to use transliteration. */ - outcharset = norm_add_slashes (outcharset, "TRANSLIT"); - charset = norm_add_slashes (charset, NULL); - if (__gconv_open (outcharset, charset, &domain->conv, - GCONV_AVOID_NOCONV) - != __GCONV_OK) - domain->conv = (__gconv_t) -1; -# else -# if HAVE_ICONV - /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5, - we want to use transliteration. */ -# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \ - || _LIBICONV_VERSION >= 0x0105 - if (strchr (outcharset, '/') == NULL) - { - char *tmp; - - len = strlen (outcharset); - tmp = (char *) alloca (len + 10 + 1); - memcpy (tmp, outcharset, len); - memcpy (tmp + len, "//TRANSLIT", 10 + 1); - outcharset = tmp; - - domain->conv = iconv_open (outcharset, charset); - - freea (outcharset); - } - else -# endif - domain->conv = iconv_open (outcharset, charset); -# endif -# endif - - freea (charset); - } -#endif /* _LIBC || HAVE_ICONV */ - } - - return nullentry; -} - -/* Frees the codeset dependent parts of an opened message catalog. */ -void -internal_function -_nl_free_domain_conv (domain) - struct loaded_domain *domain; -{ - if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1) - free (domain->conv_tab); - -#ifdef _LIBC - if (domain->conv != (__gconv_t) -1) - __gconv_close (domain->conv); -#else -# if HAVE_ICONV - if (domain->conv != (iconv_t) -1) - iconv_close (domain->conv); -# endif -#endif -} - -/* Load the message catalogs specified by FILENAME. If it is no valid - message catalog do nothing. */ -void -internal_function -_nl_load_domain (domain_file, domainbinding) - struct loaded_l10nfile *domain_file; - struct binding *domainbinding; -{ - int fd; - size_t size; -#ifdef _LIBC - struct stat64 st; -#else - struct stat st; -#endif - struct mo_file_header *data = (struct mo_file_header *) -1; - int use_mmap = 0; - struct loaded_domain *domain; - int revision; - const char *nullentry; - - domain_file->decided = 1; - domain_file->data = NULL; - - /* Note that it would be useless to store domainbinding in domain_file - because domainbinding might be == NULL now but != NULL later (after - a call to bind_textdomain_codeset). */ - - /* If the record does not represent a valid locale the FILENAME - might be NULL. This can happen when according to the given - specification the locale file name is different for XPG and CEN - syntax. */ - if (domain_file->filename == NULL) - return; - - /* Try to open the addressed file. */ - fd = open (domain_file->filename, O_RDONLY | O_BINARY); - if (fd == -1) - return; - - /* We must know about the size of the file. */ - if ( -#ifdef _LIBC - __builtin_expect (fstat64 (fd, &st) != 0, 0) -#else - __builtin_expect (fstat (fd, &st) != 0, 0) -#endif - || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0) - || __builtin_expect (size < sizeof (struct mo_file_header), 0)) - { - /* Something went wrong. */ - close (fd); - return; - } - -#ifdef HAVE_MMAP - /* Now we are ready to load the file. If mmap() is available we try - this first. If not available or it failed we try to load it. */ - data = (struct mo_file_header *) mmap (NULL, size, PROT_READ, - MAP_PRIVATE, fd, 0); - - if (__builtin_expect (data != (struct mo_file_header *) -1, 1)) - { - /* mmap() call was successful. */ - close (fd); - use_mmap = 1; - } -#endif - - /* If the data is not yet available (i.e. mmap'ed) we try to load - it manually. */ - if (data == (struct mo_file_header *) -1) - { - size_t to_read; - char *read_ptr; - - data = (struct mo_file_header *) malloc (size); - if (data == NULL) - return; - - to_read = size; - read_ptr = (char *) data; - do - { - long int nb = (long int) read (fd, read_ptr, to_read); - if (nb <= 0) - { -#ifdef EINTR - if (nb == -1 && errno == EINTR) - continue; -#endif - close (fd); - return; - } - read_ptr += nb; - to_read -= nb; - } - while (to_read > 0); - - close (fd); - } - - /* Using the magic number we can test whether it really is a message - catalog file. */ - if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED, - 0)) - { - /* The magic number is wrong: not a message catalog file. */ -#ifdef HAVE_MMAP - if (use_mmap) - munmap ((caddr_t) data, size); - else -#endif - free (data); - return; - } - - domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain)); - if (domain == NULL) - return; - domain_file->data = domain; - - domain->data = (char *) data; - domain->use_mmap = use_mmap; - domain->mmap_size = size; - domain->must_swap = data->magic != _MAGIC; - domain->malloced = NULL; - - /* Fill in the information about the available tables. */ - revision = W (domain->must_swap, data->revision); - /* We support only the major revision 0. */ - switch (revision >> 16) - { - case 0: - domain->nstrings = W (domain->must_swap, data->nstrings); - domain->orig_tab = (const struct string_desc *) - ((char *) data + W (domain->must_swap, data->orig_tab_offset)); - domain->trans_tab = (const struct string_desc *) - ((char *) data + W (domain->must_swap, data->trans_tab_offset)); - domain->hash_size = W (domain->must_swap, data->hash_tab_size); - domain->hash_tab = - (domain->hash_size > 2 - ? (const nls_uint32 *) - ((char *) data + W (domain->must_swap, data->hash_tab_offset)) - : NULL); - domain->must_swap_hash_tab = domain->must_swap; - - /* Now dispatch on the minor revision. */ - switch (revision & 0xffff) - { - case 0: - domain->n_sysdep_strings = 0; - domain->orig_sysdep_tab = NULL; - domain->trans_sysdep_tab = NULL; - break; - case 1: - default: - { - nls_uint32 n_sysdep_strings; - - if (domain->hash_tab == NULL) - /* This is invalid. These minor revisions need a hash table. */ - goto invalid; - - n_sysdep_strings = - W (domain->must_swap, data->n_sysdep_strings); - if (n_sysdep_strings > 0) - { - nls_uint32 n_sysdep_segments; - const struct sysdep_segment *sysdep_segments; - const char **sysdep_segment_values; - const nls_uint32 *orig_sysdep_tab; - const nls_uint32 *trans_sysdep_tab; - size_t memneed; - char *mem; - struct sysdep_string_desc *inmem_orig_sysdep_tab; - struct sysdep_string_desc *inmem_trans_sysdep_tab; - nls_uint32 *inmem_hash_tab; - unsigned int i; - - /* Get the values of the system dependent segments. */ - n_sysdep_segments = - W (domain->must_swap, data->n_sysdep_segments); - sysdep_segments = (const struct sysdep_segment *) - ((char *) data - + W (domain->must_swap, data->sysdep_segments_offset)); - sysdep_segment_values = - alloca (n_sysdep_segments * sizeof (const char *)); - for (i = 0; i < n_sysdep_segments; i++) - { - const char *name = - (char *) data - + W (domain->must_swap, sysdep_segments[i].offset); - nls_uint32 namelen = - W (domain->must_swap, sysdep_segments[i].length); - - if (!(namelen > 0 && name[namelen - 1] == '\0')) - { - freea (sysdep_segment_values); - goto invalid; - } - - sysdep_segment_values[i] = get_sysdep_segment_value (name); - } - - orig_sysdep_tab = (const nls_uint32 *) - ((char *) data - + W (domain->must_swap, data->orig_sysdep_tab_offset)); - trans_sysdep_tab = (const nls_uint32 *) - ((char *) data - + W (domain->must_swap, data->trans_sysdep_tab_offset)); - - /* Compute the amount of additional memory needed for the - system dependent strings and the augmented hash table. */ - memneed = 2 * n_sysdep_strings - * sizeof (struct sysdep_string_desc) - + domain->hash_size * sizeof (nls_uint32); - for (i = 0; i < 2 * n_sysdep_strings; i++) - { - const struct sysdep_string *sysdep_string = - (const struct sysdep_string *) - ((char *) data - + W (domain->must_swap, - i < n_sysdep_strings - ? orig_sysdep_tab[i] - : trans_sysdep_tab[i - n_sysdep_strings])); - size_t need = 0; - const struct segment_pair *p = sysdep_string->segments; - - if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END) - for (p = sysdep_string->segments;; p++) - { - nls_uint32 sysdepref; - - need += W (domain->must_swap, p->segsize); - - sysdepref = W (domain->must_swap, p->sysdepref); - if (sysdepref == SEGMENTS_END) - break; - - if (sysdepref >= n_sysdep_segments) - { - /* Invalid. */ - freea (sysdep_segment_values); - goto invalid; - } - - need += strlen (sysdep_segment_values[sysdepref]); - } - - memneed += need; - } - - /* Allocate additional memory. */ - mem = (char *) malloc (memneed); - if (mem == NULL) - goto invalid; - - domain->malloced = mem; - inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem; - mem += n_sysdep_strings * sizeof (struct sysdep_string_desc); - inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem; - mem += n_sysdep_strings * sizeof (struct sysdep_string_desc); - inmem_hash_tab = (nls_uint32 *) mem; - mem += domain->hash_size * sizeof (nls_uint32); - - /* Compute the system dependent strings. */ - for (i = 0; i < 2 * n_sysdep_strings; i++) - { - const struct sysdep_string *sysdep_string = - (const struct sysdep_string *) - ((char *) data - + W (domain->must_swap, - i < n_sysdep_strings - ? orig_sysdep_tab[i] - : trans_sysdep_tab[i - n_sysdep_strings])); - const char *static_segments = - (char *) data - + W (domain->must_swap, sysdep_string->offset); - const struct segment_pair *p = sysdep_string->segments; - - /* Concatenate the segments, and fill - inmem_orig_sysdep_tab[i] (for i < n_sysdep_strings) and - inmem_trans_sysdep_tab[i-n_sysdep_strings] (for - i >= n_sysdep_strings). */ - - if (W (domain->must_swap, p->sysdepref) == SEGMENTS_END) - { - /* Only one static segment. */ - inmem_orig_sysdep_tab[i].length = - W (domain->must_swap, p->segsize); - inmem_orig_sysdep_tab[i].pointer = static_segments; - } - else - { - inmem_orig_sysdep_tab[i].pointer = mem; - - for (p = sysdep_string->segments;; p++) - { - nls_uint32 segsize = - W (domain->must_swap, p->segsize); - nls_uint32 sysdepref = - W (domain->must_swap, p->sysdepref); - size_t n; - - if (segsize > 0) - { - memcpy (mem, static_segments, segsize); - mem += segsize; - static_segments += segsize; - } - - if (sysdepref == SEGMENTS_END) - break; - - n = strlen (sysdep_segment_values[sysdepref]); - memcpy (mem, sysdep_segment_values[sysdepref], n); - mem += n; - } - - inmem_orig_sysdep_tab[i].length = - mem - inmem_orig_sysdep_tab[i].pointer; - } - } - - /* Compute the augmented hash table. */ - for (i = 0; i < domain->hash_size; i++) - inmem_hash_tab[i] = - W (domain->must_swap_hash_tab, domain->hash_tab[i]); - for (i = 0; i < n_sysdep_strings; i++) - { - const char *msgid = inmem_orig_sysdep_tab[i].pointer; - nls_uint32 hash_val = hash_string (msgid); - nls_uint32 idx = hash_val % domain->hash_size; - nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); - - for (;;) - { - if (inmem_hash_tab[idx] == 0) - { - /* Hash table entry is empty. Use it. */ - inmem_hash_tab[idx] = 1 + domain->nstrings + i; - break; - } - - if (idx >= domain->hash_size - incr) - idx -= domain->hash_size - incr; - else - idx += incr; - } - } - - freea (sysdep_segment_values); - - domain->n_sysdep_strings = n_sysdep_strings; - domain->orig_sysdep_tab = inmem_orig_sysdep_tab; - domain->trans_sysdep_tab = inmem_trans_sysdep_tab; - - domain->hash_tab = inmem_hash_tab; - domain->must_swap_hash_tab = 0; - } - else - { - domain->n_sysdep_strings = 0; - domain->orig_sysdep_tab = NULL; - domain->trans_sysdep_tab = NULL; - } - } - break; - } - break; - default: - /* This is an invalid revision. */ - invalid: - /* This is an invalid .mo file. */ - if (domain->malloced) - free (domain->malloced); -#ifdef HAVE_MMAP - if (use_mmap) - munmap ((caddr_t) data, size); - else -#endif - free (data); - free (domain); - domain_file->data = NULL; - return; - } - - /* Now initialize the character set converter from the character set - the file is encoded with (found in the header entry) to the domain's - specified character set or the locale's character set. */ - nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding); - - /* Also look for a plural specification. */ - EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals); -} - - -#ifdef _LIBC -void -internal_function -_nl_unload_domain (domain) - struct loaded_domain *domain; -{ - if (domain->plural != &__gettext_germanic_plural) - __gettext_free_exp (domain->plural); - - _nl_free_domain_conv (domain); - - if (domain->malloced) - free (domain->malloced); - -# ifdef _POSIX_MAPPED_FILES - if (domain->use_mmap) - munmap ((caddr_t) domain->data, domain->mmap_size); - else -# endif /* _POSIX_MAPPED_FILES */ - free ((void *) domain->data); - - free (domain); -} -#endif diff --git a/intl/localcharset.c b/intl/localcharset.c deleted file mode 100644 index d04d05368..000000000 --- a/intl/localcharset.c +++ /dev/null @@ -1,398 +0,0 @@ -/* Determine a canonical name for the current locale's character encoding. - - Copyright (C) 2000-2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Written by Bruno Haible <bruno@clisp.org>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -/* Specification. */ -#include "localcharset.h" - -#if HAVE_STDDEF_H -# include <stddef.h> -#endif - -#include <stdio.h> -#if HAVE_STRING_H -# include <string.h> -#else -# include <strings.h> -#endif -#if HAVE_STDLIB_H -# include <stdlib.h> -#endif - -#if defined _WIN32 || defined __WIN32__ -# undef WIN32 /* avoid warning on mingw32 */ -# define WIN32 -#endif - -#if defined __EMX__ -/* Assume EMX program runs on OS/2, even if compiled under DOS. */ -# define OS2 -#endif - -#if !defined WIN32 -# if HAVE_LANGINFO_CODESET -# include <langinfo.h> -# else -# if HAVE_SETLOCALE -# include <locale.h> -# endif -# endif -#elif defined WIN32 -# define WIN32_LEAN_AND_MEAN -# include <windows.h> -#endif -#if defined OS2 -# define INCL_DOS -# include <os2.h> -#endif - -#if ENABLE_RELOCATABLE -# include "relocatable.h" -#else -# define relocate(pathname) (pathname) -#endif - -#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS */ -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -#endif - -#ifndef DIRECTORY_SEPARATOR -# define DIRECTORY_SEPARATOR '/' -#endif - -#ifndef ISSLASH -# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) -#endif - -#ifdef HAVE_GETC_UNLOCKED -# undef getc -# define getc getc_unlocked -#endif - -/* The following static variable is declared 'volatile' to avoid a - possible multithread problem in the function get_charset_aliases. If we - are running in a threaded environment, and if two threads initialize - 'charset_aliases' simultaneously, both will produce the same value, - and everything will be ok if the two assignments to 'charset_aliases' - are atomic. But I don't know what will happen if the two assignments mix. */ -#if __STDC__ != 1 -# define volatile /* empty */ -#endif -/* Pointer to the contents of the charset.alias file, if it has already been - read, else NULL. Its format is: - ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0' */ -static const char * volatile charset_aliases; - -/* Return a pointer to the contents of the charset.alias file. */ -static const char * -get_charset_aliases () -{ - const char *cp; - - cp = charset_aliases; - if (cp == NULL) - { -#if !(defined VMS || defined WIN32) - FILE *fp; - const char *dir = relocate (LIBDIR); - const char *base = "charset.alias"; - char *file_name; - - /* Concatenate dir and base into freshly allocated file_name. */ - { - size_t dir_len = strlen (dir); - size_t base_len = strlen (base); - int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); - file_name = (char *) malloc (dir_len + add_slash + base_len + 1); - if (file_name != NULL) - { - memcpy (file_name, dir, dir_len); - if (add_slash) - file_name[dir_len] = DIRECTORY_SEPARATOR; - memcpy (file_name + dir_len + add_slash, base, base_len + 1); - } - } - - if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL) - /* Out of memory or file not found, treat it as empty. */ - cp = ""; - else - { - /* Parse the file's contents. */ - int c; - char buf1[50+1]; - char buf2[50+1]; - char *res_ptr = NULL; - size_t res_size = 0; - size_t l1, l2; - - for (;;) - { - c = getc (fp); - if (c == EOF) - break; - if (c == '\n' || c == ' ' || c == '\t') - continue; - if (c == '#') - { - /* Skip comment, to end of line. */ - do - c = getc (fp); - while (!(c == EOF || c == '\n')); - if (c == EOF) - break; - continue; - } - ungetc (c, fp); - if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) - break; - l1 = strlen (buf1); - l2 = strlen (buf2); - if (res_size == 0) - { - res_size = l1 + 1 + l2 + 1; - res_ptr = (char *) malloc (res_size + 1); - } - else - { - res_size += l1 + 1 + l2 + 1; - res_ptr = (char *) realloc (res_ptr, res_size + 1); - } - if (res_ptr == NULL) - { - /* Out of memory. */ - res_size = 0; - break; - } - strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); - strcpy (res_ptr + res_size - (l2 + 1), buf2); - } - fclose (fp); - if (res_size == 0) - cp = ""; - else - { - *(res_ptr + res_size) = '\0'; - cp = res_ptr; - } - } - - if (file_name != NULL) - free (file_name); - -#else - -# if defined VMS - /* To avoid the troubles of an extra file charset.alias_vms in the - sources of many GNU packages, simply inline the aliases here. */ - /* The list of encodings is taken from the OpenVMS 7.3-1 documentation - "Compaq C Run-Time Library Reference Manual for OpenVMS systems" - section 10.7 "Handling Different Character Sets". */ - cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" - "ISO8859-2" "\0" "ISO-8859-2" "\0" - "ISO8859-5" "\0" "ISO-8859-5" "\0" - "ISO8859-7" "\0" "ISO-8859-7" "\0" - "ISO8859-8" "\0" "ISO-8859-8" "\0" - "ISO8859-9" "\0" "ISO-8859-9" "\0" - /* Japanese */ - "eucJP" "\0" "EUC-JP" "\0" - "SJIS" "\0" "SHIFT_JIS" "\0" - "DECKANJI" "\0" "DEC-KANJI" "\0" - "SDECKANJI" "\0" "EUC-JP" "\0" - /* Chinese */ - "eucTW" "\0" "EUC-TW" "\0" - "DECHANYU" "\0" "DEC-HANYU" "\0" - "DECHANZI" "\0" "GB2312" "\0" - /* Korean */ - "DECKOREAN" "\0" "EUC-KR" "\0"; -# endif - -# if defined WIN32 - /* To avoid the troubles of installing a separate file in the same - directory as the DLL and of retrieving the DLL's directory at - runtime, simply inline the aliases here. */ - - cp = "CP936" "\0" "GBK" "\0" - "CP1361" "\0" "JOHAB" "\0" - "CP20127" "\0" "ASCII" "\0" - "CP20866" "\0" "KOI8-R" "\0" - "CP21866" "\0" "KOI8-RU" "\0" - "CP28591" "\0" "ISO-8859-1" "\0" - "CP28592" "\0" "ISO-8859-2" "\0" - "CP28593" "\0" "ISO-8859-3" "\0" - "CP28594" "\0" "ISO-8859-4" "\0" - "CP28595" "\0" "ISO-8859-5" "\0" - "CP28596" "\0" "ISO-8859-6" "\0" - "CP28597" "\0" "ISO-8859-7" "\0" - "CP28598" "\0" "ISO-8859-8" "\0" - "CP28599" "\0" "ISO-8859-9" "\0" - "CP28605" "\0" "ISO-8859-15" "\0"; -# endif -#endif - - charset_aliases = cp; - } - - return cp; -} - -/* Determine the current locale's character encoding, and canonicalize it - into one of the canonical names listed in config.charset. - The result must not be freed; it is statically allocated. - If the canonical name cannot be determined, the result is a non-canonical - name. */ - -#ifdef STATIC -STATIC -#endif -const char * -locale_charset () -{ - const char *codeset; - const char *aliases; - -#if !(defined WIN32 || defined OS2) - -# if HAVE_LANGINFO_CODESET - - /* Most systems support nl_langinfo (CODESET) nowadays. */ - codeset = nl_langinfo (CODESET); - -# else - - /* On old systems which lack it, use setlocale or getenv. */ - const char *locale = NULL; - - /* But most old systems don't have a complete set of locales. Some - (like SunOS 4 or DJGPP) have only the C locale. Therefore we don't - use setlocale here; it would return "C" when it doesn't support the - locale name the user has set. */ -# if HAVE_SETLOCALE && 0 - locale = setlocale (LC_CTYPE, NULL); -# endif - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_ALL"); - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_CTYPE"); - if (locale == NULL || locale[0] == '\0') - locale = getenv ("LANG"); - } - } - - /* On some old systems, one used to set locale = "iso8859_1". On others, - you set it to "language_COUNTRY.charset". In any case, we resolve it - through the charset.alias file. */ - codeset = locale; - -# endif - -#elif defined WIN32 - - static char buf[2 + 10 + 1]; - - /* Woe32 has a function returning the locale's codepage as a number. */ - sprintf (buf, "CP%u", GetACP ()); - codeset = buf; - -#elif defined OS2 - - const char *locale; - static char buf[2 + 10 + 1]; - ULONG cp[3]; - ULONG cplen; - - /* Allow user to override the codeset, as set in the operating system, - with standard language environment variables. */ - locale = getenv ("LC_ALL"); - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_CTYPE"); - if (locale == NULL || locale[0] == '\0') - locale = getenv ("LANG"); - } - if (locale != NULL && locale[0] != '\0') - { - /* If the locale name contains an encoding after the dot, return it. */ - const char *dot = strchr (locale, '.'); - - if (dot != NULL) - { - const char *modifier; - - dot++; - /* Look for the possible @... trailer and remove it, if any. */ - modifier = strchr (dot, '@'); - if (modifier == NULL) - return dot; - if (modifier - dot < sizeof (buf)) - { - memcpy (buf, dot, modifier - dot); - buf [modifier - dot] = '\0'; - return buf; - } - } - - /* Resolve through the charset.alias file. */ - codeset = locale; - } - else - { - /* OS/2 has a function returning the locale's codepage as a number. */ - if (DosQueryCp (sizeof (cp), cp, &cplen)) - codeset = ""; - else - { - sprintf (buf, "CP%u", cp[0]); - codeset = buf; - } - } - -#endif - - if (codeset == NULL) - /* The canonical name cannot be determined. */ - codeset = ""; - - /* Resolve alias. */ - for (aliases = get_charset_aliases (); - *aliases != '\0'; - aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) - if (strcmp (codeset, aliases) == 0 - || (aliases[0] == '*' && aliases[1] == '\0')) - { - codeset = aliases + strlen (aliases) + 1; - break; - } - - /* Don't return an empty string. GNU libc and GNU libiconv interpret - the empty string as denoting "the locale's character encoding", - thus GNU libiconv would call this function a second time. */ - if (codeset[0] == '\0') - codeset = "ASCII"; - - return codeset; -} diff --git a/intl/localcharset.h b/intl/localcharset.h deleted file mode 100644 index 3b137e73c..000000000 --- a/intl/localcharset.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Determine a canonical name for the current locale's character encoding. - Copyright (C) 2000-2003 Free Software Foundation, Inc. - This file is part of the GNU CHARSET Library. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _LOCALCHARSET_H -#define _LOCALCHARSET_H - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Determine the current locale's character encoding, and canonicalize it - into one of the canonical names listed in config.charset. - The result must not be freed; it is statically allocated. - If the canonical name cannot be determined, the result is a non-canonical - name. */ -extern const char * locale_charset (void); - - -#ifdef __cplusplus -} -#endif - - -#endif /* _LOCALCHARSET_H */ diff --git a/intl/locale.alias b/intl/locale.alias deleted file mode 100644 index bd7b9b31e..000000000 --- a/intl/locale.alias +++ /dev/null @@ -1,78 +0,0 @@ -# Locale name alias data base. -# Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Library General Public License as published -# by the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA. - -# The format of this file is the same as for the corresponding file of -# the X Window System, which normally can be found in -# /usr/lib/X11/locale/locale.alias -# A single line contains two fields: an alias and a substitution value. -# All entries are case independent. - -# Note: This file is far from being complete. If you have a value for -# your own site which you think might be useful for others too, share -# it with the rest of us. Send it using the `glibcbug' script to -# bugs@gnu.org. - -# Packages using this file: - -bokmal no_NO.ISO-8859-1 -bokmål no_NO.ISO-8859-1 -catalan ca_ES.ISO-8859-1 -croatian hr_HR.ISO-8859-2 -czech cs_CZ.ISO-8859-2 -danish da_DK.ISO-8859-1 -dansk da_DK.ISO-8859-1 -deutsch de_DE.ISO-8859-1 -dutch nl_NL.ISO-8859-1 -eesti et_EE.ISO-8859-1 -estonian et_EE.ISO-8859-1 -finnish fi_FI.ISO-8859-1 -français fr_FR.ISO-8859-1 -french fr_FR.ISO-8859-1 -galego gl_ES.ISO-8859-1 -galician gl_ES.ISO-8859-1 -german de_DE.ISO-8859-1 -greek el_GR.ISO-8859-7 -hebrew he_IL.ISO-8859-8 -hrvatski hr_HR.ISO-8859-2 -hungarian hu_HU.ISO-8859-2 -icelandic is_IS.ISO-8859-1 -italian it_IT.ISO-8859-1 -japanese ja_JP.eucJP -japanese.euc ja_JP.eucJP -ja_JP ja_JP.eucJP -ja_JP.ujis ja_JP.eucJP -japanese.sjis ja_JP.SJIS -korean ko_KR.eucKR -korean.euc ko_KR.eucKR -ko_KR ko_KR.eucKR -lithuanian lt_LT.ISO-8859-13 -nb_NO no_NO.ISO-8859-1 -nb_NO.ISO-8859-1 no_NO.ISO-8859-1 -norwegian no_NO.ISO-8859-1 -nynorsk nn_NO.ISO-8859-1 -polish pl_PL.ISO-8859-2 -portuguese pt_PT.ISO-8859-1 -romanian ro_RO.ISO-8859-2 -russian ru_RU.ISO-8859-5 -slovak sk_SK.ISO-8859-2 -slovene sl_SI.ISO-8859-2 -slovenian sl_SI.ISO-8859-2 -spanish es_ES.ISO-8859-1 -swedish sv_SE.ISO-8859-1 -thai th_TH.TIS-620 -turkish tr_TR.ISO-8859-9 diff --git a/intl/localealias.c b/intl/localealias.c deleted file mode 100644 index 7c4ce58f2..000000000 --- a/intl/localealias.c +++ /dev/null @@ -1,419 +0,0 @@ -/* Handle aliases for locale names. - Copyright (C) 1995-1999, 2000-2001, 2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Tell glibc's <string.h> to provide a prototype for mempcpy(). - This must come before <config.h> because <config.h> may include - <features.h>, and once <features.h> has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <ctype.h> -#include <stdio.h> -#if defined _LIBC || defined HAVE___FSETLOCKING -# include <stdio_ext.h> -#endif -#include <sys/types.h> - -#ifdef __GNUC__ -# undef alloca -# define alloca __builtin_alloca -# define HAVE_ALLOCA 1 -#else -# ifdef _MSC_VER -# include <malloc.h> -# define alloca _alloca -# else -# if defined HAVE_ALLOCA_H || defined _LIBC -# include <alloca.h> -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca -char *alloca (); -# endif -# endif -# endif -# endif -#endif - -#include <stdlib.h> -#include <string.h> - -#include "gettextP.h" - -#if ENABLE_RELOCATABLE -# include "relocatable.h" -#else -# define relocate(pathname) (pathname) -#endif - -/* @@ end of prolog @@ */ - -#ifdef _LIBC -/* Rename the non ANSI C functions. This is required by the standard - because some ANSI C functions will require linking with this object - file and the name space must not be polluted. */ -# define strcasecmp __strcasecmp - -# ifndef mempcpy -# define mempcpy __mempcpy -# endif -# define HAVE_MEMPCPY 1 -# define HAVE___FSETLOCKING 1 - -/* We need locking here since we can be called from different places. */ -# include <bits/libc-lock.h> - -__libc_lock_define_initialized (static, lock); -#endif - -#ifndef internal_function -# define internal_function -#endif - -/* Some optimizations for glibc. */ -#ifdef _LIBC -# define FEOF(fp) feof_unlocked (fp) -# define FGETS(buf, n, fp) fgets_unlocked (buf, n, fp) -#else -# define FEOF(fp) feof (fp) -# define FGETS(buf, n, fp) fgets (buf, n, fp) -#endif - -/* For those losing systems which don't have `alloca' we have to add - some additional code emulating it. */ -#ifdef HAVE_ALLOCA -# define freea(p) /* nothing */ -#else -# define alloca(n) malloc (n) -# define freea(p) free (p) -#endif - -#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED -# undef fgets -# define fgets(buf, len, s) fgets_unlocked (buf, len, s) -#endif -#if defined _LIBC_REENTRANT || defined HAVE_FEOF_UNLOCKED -# undef feof -# define feof(s) feof_unlocked (s) -#endif - - -struct alias_map -{ - const char *alias; - const char *value; -}; - - -#ifndef _LIBC -# define libc_freeres_ptr(decl) decl -#endif - -libc_freeres_ptr (static char *string_space); -static size_t string_space_act; -static size_t string_space_max; -libc_freeres_ptr (static struct alias_map *map); -static size_t nmap; -static size_t maxmap; - - -/* Prototypes for local functions. */ -static size_t read_alias_file PARAMS ((const char *fname, int fname_len)) - internal_function; -static int extend_alias_table PARAMS ((void)); -static int alias_compare PARAMS ((const struct alias_map *map1, - const struct alias_map *map2)); - - -const char * -_nl_expand_alias (name) - const char *name; -{ - static const char *locale_alias_path; - struct alias_map *retval; - const char *result = NULL; - size_t added; - -#ifdef _LIBC - __libc_lock_lock (lock); -#endif - - if (locale_alias_path == NULL) - locale_alias_path = LOCALE_ALIAS_PATH; - - do - { - struct alias_map item; - - item.alias = name; - - if (nmap > 0) - retval = (struct alias_map *) bsearch (&item, map, nmap, - sizeof (struct alias_map), - (int (*) PARAMS ((const void *, - const void *)) - ) alias_compare); - else - retval = NULL; - - /* We really found an alias. Return the value. */ - if (retval != NULL) - { - result = retval->value; - break; - } - - /* Perhaps we can find another alias file. */ - added = 0; - while (added == 0 && locale_alias_path[0] != '\0') - { - const char *start; - - while (locale_alias_path[0] == PATH_SEPARATOR) - ++locale_alias_path; - start = locale_alias_path; - - while (locale_alias_path[0] != '\0' - && locale_alias_path[0] != PATH_SEPARATOR) - ++locale_alias_path; - - if (start < locale_alias_path) - added = read_alias_file (start, locale_alias_path - start); - } - } - while (added != 0); - -#ifdef _LIBC - __libc_lock_unlock (lock); -#endif - - return result; -} - - -static size_t -internal_function -read_alias_file (fname, fname_len) - const char *fname; - int fname_len; -{ - FILE *fp; - char *full_fname; - size_t added; - static const char aliasfile[] = "/locale.alias"; - - full_fname = (char *) alloca (fname_len + sizeof aliasfile); -#ifdef HAVE_MEMPCPY - mempcpy (mempcpy (full_fname, fname, fname_len), - aliasfile, sizeof aliasfile); -#else - memcpy (full_fname, fname, fname_len); - memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile); -#endif - - fp = fopen (relocate (full_fname), "r"); - freea (full_fname); - if (fp == NULL) - return 0; - -#ifdef HAVE___FSETLOCKING - /* No threads present. */ - __fsetlocking (fp, FSETLOCKING_BYCALLER); -#endif - - added = 0; - while (!FEOF (fp)) - { - /* It is a reasonable approach to use a fix buffer here because - a) we are only interested in the first two fields - b) these fields must be usable as file names and so must not - be that long - We avoid a multi-kilobyte buffer here since this would use up - stack space which we might not have if the program ran out of - memory. */ - char buf[400]; - char *alias; - char *value; - char *cp; - - if (FGETS (buf, sizeof buf, fp) == NULL) - /* EOF reached. */ - break; - - cp = buf; - /* Ignore leading white space. */ - while (isspace ((unsigned char) cp[0])) - ++cp; - - /* A leading '#' signals a comment line. */ - if (cp[0] != '\0' && cp[0] != '#') - { - alias = cp++; - while (cp[0] != '\0' && !isspace ((unsigned char) cp[0])) - ++cp; - /* Terminate alias name. */ - if (cp[0] != '\0') - *cp++ = '\0'; - - /* Now look for the beginning of the value. */ - while (isspace ((unsigned char) cp[0])) - ++cp; - - if (cp[0] != '\0') - { - size_t alias_len; - size_t value_len; - - value = cp++; - while (cp[0] != '\0' && !isspace ((unsigned char) cp[0])) - ++cp; - /* Terminate value. */ - if (cp[0] == '\n') - { - /* This has to be done to make the following test - for the end of line possible. We are looking for - the terminating '\n' which do not overwrite here. */ - *cp++ = '\0'; - *cp = '\n'; - } - else if (cp[0] != '\0') - *cp++ = '\0'; - - if (nmap >= maxmap) - if (__builtin_expect (extend_alias_table (), 0)) - return added; - - alias_len = strlen (alias) + 1; - value_len = strlen (value) + 1; - - if (string_space_act + alias_len + value_len > string_space_max) - { - /* Increase size of memory pool. */ - size_t new_size = (string_space_max - + (alias_len + value_len > 1024 - ? alias_len + value_len : 1024)); - char *new_pool = (char *) realloc (string_space, new_size); - if (new_pool == NULL) - return added; - - if (__builtin_expect (string_space != new_pool, 0)) - { - size_t i; - - for (i = 0; i < nmap; i++) - { - map[i].alias += new_pool - string_space; - map[i].value += new_pool - string_space; - } - } - - string_space = new_pool; - string_space_max = new_size; - } - - map[nmap].alias = memcpy (&string_space[string_space_act], - alias, alias_len); - string_space_act += alias_len; - - map[nmap].value = memcpy (&string_space[string_space_act], - value, value_len); - string_space_act += value_len; - - ++nmap; - ++added; - } - } - - /* Possibly not the whole line fits into the buffer. Ignore - the rest of the line. */ - while (strchr (buf, '\n') == NULL) - if (FGETS (buf, sizeof buf, fp) == NULL) - /* Make sure the inner loop will be left. The outer loop - will exit at the `feof' test. */ - break; - } - - /* Should we test for ferror()? I think we have to silently ignore - errors. --drepper */ - fclose (fp); - - if (added > 0) - qsort (map, nmap, sizeof (struct alias_map), - (int (*) PARAMS ((const void *, const void *))) alias_compare); - - return added; -} - - -static int -extend_alias_table () -{ - size_t new_size; - struct alias_map *new_map; - - new_size = maxmap == 0 ? 100 : 2 * maxmap; - new_map = (struct alias_map *) realloc (map, (new_size - * sizeof (struct alias_map))); - if (new_map == NULL) - /* Simply don't extend: we don't have any more core. */ - return -1; - - map = new_map; - maxmap = new_size; - return 0; -} - - -static int -alias_compare (map1, map2) - const struct alias_map *map1; - const struct alias_map *map2; -{ -#if defined _LIBC || defined HAVE_STRCASECMP - return strcasecmp (map1->alias, map2->alias); -#else - const unsigned char *p1 = (const unsigned char *) map1->alias; - const unsigned char *p2 = (const unsigned char *) map2->alias; - unsigned char c1, c2; - - if (p1 == p2) - return 0; - - do - { - /* I know this seems to be odd but the tolower() function in - some systems libc cannot handle nonalpha characters. */ - c1 = isupper (*p1) ? tolower (*p1) : *p1; - c2 = isupper (*p2) ? tolower (*p2) : *p2; - if (c1 == '\0') - break; - ++p1; - ++p2; - } - while (c1 == c2); - - return c1 - c2; -#endif -} diff --git a/intl/localename.c b/intl/localename.c deleted file mode 100644 index faacecd50..000000000 --- a/intl/localename.c +++ /dev/null @@ -1,772 +0,0 @@ -/* Determine the current selected locale. - Copyright (C) 1995-1999, 2000-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Written by Ulrich Drepper <drepper@gnu.org>, 1995. */ -/* Win32 code written by Tor Lillqvist <tml@iki.fi>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdlib.h> -#include <locale.h> - -#if defined _WIN32 || defined __WIN32__ -# undef WIN32 /* avoid warning on mingw32 */ -# define WIN32 -#endif - -#ifdef WIN32 -# define WIN32_LEAN_AND_MEAN -# include <windows.h> -/* Mingw headers don't have latest language and sublanguage codes. */ -# ifndef LANG_AFRIKAANS -# define LANG_AFRIKAANS 0x36 -# endif -# ifndef LANG_ALBANIAN -# define LANG_ALBANIAN 0x1c -# endif -# ifndef LANG_ARABIC -# define LANG_ARABIC 0x01 -# endif -# ifndef LANG_ARMENIAN -# define LANG_ARMENIAN 0x2b -# endif -# ifndef LANG_ASSAMESE -# define LANG_ASSAMESE 0x4d -# endif -# ifndef LANG_AZERI -# define LANG_AZERI 0x2c -# endif -# ifndef LANG_BASQUE -# define LANG_BASQUE 0x2d -# endif -# ifndef LANG_BELARUSIAN -# define LANG_BELARUSIAN 0x23 -# endif -# ifndef LANG_BENGALI -# define LANG_BENGALI 0x45 -# endif -# ifndef LANG_CATALAN -# define LANG_CATALAN 0x03 -# endif -# ifndef LANG_DIVEHI -# define LANG_DIVEHI 0x65 -# endif -# ifndef LANG_ESTONIAN -# define LANG_ESTONIAN 0x25 -# endif -# ifndef LANG_FAEROESE -# define LANG_FAEROESE 0x38 -# endif -# ifndef LANG_FARSI -# define LANG_FARSI 0x29 -# endif -# ifndef LANG_GALICIAN -# define LANG_GALICIAN 0x56 -# endif -# ifndef LANG_GEORGIAN -# define LANG_GEORGIAN 0x37 -# endif -# ifndef LANG_GUJARATI -# define LANG_GUJARATI 0x47 -# endif -# ifndef LANG_HEBREW -# define LANG_HEBREW 0x0d -# endif -# ifndef LANG_HINDI -# define LANG_HINDI 0x39 -# endif -# ifndef LANG_INDONESIAN -# define LANG_INDONESIAN 0x21 -# endif -# ifndef LANG_KANNADA -# define LANG_KANNADA 0x4b -# endif -# ifndef LANG_KASHMIRI -# define LANG_KASHMIRI 0x60 -# endif -# ifndef LANG_KAZAK -# define LANG_KAZAK 0x3f -# endif -# ifndef LANG_KONKANI -# define LANG_KONKANI 0x57 -# endif -# ifndef LANG_KYRGYZ -# define LANG_KYRGYZ 0x40 -# endif -# ifndef LANG_LATVIAN -# define LANG_LATVIAN 0x26 -# endif -# ifndef LANG_LITHUANIAN -# define LANG_LITHUANIAN 0x27 -# endif -# ifndef LANG_MACEDONIAN -# define LANG_MACEDONIAN 0x2f -# endif -# ifndef LANG_MALAY -# define LANG_MALAY 0x3e -# endif -# ifndef LANG_MALAYALAM -# define LANG_MALAYALAM 0x4c -# endif -# ifndef LANG_MANIPURI -# define LANG_MANIPURI 0x58 -# endif -# ifndef LANG_MARATHI -# define LANG_MARATHI 0x4e -# endif -# ifndef LANG_MONGOLIAN -# define LANG_MONGOLIAN 0x50 -# endif -# ifndef LANG_NEPALI -# define LANG_NEPALI 0x61 -# endif -# ifndef LANG_ORIYA -# define LANG_ORIYA 0x48 -# endif -# ifndef LANG_PUNJABI -# define LANG_PUNJABI 0x46 -# endif -# ifndef LANG_SANSKRIT -# define LANG_SANSKRIT 0x4f -# endif -# ifndef LANG_SERBIAN -# define LANG_SERBIAN 0x1a -# endif -# ifndef LANG_SINDHI -# define LANG_SINDHI 0x59 -# endif -# ifndef LANG_SLOVAK -# define LANG_SLOVAK 0x1b -# endif -# ifndef LANG_SORBIAN -# define LANG_SORBIAN 0x2e -# endif -# ifndef LANG_SWAHILI -# define LANG_SWAHILI 0x41 -# endif -# ifndef LANG_SYRIAC -# define LANG_SYRIAC 0x5a -# endif -# ifndef LANG_TAMIL -# define LANG_TAMIL 0x49 -# endif -# ifndef LANG_TATAR -# define LANG_TATAR 0x44 -# endif -# ifndef LANG_TELUGU -# define LANG_TELUGU 0x4a -# endif -# ifndef LANG_THAI -# define LANG_THAI 0x1e -# endif -# ifndef LANG_UKRAINIAN -# define LANG_UKRAINIAN 0x22 -# endif -# ifndef LANG_URDU -# define LANG_URDU 0x20 -# endif -# ifndef LANG_UZBEK -# define LANG_UZBEK 0x43 -# endif -# ifndef LANG_VIETNAMESE -# define LANG_VIETNAMESE 0x2a -# endif -# ifndef SUBLANG_ARABIC_SAUDI_ARABIA -# define SUBLANG_ARABIC_SAUDI_ARABIA 0x01 -# endif -# ifndef SUBLANG_ARABIC_IRAQ -# define SUBLANG_ARABIC_IRAQ 0x02 -# endif -# ifndef SUBLANG_ARABIC_EGYPT -# define SUBLANG_ARABIC_EGYPT 0x03 -# endif -# ifndef SUBLANG_ARABIC_LIBYA -# define SUBLANG_ARABIC_LIBYA 0x04 -# endif -# ifndef SUBLANG_ARABIC_ALGERIA -# define SUBLANG_ARABIC_ALGERIA 0x05 -# endif -# ifndef SUBLANG_ARABIC_MOROCCO -# define SUBLANG_ARABIC_MOROCCO 0x06 -# endif -# ifndef SUBLANG_ARABIC_TUNISIA -# define SUBLANG_ARABIC_TUNISIA 0x07 -# endif -# ifndef SUBLANG_ARABIC_OMAN -# define SUBLANG_ARABIC_OMAN 0x08 -# endif -# ifndef SUBLANG_ARABIC_YEMEN -# define SUBLANG_ARABIC_YEMEN 0x09 -# endif -# ifndef SUBLANG_ARABIC_SYRIA -# define SUBLANG_ARABIC_SYRIA 0x0a -# endif -# ifndef SUBLANG_ARABIC_JORDAN -# define SUBLANG_ARABIC_JORDAN 0x0b -# endif -# ifndef SUBLANG_ARABIC_LEBANON -# define SUBLANG_ARABIC_LEBANON 0x0c -# endif -# ifndef SUBLANG_ARABIC_KUWAIT -# define SUBLANG_ARABIC_KUWAIT 0x0d -# endif -# ifndef SUBLANG_ARABIC_UAE -# define SUBLANG_ARABIC_UAE 0x0e -# endif -# ifndef SUBLANG_ARABIC_BAHRAIN -# define SUBLANG_ARABIC_BAHRAIN 0x0f -# endif -# ifndef SUBLANG_ARABIC_QATAR -# define SUBLANG_ARABIC_QATAR 0x10 -# endif -# ifndef SUBLANG_AZERI_LATIN -# define SUBLANG_AZERI_LATIN 0x01 -# endif -# ifndef SUBLANG_AZERI_CYRILLIC -# define SUBLANG_AZERI_CYRILLIC 0x02 -# endif -# ifndef SUBLANG_CHINESE_MACAU -# define SUBLANG_CHINESE_MACAU 0x05 -# endif -# ifndef SUBLANG_ENGLISH_SOUTH_AFRICA -# define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07 -# endif -# ifndef SUBLANG_ENGLISH_JAMAICA -# define SUBLANG_ENGLISH_JAMAICA 0x08 -# endif -# ifndef SUBLANG_ENGLISH_CARIBBEAN -# define SUBLANG_ENGLISH_CARIBBEAN 0x09 -# endif -# ifndef SUBLANG_ENGLISH_BELIZE -# define SUBLANG_ENGLISH_BELIZE 0x0a -# endif -# ifndef SUBLANG_ENGLISH_TRINIDAD -# define SUBLANG_ENGLISH_TRINIDAD 0x0b -# endif -# ifndef SUBLANG_ENGLISH_ZIMBABWE -# define SUBLANG_ENGLISH_ZIMBABWE 0x0c -# endif -# ifndef SUBLANG_ENGLISH_PHILIPPINES -# define SUBLANG_ENGLISH_PHILIPPINES 0x0d -# endif -# ifndef SUBLANG_FRENCH_LUXEMBOURG -# define SUBLANG_FRENCH_LUXEMBOURG 0x05 -# endif -# ifndef SUBLANG_FRENCH_MONACO -# define SUBLANG_FRENCH_MONACO 0x06 -# endif -# ifndef SUBLANG_GERMAN_LUXEMBOURG -# define SUBLANG_GERMAN_LUXEMBOURG 0x04 -# endif -# ifndef SUBLANG_GERMAN_LIECHTENSTEIN -# define SUBLANG_GERMAN_LIECHTENSTEIN 0x05 -# endif -# ifndef SUBLANG_KASHMIRI_INDIA -# define SUBLANG_KASHMIRI_INDIA 0x02 -# endif -# ifndef SUBLANG_MALAY_MALAYSIA -# define SUBLANG_MALAY_MALAYSIA 0x01 -# endif -# ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM -# define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02 -# endif -# ifndef SUBLANG_NEPALI_INDIA -# define SUBLANG_NEPALI_INDIA 0x02 -# endif -# ifndef SUBLANG_SERBIAN_LATIN -# define SUBLANG_SERBIAN_LATIN 0x02 -# endif -# ifndef SUBLANG_SERBIAN_CYRILLIC -# define SUBLANG_SERBIAN_CYRILLIC 0x03 -# endif -# ifndef SUBLANG_SPANISH_GUATEMALA -# define SUBLANG_SPANISH_GUATEMALA 0x04 -# endif -# ifndef SUBLANG_SPANISH_COSTA_RICA -# define SUBLANG_SPANISH_COSTA_RICA 0x05 -# endif -# ifndef SUBLANG_SPANISH_PANAMA -# define SUBLANG_SPANISH_PANAMA 0x06 -# endif -# ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC -# define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07 -# endif -# ifndef SUBLANG_SPANISH_VENEZUELA -# define SUBLANG_SPANISH_VENEZUELA 0x08 -# endif -# ifndef SUBLANG_SPANISH_COLOMBIA -# define SUBLANG_SPANISH_COLOMBIA 0x09 -# endif -# ifndef SUBLANG_SPANISH_PERU -# define SUBLANG_SPANISH_PERU 0x0a -# endif -# ifndef SUBLANG_SPANISH_ARGENTINA -# define SUBLANG_SPANISH_ARGENTINA 0x0b -# endif -# ifndef SUBLANG_SPANISH_ECUADOR -# define SUBLANG_SPANISH_ECUADOR 0x0c -# endif -# ifndef SUBLANG_SPANISH_CHILE -# define SUBLANG_SPANISH_CHILE 0x0d -# endif -# ifndef SUBLANG_SPANISH_URUGUAY -# define SUBLANG_SPANISH_URUGUAY 0x0e -# endif -# ifndef SUBLANG_SPANISH_PARAGUAY -# define SUBLANG_SPANISH_PARAGUAY 0x0f -# endif -# ifndef SUBLANG_SPANISH_BOLIVIA -# define SUBLANG_SPANISH_BOLIVIA 0x10 -# endif -# ifndef SUBLANG_SPANISH_EL_SALVADOR -# define SUBLANG_SPANISH_EL_SALVADOR 0x11 -# endif -# ifndef SUBLANG_SPANISH_HONDURAS -# define SUBLANG_SPANISH_HONDURAS 0x12 -# endif -# ifndef SUBLANG_SPANISH_NICARAGUA -# define SUBLANG_SPANISH_NICARAGUA 0x13 -# endif -# ifndef SUBLANG_SPANISH_PUERTO_RICO -# define SUBLANG_SPANISH_PUERTO_RICO 0x14 -# endif -# ifndef SUBLANG_SWEDISH_FINLAND -# define SUBLANG_SWEDISH_FINLAND 0x02 -# endif -# ifndef SUBLANG_URDU_PAKISTAN -# define SUBLANG_URDU_PAKISTAN 0x01 -# endif -# ifndef SUBLANG_URDU_INDIA -# define SUBLANG_URDU_INDIA 0x02 -# endif -# ifndef SUBLANG_UZBEK_LATIN -# define SUBLANG_UZBEK_LATIN 0x01 -# endif -# ifndef SUBLANG_UZBEK_CYRILLIC -# define SUBLANG_UZBEK_CYRILLIC 0x02 -# endif -#endif - -/* XPG3 defines the result of 'setlocale (category, NULL)' as: - "Directs 'setlocale()' to query 'category' and return the current - setting of 'local'." - However it does not specify the exact format. Neither do SUSV2 and - ISO C 99. So we can use this feature only on selected systems (e.g. - those using GNU C Library). */ -#if defined _LIBC || (defined __GNU_LIBRARY__ && __GNU_LIBRARY__ >= 2) -# define HAVE_LOCALE_NULL -#endif - -/* Determine the current locale's name, and canonicalize it into XPG syntax - language[_territory[.codeset]][@modifier] - The codeset part in the result is not reliable; the locale_charset() - should be used for codeset information instead. - The result must not be freed; it is statically allocated. */ - -const char * -_nl_locale_name (category, categoryname) - int category; - const char *categoryname; -{ - const char *retval; - -#ifndef WIN32 - - /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'. - On some systems this can be done by the 'setlocale' function itself. */ -# if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL - retval = setlocale (category, NULL); -# else - /* Setting of LC_ALL overwrites all other. */ - retval = getenv ("LC_ALL"); - if (retval == NULL || retval[0] == '\0') - { - /* Next comes the name of the desired category. */ - retval = getenv (categoryname); - if (retval == NULL || retval[0] == '\0') - { - /* Last possibility is the LANG environment variable. */ - retval = getenv ("LANG"); - if (retval == NULL || retval[0] == '\0') - /* We use C as the default domain. POSIX says this is - implementation defined. */ - retval = "C"; - } - } -# endif - - return retval; - -#else /* WIN32 */ - - /* Return an XPG style locale name language[_territory][@modifier]. - Don't even bother determining the codeset; it's not useful in this - context, because message catalogs are not specific to a single - codeset. */ - - LCID lcid; - LANGID langid; - int primary, sub; - - /* Let the user override the system settings through environment - variables, as on POSIX systems. */ - retval = getenv ("LC_ALL"); - if (retval != NULL && retval[0] != '\0') - return retval; - retval = getenv (categoryname); - if (retval != NULL && retval[0] != '\0') - return retval; - retval = getenv ("LANG"); - if (retval != NULL && retval[0] != '\0') - return retval; - - /* Use native Win32 API locale ID. */ - lcid = GetThreadLocale (); - - /* Strip off the sorting rules, keep only the language part. */ - langid = LANGIDFROMLCID (lcid); - - /* Split into language and territory part. */ - primary = PRIMARYLANGID (langid); - sub = SUBLANGID (langid); - - /* Dispatch on language. - See also http://www.unicode.org/unicode/onlinedat/languages.html . - For details about languages, see http://www.ethnologue.com/ . */ - switch (primary) - { - case LANG_AFRIKAANS: return "af_ZA"; - case LANG_ALBANIAN: return "sq_AL"; - case 0x5e: /* AMHARIC */ return "am_ET"; - case LANG_ARABIC: - switch (sub) - { - case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA"; - case SUBLANG_ARABIC_IRAQ: return "ar_IQ"; - case SUBLANG_ARABIC_EGYPT: return "ar_EG"; - case SUBLANG_ARABIC_LIBYA: return "ar_LY"; - case SUBLANG_ARABIC_ALGERIA: return "ar_DZ"; - case SUBLANG_ARABIC_MOROCCO: return "ar_MA"; - case SUBLANG_ARABIC_TUNISIA: return "ar_TN"; - case SUBLANG_ARABIC_OMAN: return "ar_OM"; - case SUBLANG_ARABIC_YEMEN: return "ar_YE"; - case SUBLANG_ARABIC_SYRIA: return "ar_SY"; - case SUBLANG_ARABIC_JORDAN: return "ar_JO"; - case SUBLANG_ARABIC_LEBANON: return "ar_LB"; - case SUBLANG_ARABIC_KUWAIT: return "ar_KW"; - case SUBLANG_ARABIC_UAE: return "ar_AE"; - case SUBLANG_ARABIC_BAHRAIN: return "ar_BH"; - case SUBLANG_ARABIC_QATAR: return "ar_QA"; - } - return "ar"; - case LANG_ARMENIAN: return "hy_AM"; - case LANG_ASSAMESE: return "as_IN"; - case LANG_AZERI: - switch (sub) - { - /* FIXME: Adjust this when Azerbaijani locales appear on Unix. */ - case SUBLANG_AZERI_LATIN: return "az_AZ@latin"; - case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic"; - } - return "az"; - case LANG_BASQUE: - return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR". */ - case LANG_BELARUSIAN: return "be_BY"; - case LANG_BENGALI: return "bn_IN"; - case LANG_BULGARIAN: return "bg_BG"; - case 0x55: /* BURMESE */ return "my_MM"; - case 0x53: /* CAMBODIAN */ return "km_KH"; - case LANG_CATALAN: return "ca_ES"; - case 0x5c: /* CHEROKEE */ return "chr_US"; - case LANG_CHINESE: - switch (sub) - { - case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW"; - case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN"; - case SUBLANG_CHINESE_HONGKONG: return "zh_HK"; - case SUBLANG_CHINESE_SINGAPORE: return "zh_SG"; - case SUBLANG_CHINESE_MACAU: return "zh_MO"; - } - return "zh"; - case LANG_CROATIAN: /* LANG_CROATIAN == LANG_SERBIAN - * What used to be called Serbo-Croatian - * should really now be two separate - * languages because of political reasons. - * (Says tml, who knows nothing about Serbian - * or Croatian.) - * (I can feel those flames coming already.) - */ - switch (sub) - { - case SUBLANG_DEFAULT: return "hr_HR"; - case SUBLANG_SERBIAN_LATIN: return "sr_YU"; - case SUBLANG_SERBIAN_CYRILLIC: return "sr_YU@cyrillic"; - } - return "hr"; - case LANG_CZECH: return "cs_CZ"; - case LANG_DANISH: return "da_DK"; - case LANG_DIVEHI: return "div_MV"; - case LANG_DUTCH: - switch (sub) - { - case SUBLANG_DUTCH: return "nl_NL"; - case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE"; - } - return "nl"; - case 0x66: /* EDO */ return "bin_NG"; - case LANG_ENGLISH: - switch (sub) - { - /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought - * English was the language spoken in England. - * Oh well. - */ - case SUBLANG_ENGLISH_US: return "en_US"; - case SUBLANG_ENGLISH_UK: return "en_GB"; - case SUBLANG_ENGLISH_AUS: return "en_AU"; - case SUBLANG_ENGLISH_CAN: return "en_CA"; - case SUBLANG_ENGLISH_NZ: return "en_NZ"; - case SUBLANG_ENGLISH_EIRE: return "en_IE"; - case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA"; - case SUBLANG_ENGLISH_JAMAICA: return "en_JM"; - case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */ - case SUBLANG_ENGLISH_BELIZE: return "en_BZ"; - case SUBLANG_ENGLISH_TRINIDAD: return "en_TT"; - case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW"; - case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH"; - } - return "en"; - case LANG_ESTONIAN: return "et_EE"; - case LANG_FAEROESE: return "fo_FO"; - case LANG_FARSI: return "fa_IR"; - case LANG_FINNISH: return "fi_FI"; - case LANG_FRENCH: - switch (sub) - { - case SUBLANG_FRENCH: return "fr_FR"; - case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE"; - case SUBLANG_FRENCH_CANADIAN: return "fr_CA"; - case SUBLANG_FRENCH_SWISS: return "fr_CH"; - case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU"; - case SUBLANG_FRENCH_MONACO: return "fr_MC"; - } - return "fr"; - case 0x62: /* FRISIAN */ return "fy_NL"; - case 0x67: /* FULFULDE */ return "ful_NG"; - case 0x3c: /* GAELIC */ - switch (sub) - { - case 0x01: /* SCOTTISH */ return "gd_GB"; - case 0x02: /* IRISH */ return "ga_IE"; - } - return "C"; - case LANG_GALICIAN: return "gl_ES"; - case LANG_GEORGIAN: return "ka_GE"; - case LANG_GERMAN: - switch (sub) - { - case SUBLANG_GERMAN: return "de_DE"; - case SUBLANG_GERMAN_SWISS: return "de_CH"; - case SUBLANG_GERMAN_AUSTRIAN: return "de_AT"; - case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU"; - case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI"; - } - return "de"; - case LANG_GREEK: return "el_GR"; - case 0x74: /* GUARANI */ return "gn_PY"; - case LANG_GUJARATI: return "gu_IN"; - case 0x68: /* HAUSA */ return "ha_NG"; - case 0x75: /* HAWAIIAN */ - /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers) - or Hawaii Creole English ("cpe_US", 600000 speakers)? */ - return "cpe_US"; - case LANG_HEBREW: return "he_IL"; - case LANG_HINDI: return "hi_IN"; - case LANG_HUNGARIAN: return "hu_HU"; - case 0x69: /* IBIBIO */ return "nic_NG"; - case LANG_ICELANDIC: return "is_IS"; - case 0x70: /* IGBO */ return "ibo_NG"; - case LANG_INDONESIAN: return "id_ID"; - case 0x5d: /* INUKTITUT */ return "iu_CA"; - case LANG_ITALIAN: - switch (sub) - { - case SUBLANG_ITALIAN: return "it_IT"; - case SUBLANG_ITALIAN_SWISS: return "it_CH"; - } - return "it"; - case LANG_JAPANESE: return "ja_JP"; - case LANG_KANNADA: return "kn_IN"; - case 0x71: /* KANURI */ return "kau_NG"; - case LANG_KASHMIRI: - switch (sub) - { - case SUBLANG_DEFAULT: return "ks_PK"; - case SUBLANG_KASHMIRI_INDIA: return "ks_IN"; - } - return "ks"; - case LANG_KAZAK: return "kk_KZ"; - case LANG_KONKANI: - /* FIXME: Adjust this when such locales appear on Unix. */ - return "kok_IN"; - case LANG_KOREAN: return "ko_KR"; - case LANG_KYRGYZ: return "ky_KG"; - case 0x54: /* LAO */ return "lo_LA"; - case 0x76: /* LATIN */ return "la_VA"; - case LANG_LATVIAN: return "lv_LV"; - case LANG_LITHUANIAN: return "lt_LT"; - case LANG_MACEDONIAN: return "mk_MK"; - case LANG_MALAY: - switch (sub) - { - case SUBLANG_MALAY_MALAYSIA: return "ms_MY"; - case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN"; - } - return "ms"; - case LANG_MALAYALAM: return "ml_IN"; - case 0x3a: /* MALTESE */ return "mt_MT"; - case LANG_MANIPURI: - /* FIXME: Adjust this when such locales appear on Unix. */ - return "mni_IN"; - case LANG_MARATHI: return "mr_IN"; - case LANG_MONGOLIAN: - return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN". */ - case LANG_NEPALI: - switch (sub) - { - case SUBLANG_DEFAULT: return "ne_NP"; - case SUBLANG_NEPALI_INDIA: return "ne_IN"; - } - return "ne"; - case LANG_NORWEGIAN: - switch (sub) - { - case SUBLANG_NORWEGIAN_BOKMAL: return "no_NO"; - case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO"; - } - return "no"; - case LANG_ORIYA: return "or_IN"; - case 0x72: /* OROMO */ return "om_ET"; - case 0x79: /* PAPIAMENTU */ return "pap_AN"; - case 0x63: /* PASHTO */ - return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF". */ - case LANG_POLISH: return "pl_PL"; - case LANG_PORTUGUESE: - switch (sub) - { - case SUBLANG_PORTUGUESE: return "pt_PT"; - /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT. - Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */ - case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR"; - } - return "pt"; - case LANG_PUNJABI: return "pa_IN"; - case 0x17: /* RHAETO-ROMANCE */ return "rm_CH"; - case LANG_ROMANIAN: return "ro_RO"; - case LANG_RUSSIAN: - return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA". */ - case 0x3b: /* SAMI */ return "se_NO"; - case LANG_SANSKRIT: return "sa_IN"; - case LANG_SINDHI: return "sd"; - case 0x5b: /* SINHALESE */ return "si_LK"; - case LANG_SLOVAK: return "sk_SK"; - case LANG_SLOVENIAN: return "sl_SI"; - case 0x77: /* SOMALI */ return "so_SO"; - case LANG_SORBIAN: - /* FIXME: Adjust this when such locales appear on Unix. */ - return "wen_DE"; - case LANG_SPANISH: - switch (sub) - { - case SUBLANG_SPANISH: return "es_ES"; - case SUBLANG_SPANISH_MEXICAN: return "es_MX"; - case SUBLANG_SPANISH_MODERN: - return "es_ES@modern"; /* not seen on Unix */ - case SUBLANG_SPANISH_GUATEMALA: return "es_GT"; - case SUBLANG_SPANISH_COSTA_RICA: return "es_CR"; - case SUBLANG_SPANISH_PANAMA: return "es_PA"; - case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO"; - case SUBLANG_SPANISH_VENEZUELA: return "es_VE"; - case SUBLANG_SPANISH_COLOMBIA: return "es_CO"; - case SUBLANG_SPANISH_PERU: return "es_PE"; - case SUBLANG_SPANISH_ARGENTINA: return "es_AR"; - case SUBLANG_SPANISH_ECUADOR: return "es_EC"; - case SUBLANG_SPANISH_CHILE: return "es_CL"; - case SUBLANG_SPANISH_URUGUAY: return "es_UY"; - case SUBLANG_SPANISH_PARAGUAY: return "es_PY"; - case SUBLANG_SPANISH_BOLIVIA: return "es_BO"; - case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV"; - case SUBLANG_SPANISH_HONDURAS: return "es_HN"; - case SUBLANG_SPANISH_NICARAGUA: return "es_NI"; - case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR"; - } - return "es"; - case 0x30: /* SUTU */ return "bnt_TZ"; - case LANG_SWAHILI: return "sw_KE"; - case LANG_SWEDISH: - switch (sub) - { - case SUBLANG_DEFAULT: return "sv_SE"; - case SUBLANG_SWEDISH_FINLAND: return "sv_FI"; - } - return "sv"; - case LANG_SYRIAC: return "syr_TR"; /* An extinct language. */ - case 0x64: /* TAGALOG */ return "tl_PH"; - case 0x28: /* TAJIK */ return "tg_TJ"; - case 0x5f: /* TAMAZIGHT */ return "ber_MA"; - case LANG_TAMIL: - return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG". */ - case LANG_TATAR: return "tt_RU"; - case LANG_TELUGU: return "te_IN"; - case LANG_THAI: return "th_TH"; - case 0x51: /* TIBETAN */ return "bo_CN"; - case 0x73: /* TIGRINYA */ return "ti_ET"; - case 0x31: /* TSONGA */ return "ts_ZA"; - case LANG_TURKISH: return "tr_TR"; - case 0x42: /* TURKMEN */ return "tk_TM"; - case LANG_UKRAINIAN: return "uk_UA"; - case LANG_URDU: - switch (sub) - { - case SUBLANG_URDU_PAKISTAN: return "ur_PK"; - case SUBLANG_URDU_INDIA: return "ur_IN"; - } - return "ur"; - case LANG_UZBEK: - switch (sub) - { - /* FIXME: Adjust this when Uzbek locales appear on Unix. */ - case SUBLANG_UZBEK_LATIN: return "uz_UZ@latin"; - case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic"; - } - return "uz"; - case 0x33: /* VENDA */ return "ven_ZA"; - case LANG_VIETNAMESE: return "vi_VN"; - case 0x52: /* WELSH */ return "cy_GB"; - case 0x34: /* XHOSA */ return "xh_ZA"; - case 0x78: /* YI */ return "sit_CN"; - case 0x3d: /* YIDDISH */ return "yi_IL"; - case 0x6a: /* YORUBA */ return "yo_NG"; - case 0x35: /* ZULU */ return "zu_ZA"; - default: return "C"; - } - -#endif -} diff --git a/intl/log.c b/intl/log.c deleted file mode 100644 index 9c84791b9..000000000 --- a/intl/log.c +++ /dev/null @@ -1,104 +0,0 @@ -/* Log file output. - Copyright (C) 2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Written by Bruno Haible <bruno@clisp.org>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -/* Print an ASCII string with quotes and escape sequences where needed. */ -static void -print_escaped (stream, str) - FILE *stream; - const char *str; -{ - putc ('"', stream); - for (; *str != '\0'; str++) - if (*str == '\n') - { - fputs ("\\n\"", stream); - if (str[1] == '\0') - return; - fputs ("\n\"", stream); - } - else - { - if (*str == '"' || *str == '\\') - putc ('\\', stream); - putc (*str, stream); - } - putc ('"', stream); -} - -/* Add to the log file an entry denoting a failed translation. */ -void -_nl_log_untranslated (logfilename, domainname, msgid1, msgid2, plural) - const char *logfilename; - const char *domainname; - const char *msgid1; - const char *msgid2; - int plural; -{ - static char *last_logfilename = NULL; - static FILE *last_logfile = NULL; - FILE *logfile; - - /* Can we reuse the last opened logfile? */ - if (last_logfilename == NULL || strcmp (logfilename, last_logfilename) != 0) - { - /* Close the last used logfile. */ - if (last_logfilename != NULL) - { - if (last_logfile != NULL) - { - fclose (last_logfile); - last_logfile = NULL; - } - free (last_logfilename); - last_logfilename = NULL; - } - /* Open the logfile. */ - last_logfilename = (char *) malloc (strlen (logfilename) + 1); - if (last_logfilename == NULL) - return; - strcpy (last_logfilename, logfilename); - last_logfile = fopen (logfilename, "a"); - if (last_logfile == NULL) - return; - } - logfile = last_logfile; - - fprintf (logfile, "domain "); - print_escaped (logfile, domainname); - fprintf (logfile, "\nmsgid "); - print_escaped (logfile, msgid1); - if (plural) - { - fprintf (logfile, "\nmsgid_plural "); - print_escaped (logfile, msgid2); - fprintf (logfile, "\nmsgstr[0] \"\"\n"); - } - else - fprintf (logfile, "\nmsgstr \"\"\n"); - putc ('\n', logfile); -} diff --git a/intl/ngettext.c b/intl/ngettext.c deleted file mode 100644 index 17a27f4aa..000000000 --- a/intl/ngettext.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Implementation of ngettext(3) function. - Copyright (C) 1995, 1997, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#ifdef _LIBC -# define __need_NULL -# include <stddef.h> -#else -# include <stdlib.h> /* Just for NULL. */ -#endif - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -#include <locale.h> - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define NGETTEXT __ngettext -# define DCNGETTEXT __dcngettext -#else -# define NGETTEXT libintl_ngettext -# define DCNGETTEXT libintl_dcngettext -#endif - -/* Look up MSGID in the current default message catalog for the current - LC_MESSAGES locale. If not found, returns MSGID itself (the default - text). */ -char * -NGETTEXT (msgid1, msgid2, n) - const char *msgid1; - const char *msgid2; - unsigned long int n; -{ - return DCNGETTEXT (NULL, msgid1, msgid2, n, LC_MESSAGES); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__ngettext, ngettext); -#endif diff --git a/intl/os2compat.c b/intl/os2compat.c deleted file mode 100644 index c8dc33e7c..000000000 --- a/intl/os2compat.c +++ /dev/null @@ -1,98 +0,0 @@ -/* OS/2 compatibility functions. - Copyright (C) 2001-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#define OS2_AWARE -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <sys/param.h> - -/* A version of getenv() that works from DLLs */ -extern unsigned long DosScanEnv (const unsigned char *pszName, unsigned char **ppszValue); - -char * -_nl_getenv (const char *name) -{ - unsigned char *value; - if (DosScanEnv (name, &value)) - return NULL; - else - return value; -} - -/* A fixed size buffer. */ -char libintl_nl_default_dirname[MAXPATHLEN+1]; - -char *_nlos2_libdir = NULL; -char *_nlos2_localealiaspath = NULL; -char *_nlos2_localedir = NULL; - -static __attribute__((constructor)) void -nlos2_initialize () -{ - char *root = getenv ("UNIXROOT"); - char *gnulocaledir = getenv ("GNULOCALEDIR"); - - _nlos2_libdir = gnulocaledir; - if (!_nlos2_libdir) - { - if (root) - { - size_t sl = strlen (root); - _nlos2_libdir = (char *) malloc (sl + strlen (LIBDIR) + 1); - memcpy (_nlos2_libdir, root, sl); - memcpy (_nlos2_libdir + sl, LIBDIR, strlen (LIBDIR) + 1); - } - else - _nlos2_libdir = LIBDIR; - } - - _nlos2_localealiaspath = gnulocaledir; - if (!_nlos2_localealiaspath) - { - if (root) - { - size_t sl = strlen (root); - _nlos2_localealiaspath = (char *) malloc (sl + strlen (LOCALE_ALIAS_PATH) + 1); - memcpy (_nlos2_localealiaspath, root, sl); - memcpy (_nlos2_localealiaspath + sl, LOCALE_ALIAS_PATH, strlen (LOCALE_ALIAS_PATH) + 1); - } - else - _nlos2_localealiaspath = LOCALE_ALIAS_PATH; - } - - _nlos2_localedir = gnulocaledir; - if (!_nlos2_localedir) - { - if (root) - { - size_t sl = strlen (root); - _nlos2_localedir = (char *) malloc (sl + strlen (LOCALEDIR) + 1); - memcpy (_nlos2_localedir, root, sl); - memcpy (_nlos2_localedir + sl, LOCALEDIR, strlen (LOCALEDIR) + 1); - } - else - _nlos2_localedir = LOCALEDIR; - } - - if (strlen (_nlos2_localedir) <= MAXPATHLEN) - strcpy (libintl_nl_default_dirname, _nlos2_localedir); -} diff --git a/intl/os2compat.h b/intl/os2compat.h deleted file mode 100644 index 4f74e8c03..000000000 --- a/intl/os2compat.h +++ /dev/null @@ -1,46 +0,0 @@ -/* OS/2 compatibility defines. - This file is intended to be included from config.h - Copyright (C) 2001-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* When included from os2compat.h we need all the original definitions */ -#ifndef OS2_AWARE - -#undef LIBDIR -#define LIBDIR _nlos2_libdir -extern char *_nlos2_libdir; - -#undef LOCALEDIR -#define LOCALEDIR _nlos2_localedir -extern char *_nlos2_localedir; - -#undef LOCALE_ALIAS_PATH -#define LOCALE_ALIAS_PATH _nlos2_localealiaspath -extern char *_nlos2_localealiaspath; - -#endif - -#undef HAVE_STRCASECMP -#define HAVE_STRCASECMP 1 -#define strcasecmp stricmp -#define strncasecmp strnicmp - -/* We have our own getenv() which works even if library is compiled as DLL */ -#define getenv _nl_getenv - -/* Older versions of gettext used -1 as the value of LC_MESSAGES */ -#define LC_MESSAGES_COMPAT (-1) diff --git a/intl/osdep.c b/intl/osdep.c deleted file mode 100644 index b37259838..000000000 --- a/intl/osdep.c +++ /dev/null @@ -1,24 +0,0 @@ -/* OS dependent parts of libintl. - Copyright (C) 2001-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#if defined __EMX__ -# include "os2compat.c" -#else -/* Avoid AIX compiler warning. */ -typedef int dummy; -#endif diff --git a/intl/plural-exp.c b/intl/plural-exp.c deleted file mode 100644 index c937c011a..000000000 --- a/intl/plural-exp.c +++ /dev/null @@ -1,156 +0,0 @@ -/* Expression parsing for plural form selection. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. - Written by Ulrich Drepper <drepper@cygnus.com>, 2000. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <ctype.h> -#include <stdlib.h> -#include <string.h> - -#include "plural-exp.h" - -#if (defined __GNUC__ && !defined __APPLE_CC__) \ - || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) - -/* These structs are the constant expression for the germanic plural - form determination. It represents the expression "n != 1". */ -static const struct expression plvar = -{ - .nargs = 0, - .operation = var, -}; -static const struct expression plone = -{ - .nargs = 0, - .operation = num, - .val = - { - .num = 1 - } -}; -struct expression GERMANIC_PLURAL = -{ - .nargs = 2, - .operation = not_equal, - .val = - { - .args = - { - [0] = (struct expression *) &plvar, - [1] = (struct expression *) &plone - } - } -}; - -# define INIT_GERMANIC_PLURAL() - -#else - -/* For compilers without support for ISO C 99 struct/union initializers: - Initialization at run-time. */ - -static struct expression plvar; -static struct expression plone; -struct expression GERMANIC_PLURAL; - -static void -init_germanic_plural () -{ - if (plone.val.num == 0) - { - plvar.nargs = 0; - plvar.operation = var; - - plone.nargs = 0; - plone.operation = num; - plone.val.num = 1; - - GERMANIC_PLURAL.nargs = 2; - GERMANIC_PLURAL.operation = not_equal; - GERMANIC_PLURAL.val.args[0] = &plvar; - GERMANIC_PLURAL.val.args[1] = &plone; - } -} - -# define INIT_GERMANIC_PLURAL() init_germanic_plural () - -#endif - -void -internal_function -EXTRACT_PLURAL_EXPRESSION (nullentry, pluralp, npluralsp) - const char *nullentry; - struct expression **pluralp; - unsigned long int *npluralsp; -{ - if (nullentry != NULL) - { - const char *plural; - const char *nplurals; - - plural = strstr (nullentry, "plural="); - nplurals = strstr (nullentry, "nplurals="); - if (plural == NULL || nplurals == NULL) - goto no_plural; - else - { - char *endp; - unsigned long int n; - struct parse_args args; - - /* First get the number. */ - nplurals += 9; - while (*nplurals != '\0' && isspace ((unsigned char) *nplurals)) - ++nplurals; - if (!(*nplurals >= '0' && *nplurals <= '9')) - goto no_plural; -#if defined HAVE_STRTOUL || defined _LIBC - n = strtoul (nplurals, &endp, 10); -#else - for (endp = nplurals, n = 0; *endp >= '0' && *endp <= '9'; endp++) - n = n * 10 + (*endp - '0'); -#endif - if (nplurals == endp) - goto no_plural; - *npluralsp = n; - - /* Due to the restrictions bison imposes onto the interface of the - scanner function we have to put the input string and the result - passed up from the parser into the same structure which address - is passed down to the parser. */ - plural += 7; - args.cp = plural; - if (PLURAL_PARSE (&args) != 0) - goto no_plural; - *pluralp = args.res; - } - } - else - { - /* By default we are using the Germanic form: singular form only - for `one', the plural form otherwise. Yes, this is also what - English is using since English is a Germanic language. */ - no_plural: - INIT_GERMANIC_PLURAL (); - *pluralp = &GERMANIC_PLURAL; - *npluralsp = 2; - } -} diff --git a/intl/plural-exp.h b/intl/plural-exp.h deleted file mode 100644 index 9e5d16583..000000000 --- a/intl/plural-exp.h +++ /dev/null @@ -1,126 +0,0 @@ -/* Expression parsing and evaluation for plural form selection. - Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. - Written by Ulrich Drepper <drepper@cygnus.com>, 2000. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _PLURAL_EXP_H -#define _PLURAL_EXP_H - -#ifndef PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - -#ifndef internal_function -# define internal_function -#endif - -#ifndef attribute_hidden -# define attribute_hidden -#endif - - -/* This is the representation of the expressions to determine the - plural form. */ -struct expression -{ - int nargs; /* Number of arguments. */ - enum operator - { - /* Without arguments: */ - var, /* The variable "n". */ - num, /* Decimal number. */ - /* Unary operators: */ - lnot, /* Logical NOT. */ - /* Binary operators: */ - mult, /* Multiplication. */ - divide, /* Division. */ - module, /* Modulo operation. */ - plus, /* Addition. */ - minus, /* Subtraction. */ - less_than, /* Comparison. */ - greater_than, /* Comparison. */ - less_or_equal, /* Comparison. */ - greater_or_equal, /* Comparison. */ - equal, /* Comparison for equality. */ - not_equal, /* Comparison for inequality. */ - land, /* Logical AND. */ - lor, /* Logical OR. */ - /* Ternary operators: */ - qmop /* Question mark operator. */ - } operation; - union - { - unsigned long int num; /* Number value for `num'. */ - struct expression *args[3]; /* Up to three arguments. */ - } val; -}; - -/* This is the data structure to pass information to the parser and get - the result in a thread-safe way. */ -struct parse_args -{ - const char *cp; - struct expression *res; -}; - - -/* Names for the libintl functions are a problem. This source code is used - 1. in the GNU C Library library, - 2. in the GNU libintl library, - 3. in the GNU gettext tools. - The function names in each situation must be different, to allow for - binary incompatible changes in 'struct expression'. Furthermore, - 1. in the GNU C Library library, the names have a __ prefix, - 2.+3. in the GNU libintl library and in the GNU gettext tools, the names - must follow ANSI C and not start with __. - So we have to distinguish the three cases. */ -#ifdef _LIBC -# define FREE_EXPRESSION __gettext_free_exp -# define PLURAL_PARSE __gettextparse -# define GERMANIC_PLURAL __gettext_germanic_plural -# define EXTRACT_PLURAL_EXPRESSION __gettext_extract_plural -#elif defined (IN_LIBINTL) -# define FREE_EXPRESSION libintl_gettext_free_exp -# define PLURAL_PARSE libintl_gettextparse -# define GERMANIC_PLURAL libintl_gettext_germanic_plural -# define EXTRACT_PLURAL_EXPRESSION libintl_gettext_extract_plural -#else -# define FREE_EXPRESSION free_plural_expression -# define PLURAL_PARSE parse_plural_expression -# define GERMANIC_PLURAL germanic_plural -# define EXTRACT_PLURAL_EXPRESSION extract_plural_expression -#endif - -extern void FREE_EXPRESSION PARAMS ((struct expression *exp)) - internal_function; -extern int PLURAL_PARSE PARAMS ((void *arg)); -extern struct expression GERMANIC_PLURAL attribute_hidden; -extern void EXTRACT_PLURAL_EXPRESSION PARAMS ((const char *nullentry, - struct expression **pluralp, - unsigned long int *npluralsp)) - internal_function; - -#if !defined (_LIBC) && !defined (IN_LIBINTL) -extern unsigned long int plural_eval PARAMS ((struct expression *pexp, - unsigned long int n)); -#endif - -#endif /* _PLURAL_EXP_H */ diff --git a/intl/plural.c b/intl/plural.c deleted file mode 100644 index 3a4fa20ca..000000000 --- a/intl/plural.c +++ /dev/null @@ -1,1518 +0,0 @@ -/* A Bison parser, made from plural.y - by GNU bison 1.35. */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define yyparse __gettextparse -#define yylex __gettextlex -#define yyerror __gettexterror -#define yylval __gettextlval -#define yychar __gettextchar -#define yydebug __gettextdebug -#define yynerrs __gettextnerrs -# define EQUOP2 257 -# define CMPOP2 258 -# define ADDOP2 259 -# define MULOP2 260 -# define NUMBER 261 - -#line 1 "plural.y" - -/* Expression parsing for plural form selection. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. - Written by Ulrich Drepper <drepper@cygnus.com>, 2000. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* The bison generated parser uses alloca. AIX 3 forces us to put this - declaration at the beginning of the file. The declaration in bison's - skeleton file comes too late. This must come before <config.h> - because <config.h> may include arbitrary system headers. */ -#if defined _AIX && !defined __GNUC__ - #pragma alloca -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stddef.h> -#include <stdlib.h> -#include "plural-exp.h" - -/* The main function generated by the parser is called __gettextparse, - but we want it to be called PLURAL_PARSE. */ -#ifndef _LIBC -# define __gettextparse PLURAL_PARSE -#endif - -#define YYLEX_PARAM &((struct parse_args *) arg)->cp -#define YYPARSE_PARAM arg - -#line 49 "plural.y" -#ifndef YYSTYPE -typedef union { - unsigned long int num; - enum operator op; - struct expression *exp; -} yystype; -# define YYSTYPE yystype -# define YYSTYPE_IS_TRIVIAL 1 -#endif -#line 55 "plural.y" - -/* Prototypes for local functions. */ -static struct expression *new_exp PARAMS ((int nargs, enum operator op, - struct expression * const *args)); -static inline struct expression *new_exp_0 PARAMS ((enum operator op)); -static inline struct expression *new_exp_1 PARAMS ((enum operator op, - struct expression *right)); -static struct expression *new_exp_2 PARAMS ((enum operator op, - struct expression *left, - struct expression *right)); -static inline struct expression *new_exp_3 PARAMS ((enum operator op, - struct expression *bexp, - struct expression *tbranch, - struct expression *fbranch)); -static int yylex PARAMS ((YYSTYPE *lval, const char **pexp)); -static void yyerror PARAMS ((const char *str)); - -/* Allocation of expressions. */ - -static struct expression * -new_exp (nargs, op, args) - int nargs; - enum operator op; - struct expression * const *args; -{ - int i; - struct expression *newp; - - /* If any of the argument could not be malloc'ed, just return NULL. */ - for (i = nargs - 1; i >= 0; i--) - if (args[i] == NULL) - goto fail; - - /* Allocate a new expression. */ - newp = (struct expression *) malloc (sizeof (*newp)); - if (newp != NULL) - { - newp->nargs = nargs; - newp->operation = op; - for (i = nargs - 1; i >= 0; i--) - newp->val.args[i] = args[i]; - return newp; - } - - fail: - for (i = nargs - 1; i >= 0; i--) - FREE_EXPRESSION (args[i]); - - return NULL; -} - -static inline struct expression * -new_exp_0 (op) - enum operator op; -{ - return new_exp (0, op, NULL); -} - -static inline struct expression * -new_exp_1 (op, right) - enum operator op; - struct expression *right; -{ - struct expression *args[1]; - - args[0] = right; - return new_exp (1, op, args); -} - -static struct expression * -new_exp_2 (op, left, right) - enum operator op; - struct expression *left; - struct expression *right; -{ - struct expression *args[2]; - - args[0] = left; - args[1] = right; - return new_exp (2, op, args); -} - -static inline struct expression * -new_exp_3 (op, bexp, tbranch, fbranch) - enum operator op; - struct expression *bexp; - struct expression *tbranch; - struct expression *fbranch; -{ - struct expression *args[3]; - - args[0] = bexp; - args[1] = tbranch; - args[2] = fbranch; - return new_exp (3, op, args); -} - -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - - - -#define YYFINAL 27 -#define YYFLAG -32768 -#define YYNTBASE 16 - -/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */ -#define YYTRANSLATE(x) ((unsigned)(x) <= 261 ? yytranslate[x] : 18) - -/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */ -static const char yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 10, 2, 2, 2, 2, 5, 2, - 14, 15, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 12, 2, - 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 6, 7, 8, - 9, 11 -}; - -#if YYDEBUG -static const short yyprhs[] = -{ - 0, 0, 2, 8, 12, 16, 20, 24, 28, 32, - 35, 37, 39 -}; -static const short yyrhs[] = -{ - 17, 0, 17, 3, 17, 12, 17, 0, 17, 4, - 17, 0, 17, 5, 17, 0, 17, 6, 17, 0, - 17, 7, 17, 0, 17, 8, 17, 0, 17, 9, - 17, 0, 10, 17, 0, 13, 0, 11, 0, 14, - 17, 15, 0 -}; - -#endif - -#if YYDEBUG -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const short yyrline[] = -{ - 0, 174, 182, 186, 190, 194, 198, 202, 206, 210, - 214, 218, 223 -}; -#endif - - -#if (YYDEBUG) || defined YYERROR_VERBOSE - -/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */ -static const char *const yytname[] = -{ - "$", "error", "$undefined.", "'?'", "'|'", "'&'", "EQUOP2", "CMPOP2", - "ADDOP2", "MULOP2", "'!'", "NUMBER", "':'", "'n'", "'('", "')'", - "start", "exp", 0 -}; -#endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const short yyr1[] = -{ - 0, 16, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const short yyr2[] = -{ - 0, 1, 5, 3, 3, 3, 3, 3, 3, 2, - 1, 1, 3 -}; - -/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE - doesn't specify something else to do. Zero means the default is an - error. */ -static const short yydefact[] = -{ - 0, 0, 11, 10, 0, 1, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 0, 3, 4, 5, - 6, 7, 8, 0, 2, 0, 0, 0 -}; - -static const short yydefgoto[] = -{ - 25, 5 -}; - -static const short yypact[] = -{ - -9, -9,-32768,-32768, -9, 34,-32768, 11, -9, -9, - -9, -9, -9, -9, -9,-32768, 24, 39, 43, 16, - 26, -3,-32768, -9, 34, 21, 53,-32768 -}; - -static const short yypgoto[] = -{ - -32768, -1 -}; - - -#define YYLAST 53 - - -static const short yytable[] = -{ - 6, 1, 2, 7, 3, 4, 14, 16, 17, 18, - 19, 20, 21, 22, 8, 9, 10, 11, 12, 13, - 14, 26, 24, 12, 13, 14, 15, 8, 9, 10, - 11, 12, 13, 14, 13, 14, 23, 8, 9, 10, - 11, 12, 13, 14, 10, 11, 12, 13, 14, 11, - 12, 13, 14, 27 -}; - -static const short yycheck[] = -{ - 1, 10, 11, 4, 13, 14, 9, 8, 9, 10, - 11, 12, 13, 14, 3, 4, 5, 6, 7, 8, - 9, 0, 23, 7, 8, 9, 15, 3, 4, 5, - 6, 7, 8, 9, 8, 9, 12, 3, 4, 5, - 6, 7, 8, 9, 5, 6, 7, 8, 9, 6, - 7, 8, 9, 0 -}; -#define YYPURE 1 - -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/local/share/bison/bison.simple" - -/* Skeleton output parser for bison, - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* This is the parser code that is written into each bison parser when - the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE) - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# else -# ifndef YYSTACK_USE_ALLOCA -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca -# else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -# define YYSTACK_ALLOC malloc -# define YYSTACK_FREE free -# endif -#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - short yyss; - YYSTYPE yyvs; -# if YYLSP_NEEDED - YYLTYPE yyls; -# endif -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# if YYLSP_NEEDED -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAX) -# else -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAX) -# endif - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - - -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# if defined (__STDC__) || defined (__cplusplus) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int -#endif - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror ("syntax error: cannot back up"); \ - YYERROR; \ - } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). - - When YYLLOC_DEFAULT is run, CURRENT is set the location of the - first token. By default, to implement support for ranges, extend - its range to the last symbol. */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - Current.last_line = Rhs[N].last_line; \ - Current.last_column = Rhs[N].last_column; -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#if YYPURE -# if YYLSP_NEEDED -# ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -# else -# define YYLEX yylex (&yylval, &yylloc) -# endif -# else /* !YYLSP_NEEDED */ -# ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, YYLEX_PARAM) -# else -# define YYLEX yylex (&yylval) -# endif -# endif /* !YYLSP_NEEDED */ -#else /* !YYPURE */ -# define YYLEX yylex () -#endif /* !YYPURE */ - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -#endif /* !YYDEBUG */ - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#if YYMAXDEPTH == 0 -# undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - -#ifdef YYERROR_VERBOSE - -# ifndef yystrlen -# if defined (__GLIBC__) && defined (_STRING_H) -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -# if defined (__STDC__) || defined (__cplusplus) -yystrlen (const char *yystr) -# else -yystrlen (yystr) - const char *yystr; -# endif -{ - register const char *yys = yystr; - - while (*yys++ != '\0') - continue; - - return yys - yystr - 1; -} -# endif -# endif - -# ifndef yystpcpy -# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -# if defined (__STDC__) || defined (__cplusplus) -yystpcpy (char *yydest, const char *yysrc) -# else -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -# endif -{ - register char *yyd = yydest; - register const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif -#endif - -#line 315 "/usr/local/share/bison/bison.simple" - - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -# define YYPARSE_PARAM_DECL -# else -# define YYPARSE_PARAM_ARG YYPARSE_PARAM -# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -# endif -#else /* !YYPARSE_PARAM */ -# define YYPARSE_PARAM_ARG -# define YYPARSE_PARAM_DECL -#endif /* !YYPARSE_PARAM */ - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -# ifdef YYPARSE_PARAM -int yyparse (void *); -# else -int yyparse (void); -# endif -#endif - -/* YY_DECL_VARIABLES -- depending whether we use a pure parser, - variables are global, or local to YYPARSE. */ - -#define YY_DECL_NON_LSP_VARIABLES \ -/* The lookahead symbol. */ \ -int yychar; \ - \ -/* The semantic value of the lookahead symbol. */ \ -YYSTYPE yylval; \ - \ -/* Number of parse errors so far. */ \ -int yynerrs; - -#if YYLSP_NEEDED -# define YY_DECL_VARIABLES \ -YY_DECL_NON_LSP_VARIABLES \ - \ -/* Location data for the lookahead symbol. */ \ -YYLTYPE yylloc; -#else -# define YY_DECL_VARIABLES \ -YY_DECL_NON_LSP_VARIABLES -#endif - - -/* If nonreentrant, generate the variables here. */ - -#if !YYPURE -YY_DECL_VARIABLES -#endif /* !YYPURE */ - -int -yyparse (YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - /* If reentrant, generate the variables here. */ -#if YYPURE - YY_DECL_VARIABLES -#endif /* !YYPURE */ - - register int yystate; - register int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Lookahead token as an internal (translated) token number. */ - int yychar1 = 0; - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - short yyssa[YYINITDEPTH]; - short *yyss = yyssa; - register short *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - register YYSTYPE *yyvsp; - -#if YYLSP_NEEDED - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; -#endif - -#if YYLSP_NEEDED -# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -# define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - YYSIZE_T yystacksize = YYINITDEPTH; - - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; -#if YYLSP_NEEDED - YYLTYPE yyloc; -#endif - - /* When reducing, the number of symbols on the RHS of the reduced - rule. */ - int yylen; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; -#if YYLSP_NEEDED - yylsp = yyls; -#endif - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. - */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. */ -# if YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - yyls = yyls1; -# else - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); -# endif - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyoverflowlab; -# else - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - goto yyoverflowlab; - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; - - { - short *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); -# if YYLSP_NEEDED - YYSTACK_RELOCATE (yyls); -# endif -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; -#if YYLSP_NEEDED - yylsp = yyls + yysize - 1; -#endif - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yychar1 = YYTRANSLATE (yychar); - -#if YYDEBUG - /* We have to keep this `#if YYDEBUG', since we use variables - which are defined only if `YYDEBUG' is set. */ - if (yydebug) - { - YYFPRINTF (stderr, "Next token is %d (%s", - yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise - meaning of a token, for further debugging info. */ -# ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -# endif - YYFPRINTF (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - YYDPRINTF ((stderr, "Shifting token %d (%s), ", - yychar, yytname[yychar1])); - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#if YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - yystate = yyn; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to the semantic value of - the lookahead token. This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - -#if YYLSP_NEEDED - /* Similarly for the default location. Let the user run additional - commands if for instance locations are ranges. */ - yyloc = yylsp[1-yylen]; - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); -#endif - -#if YYDEBUG - /* We have to keep this `#if YYDEBUG', since we use variables which - are defined only if `YYDEBUG' is set. */ - if (yydebug) - { - int yyi; - - YYFPRINTF (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++) - YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); - YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - switch (yyn) { - -case 1: -#line 175 "plural.y" -{ - if (yyvsp[0].exp == NULL) - YYABORT; - ((struct parse_args *) arg)->res = yyvsp[0].exp; - } - break; -case 2: -#line 183 "plural.y" -{ - yyval.exp = new_exp_3 (qmop, yyvsp[-4].exp, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 3: -#line 187 "plural.y" -{ - yyval.exp = new_exp_2 (lor, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 4: -#line 191 "plural.y" -{ - yyval.exp = new_exp_2 (land, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 5: -#line 195 "plural.y" -{ - yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 6: -#line 199 "plural.y" -{ - yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 7: -#line 203 "plural.y" -{ - yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 8: -#line 207 "plural.y" -{ - yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 9: -#line 211 "plural.y" -{ - yyval.exp = new_exp_1 (lnot, yyvsp[0].exp); - } - break; -case 10: -#line 215 "plural.y" -{ - yyval.exp = new_exp_0 (var); - } - break; -case 11: -#line 219 "plural.y" -{ - if ((yyval.exp = new_exp_0 (num)) != NULL) - yyval.exp->val.num = yyvsp[0].num; - } - break; -case 12: -#line 224 "plural.y" -{ - yyval.exp = yyvsp[-1].exp; - } - break; -} - -#line 705 "/usr/local/share/bison/bison.simple" - - - yyvsp -= yylen; - yyssp -= yylen; -#if YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG - if (yydebug) - { - short *yyssp1 = yyss - 1; - YYFPRINTF (stderr, "state stack now"); - while (yyssp1 != yyssp) - YYFPRINTF (stderr, " %d", *++yyssp1); - YYFPRINTF (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; -#if YYLSP_NEEDED - *++yylsp = yyloc; -#endif - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - YYSIZE_T yysize = 0; - char *yymsg; - int yyx, yycount; - - yycount = 0; - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) - if (yycheck[yyx + yyn] == yyx) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("parse error, unexpected ") + 1; - yysize += yystrlen (yytname[YYTRANSLATE (yychar)]); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "parse error, unexpected "); - yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]); - - if (yycount < 5) - { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) - if (yycheck[yyx + yyn] == yyx) - { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); - yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - yyerror ("parse error; also virtual memory exhausted"); - } - else -#endif /* defined (YYERROR_VERBOSE) */ - yyerror ("parse error"); - } - goto yyerrlab1; - - -/*--------------------------------------------------. -| yyerrlab1 -- error raised explicitly by an action | -`--------------------------------------------------*/ -yyerrlab1: - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - YYDPRINTF ((stderr, "Discarding token %d (%s).\n", - yychar, yytname[yychar1])); - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - - -/*-------------------------------------------------------------------. -| yyerrdefault -- current state does not do anything special for the | -| error token. | -`-------------------------------------------------------------------*/ -yyerrdefault: -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - - /* If its default is to accept any token, ok. Otherwise pop it. */ - yyn = yydefact[yystate]; - if (yyn) - goto yydefault; -#endif - - -/*---------------------------------------------------------------. -| yyerrpop -- pop the current state because it cannot handle the | -| error token | -`---------------------------------------------------------------*/ -yyerrpop: - if (yyssp == yyss) - YYABORT; - yyvsp--; - yystate = *--yyssp; -#if YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG - if (yydebug) - { - short *yyssp1 = yyss - 1; - YYFPRINTF (stderr, "Error: state stack now"); - while (yyssp1 != yyssp) - YYFPRINTF (stderr, " %d", *++yyssp1); - YYFPRINTF (stderr, "\n"); - } -#endif - -/*--------------. -| yyerrhandle. | -`--------------*/ -yyerrhandle: - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - - YYDPRINTF ((stderr, "Shifting error token, ")); - - *++yyvsp = yylval; -#if YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -/*---------------------------------------------. -| yyoverflowab -- parser overflow comes here. | -`---------------------------------------------*/ -yyoverflowlab: - yyerror ("parser stack overflow"); - yyresult = 2; - /* Fall through. */ - -yyreturn: -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - return yyresult; -} -#line 229 "plural.y" - - -void -internal_function -FREE_EXPRESSION (exp) - struct expression *exp; -{ - if (exp == NULL) - return; - - /* Handle the recursive case. */ - switch (exp->nargs) - { - case 3: - FREE_EXPRESSION (exp->val.args[2]); - /* FALLTHROUGH */ - case 2: - FREE_EXPRESSION (exp->val.args[1]); - /* FALLTHROUGH */ - case 1: - FREE_EXPRESSION (exp->val.args[0]); - /* FALLTHROUGH */ - default: - break; - } - - free (exp); -} - - -static int -yylex (lval, pexp) - YYSTYPE *lval; - const char **pexp; -{ - const char *exp = *pexp; - int result; - - while (1) - { - if (exp[0] == '\0') - { - *pexp = exp; - return YYEOF; - } - - if (exp[0] != ' ' && exp[0] != '\t') - break; - - ++exp; - } - - result = *exp++; - switch (result) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - { - unsigned long int n = result - '0'; - while (exp[0] >= '0' && exp[0] <= '9') - { - n *= 10; - n += exp[0] - '0'; - ++exp; - } - lval->num = n; - result = NUMBER; - } - break; - - case '=': - if (exp[0] == '=') - { - ++exp; - lval->op = equal; - result = EQUOP2; - } - else - result = YYERRCODE; - break; - - case '!': - if (exp[0] == '=') - { - ++exp; - lval->op = not_equal; - result = EQUOP2; - } - break; - - case '&': - case '|': - if (exp[0] == result) - ++exp; - else - result = YYERRCODE; - break; - - case '<': - if (exp[0] == '=') - { - ++exp; - lval->op = less_or_equal; - } - else - lval->op = less_than; - result = CMPOP2; - break; - - case '>': - if (exp[0] == '=') - { - ++exp; - lval->op = greater_or_equal; - } - else - lval->op = greater_than; - result = CMPOP2; - break; - - case '*': - lval->op = mult; - result = MULOP2; - break; - - case '/': - lval->op = divide; - result = MULOP2; - break; - - case '%': - lval->op = module; - result = MULOP2; - break; - - case '+': - lval->op = plus; - result = ADDOP2; - break; - - case '-': - lval->op = minus; - result = ADDOP2; - break; - - case 'n': - case '?': - case ':': - case '(': - case ')': - /* Nothing, just return the character. */ - break; - - case ';': - case '\n': - case '\0': - /* Be safe and let the user call this function again. */ - --exp; - result = YYEOF; - break; - - default: - result = YYERRCODE; -#if YYDEBUG != 0 - --exp; -#endif - break; - } - - *pexp = exp; - - return result; -} - - -static void -yyerror (str) - const char *str; -{ - /* Do nothing. We don't print error messages here. */ -} diff --git a/intl/plural.y b/intl/plural.y deleted file mode 100644 index 616b7c11a..000000000 --- a/intl/plural.y +++ /dev/null @@ -1,409 +0,0 @@ -%{ -/* Expression parsing for plural form selection. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. - Written by Ulrich Drepper <drepper@cygnus.com>, 2000. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* The bison generated parser uses alloca. AIX 3 forces us to put this - declaration at the beginning of the file. The declaration in bison's - skeleton file comes too late. This must come before <config.h> - because <config.h> may include arbitrary system headers. */ -#if defined _AIX && !defined __GNUC__ - #pragma alloca -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stddef.h> -#include <stdlib.h> -#include "plural-exp.h" - -/* The main function generated by the parser is called __gettextparse, - but we want it to be called PLURAL_PARSE. */ -#ifndef _LIBC -# define __gettextparse PLURAL_PARSE -#endif - -#define YYLEX_PARAM &((struct parse_args *) arg)->cp -#define YYPARSE_PARAM arg -%} -%pure_parser -%expect 7 - -%union { - unsigned long int num; - enum operator op; - struct expression *exp; -} - -%{ -/* Prototypes for local functions. */ -static struct expression *new_exp PARAMS ((int nargs, enum operator op, - struct expression * const *args)); -static inline struct expression *new_exp_0 PARAMS ((enum operator op)); -static inline struct expression *new_exp_1 PARAMS ((enum operator op, - struct expression *right)); -static struct expression *new_exp_2 PARAMS ((enum operator op, - struct expression *left, - struct expression *right)); -static inline struct expression *new_exp_3 PARAMS ((enum operator op, - struct expression *bexp, - struct expression *tbranch, - struct expression *fbranch)); -static int yylex PARAMS ((YYSTYPE *lval, const char **pexp)); -static void yyerror PARAMS ((const char *str)); - -/* Allocation of expressions. */ - -static struct expression * -new_exp (nargs, op, args) - int nargs; - enum operator op; - struct expression * const *args; -{ - int i; - struct expression *newp; - - /* If any of the argument could not be malloc'ed, just return NULL. */ - for (i = nargs - 1; i >= 0; i--) - if (args[i] == NULL) - goto fail; - - /* Allocate a new expression. */ - newp = (struct expression *) malloc (sizeof (*newp)); - if (newp != NULL) - { - newp->nargs = nargs; - newp->operation = op; - for (i = nargs - 1; i >= 0; i--) - newp->val.args[i] = args[i]; - return newp; - } - - fail: - for (i = nargs - 1; i >= 0; i--) - FREE_EXPRESSION (args[i]); - - return NULL; -} - -static inline struct expression * -new_exp_0 (op) - enum operator op; -{ - return new_exp (0, op, NULL); -} - -static inline struct expression * -new_exp_1 (op, right) - enum operator op; - struct expression *right; -{ - struct expression *args[1]; - - args[0] = right; - return new_exp (1, op, args); -} - -static struct expression * -new_exp_2 (op, left, right) - enum operator op; - struct expression *left; - struct expression *right; -{ - struct expression *args[2]; - - args[0] = left; - args[1] = right; - return new_exp (2, op, args); -} - -static inline struct expression * -new_exp_3 (op, bexp, tbranch, fbranch) - enum operator op; - struct expression *bexp; - struct expression *tbranch; - struct expression *fbranch; -{ - struct expression *args[3]; - - args[0] = bexp; - args[1] = tbranch; - args[2] = fbranch; - return new_exp (3, op, args); -} - -%} - -/* This declares that all operators have the same associativity and the - precedence order as in C. See [Harbison, Steele: C, A Reference Manual]. - There is no unary minus and no bitwise operators. - Operators with the same syntactic behaviour have been merged into a single - token, to save space in the array generated by bison. */ -%right '?' /* ? */ -%left '|' /* || */ -%left '&' /* && */ -%left EQUOP2 /* == != */ -%left CMPOP2 /* < > <= >= */ -%left ADDOP2 /* + - */ -%left MULOP2 /* * / % */ -%right '!' /* ! */ - -%token <op> EQUOP2 CMPOP2 ADDOP2 MULOP2 -%token <num> NUMBER -%type <exp> exp - -%% - -start: exp - { - if ($1 == NULL) - YYABORT; - ((struct parse_args *) arg)->res = $1; - } - ; - -exp: exp '?' exp ':' exp - { - $$ = new_exp_3 (qmop, $1, $3, $5); - } - | exp '|' exp - { - $$ = new_exp_2 (lor, $1, $3); - } - | exp '&' exp - { - $$ = new_exp_2 (land, $1, $3); - } - | exp EQUOP2 exp - { - $$ = new_exp_2 ($2, $1, $3); - } - | exp CMPOP2 exp - { - $$ = new_exp_2 ($2, $1, $3); - } - | exp ADDOP2 exp - { - $$ = new_exp_2 ($2, $1, $3); - } - | exp MULOP2 exp - { - $$ = new_exp_2 ($2, $1, $3); - } - | '!' exp - { - $$ = new_exp_1 (lnot, $2); - } - | 'n' - { - $$ = new_exp_0 (var); - } - | NUMBER - { - if (($$ = new_exp_0 (num)) != NULL) - $$->val.num = $1; - } - | '(' exp ')' - { - $$ = $2; - } - ; - -%% - -void -internal_function -FREE_EXPRESSION (exp) - struct expression *exp; -{ - if (exp == NULL) - return; - - /* Handle the recursive case. */ - switch (exp->nargs) - { - case 3: - FREE_EXPRESSION (exp->val.args[2]); - /* FALLTHROUGH */ - case 2: - FREE_EXPRESSION (exp->val.args[1]); - /* FALLTHROUGH */ - case 1: - FREE_EXPRESSION (exp->val.args[0]); - /* FALLTHROUGH */ - default: - break; - } - - free (exp); -} - - -static int -yylex (lval, pexp) - YYSTYPE *lval; - const char **pexp; -{ - const char *exp = *pexp; - int result; - - while (1) - { - if (exp[0] == '\0') - { - *pexp = exp; - return YYEOF; - } - - if (exp[0] != ' ' && exp[0] != '\t') - break; - - ++exp; - } - - result = *exp++; - switch (result) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - { - unsigned long int n = result - '0'; - while (exp[0] >= '0' && exp[0] <= '9') - { - n *= 10; - n += exp[0] - '0'; - ++exp; - } - lval->num = n; - result = NUMBER; - } - break; - - case '=': - if (exp[0] == '=') - { - ++exp; - lval->op = equal; - result = EQUOP2; - } - else - result = YYERRCODE; - break; - - case '!': - if (exp[0] == '=') - { - ++exp; - lval->op = not_equal; - result = EQUOP2; - } - break; - - case '&': - case '|': - if (exp[0] == result) - ++exp; - else - result = YYERRCODE; - break; - - case '<': - if (exp[0] == '=') - { - ++exp; - lval->op = less_or_equal; - } - else - lval->op = less_than; - result = CMPOP2; - break; - - case '>': - if (exp[0] == '=') - { - ++exp; - lval->op = greater_or_equal; - } - else - lval->op = greater_than; - result = CMPOP2; - break; - - case '*': - lval->op = mult; - result = MULOP2; - break; - - case '/': - lval->op = divide; - result = MULOP2; - break; - - case '%': - lval->op = module; - result = MULOP2; - break; - - case '+': - lval->op = plus; - result = ADDOP2; - break; - - case '-': - lval->op = minus; - result = ADDOP2; - break; - - case 'n': - case '?': - case ':': - case '(': - case ')': - /* Nothing, just return the character. */ - break; - - case ';': - case '\n': - case '\0': - /* Be safe and let the user call this function again. */ - --exp; - result = YYEOF; - break; - - default: - result = YYERRCODE; -#if YYDEBUG != 0 - --exp; -#endif - break; - } - - *pexp = exp; - - return result; -} - - -static void -yyerror (str) - const char *str; -{ - /* Do nothing. We don't print error messages here. */ -} diff --git a/intl/ref-add.sin b/intl/ref-add.sin deleted file mode 100644 index 167374e3c..000000000 --- a/intl/ref-add.sin +++ /dev/null @@ -1,31 +0,0 @@ -# Add this package to a list of references stored in a text file. -# -# Copyright (C) 2000 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Library General Public License as published -# by the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA. -# -# Written by Bruno Haible <haible@clisp.cons.org>. -# -/^# Packages using this file: / { - s/# Packages using this file:// - ta - :a - s/ @PACKAGE@ / @PACKAGE@ / - tb - s/ $/ @PACKAGE@ / - :b - s/^/# Packages using this file:/ -} diff --git a/intl/ref-del.sin b/intl/ref-del.sin deleted file mode 100644 index 613cf37f3..000000000 --- a/intl/ref-del.sin +++ /dev/null @@ -1,26 +0,0 @@ -# Remove this package from a list of references stored in a text file. -# -# Copyright (C) 2000 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Library General Public License as published -# by the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA. -# -# Written by Bruno Haible <haible@clisp.cons.org>. -# -/^# Packages using this file: / { - s/# Packages using this file:// - s/ @PACKAGE@ / / - s/^/# Packages using this file:/ -} diff --git a/intl/relocatable.c b/intl/relocatable.c deleted file mode 100644 index 16f79a528..000000000 --- a/intl/relocatable.c +++ /dev/null @@ -1,439 +0,0 @@ -/* Provide relocatable packages. - Copyright (C) 2003 Free Software Foundation, Inc. - Written by Bruno Haible <bruno@clisp.org>, 2003. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - - -/* Tell glibc's <stdio.h> to provide a prototype for getline(). - This must come before <config.h> because <config.h> may include - <features.h>, and once <features.h> has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -/* Specification. */ -#include "relocatable.h" - -#if ENABLE_RELOCATABLE - -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef NO_XMALLOC -# define xmalloc malloc -#else -# include "xmalloc.h" -#endif - -#if DEPENDS_ON_LIBCHARSET -# include <libcharset.h> -#endif -#if DEPENDS_ON_LIBICONV && HAVE_ICONV -# include <iconv.h> -#endif -#if DEPENDS_ON_LIBINTL && ENABLE_NLS -# include <libintl.h> -#endif - -/* Faked cheap 'bool'. */ -#undef bool -#undef false -#undef true -#define bool int -#define false 0 -#define true 1 - -/* Pathname support. - ISSLASH(C) tests whether C is a directory separator character. - IS_PATH_WITH_DIR(P) tests whether P contains a directory specification. - */ -#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS */ -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -# define HAS_DEVICE(P) \ - ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ - && (P)[1] == ':') -# define IS_PATH_WITH_DIR(P) \ - (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P)) -# define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0) -#else - /* Unix */ -# define ISSLASH(C) ((C) == '/') -# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL) -# define FILESYSTEM_PREFIX_LEN(P) 0 -#endif - -/* Original installation prefix. */ -static char *orig_prefix; -static size_t orig_prefix_len; -/* Current installation prefix. */ -static char *curr_prefix; -static size_t curr_prefix_len; -/* These prefixes do not end in a slash. Anything that will be concatenated - to them must start with a slash. */ - -/* Sets the original and the current installation prefix of this module. - Relocation simply replaces a pathname starting with the original prefix - by the corresponding pathname with the current prefix instead. Both - prefixes should be directory names without trailing slash (i.e. use "" - instead of "/"). */ -static void -set_this_relocation_prefix (const char *orig_prefix_arg, - const char *curr_prefix_arg) -{ - if (orig_prefix_arg != NULL && curr_prefix_arg != NULL - /* Optimization: if orig_prefix and curr_prefix are equal, the - relocation is a nop. */ - && strcmp (orig_prefix_arg, curr_prefix_arg) != 0) - { - /* Duplicate the argument strings. */ - char *memory; - - orig_prefix_len = strlen (orig_prefix_arg); - curr_prefix_len = strlen (curr_prefix_arg); - memory = (char *) xmalloc (orig_prefix_len + 1 + curr_prefix_len + 1); -#ifdef NO_XMALLOC - if (memory != NULL) -#endif - { - memcpy (memory, orig_prefix_arg, orig_prefix_len + 1); - orig_prefix = memory; - memory += orig_prefix_len + 1; - memcpy (memory, curr_prefix_arg, curr_prefix_len + 1); - curr_prefix = memory; - return; - } - } - orig_prefix = NULL; - curr_prefix = NULL; - /* Don't worry about wasted memory here - this function is usually only - called once. */ -} - -/* Sets the original and the current installation prefix of the package. - Relocation simply replaces a pathname starting with the original prefix - by the corresponding pathname with the current prefix instead. Both - prefixes should be directory names without trailing slash (i.e. use "" - instead of "/"). */ -void -set_relocation_prefix (const char *orig_prefix_arg, const char *curr_prefix_arg) -{ - set_this_relocation_prefix (orig_prefix_arg, curr_prefix_arg); - - /* Now notify all dependent libraries. */ -#if DEPENDS_ON_LIBCHARSET - libcharset_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg); -#endif -#if DEPENDS_ON_LIBICONV && HAVE_ICONV && _LIBICONV_VERSION >= 0x0109 - libiconv_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg); -#endif -#if DEPENDS_ON_LIBINTL && ENABLE_NLS && defined libintl_set_relocation_prefix - libintl_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg); -#endif -} - -/* Convenience function: - Computes the current installation prefix, based on the original - installation prefix, the original installation directory of a particular - file, and the current pathname of this file. Returns NULL upon failure. */ -#ifdef IN_LIBRARY -#define compute_curr_prefix local_compute_curr_prefix -static -#endif -const char * -compute_curr_prefix (const char *orig_installprefix, - const char *orig_installdir, - const char *curr_pathname) -{ - const char *curr_installdir; - const char *rel_installdir; - - if (curr_pathname == NULL) - return NULL; - - /* Determine the relative installation directory, relative to the prefix. - This is simply the difference between orig_installprefix and - orig_installdir. */ - if (strncmp (orig_installprefix, orig_installdir, strlen (orig_installprefix)) - != 0) - /* Shouldn't happen - nothing should be installed outside $(prefix). */ - return NULL; - rel_installdir = orig_installdir + strlen (orig_installprefix); - - /* Determine the current installation directory. */ - { - const char *p_base = curr_pathname + FILESYSTEM_PREFIX_LEN (curr_pathname); - const char *p = curr_pathname + strlen (curr_pathname); - char *q; - - while (p > p_base) - { - p--; - if (ISSLASH (*p)) - break; - } - - q = (char *) xmalloc (p - curr_pathname + 1); -#ifdef NO_XMALLOC - if (q == NULL) - return NULL; -#endif - memcpy (q, curr_pathname, p - curr_pathname); - q[p - curr_pathname] = '\0'; - curr_installdir = q; - } - - /* Compute the current installation prefix by removing the trailing - rel_installdir from it. */ - { - const char *rp = rel_installdir + strlen (rel_installdir); - const char *cp = curr_installdir + strlen (curr_installdir); - const char *cp_base = - curr_installdir + FILESYSTEM_PREFIX_LEN (curr_installdir); - - while (rp > rel_installdir && cp > cp_base) - { - bool same = false; - const char *rpi = rp; - const char *cpi = cp; - - while (rpi > rel_installdir && cpi > cp_base) - { - rpi--; - cpi--; - if (ISSLASH (*rpi) || ISSLASH (*cpi)) - { - if (ISSLASH (*rpi) && ISSLASH (*cpi)) - same = true; - break; - } -#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS - case insignificant filesystem */ - if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi) - != (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi)) - break; -#else - if (*rpi != *cpi) - break; -#endif - } - if (!same) - break; - /* The last pathname component was the same. opi and cpi now point - to the slash before it. */ - rp = rpi; - cp = cpi; - } - - if (rp > rel_installdir) - /* Unexpected: The curr_installdir does not end with rel_installdir. */ - return NULL; - - { - size_t curr_prefix_len = cp - curr_installdir; - char *curr_prefix; - - curr_prefix = (char *) xmalloc (curr_prefix_len + 1); -#ifdef NO_XMALLOC - if (curr_prefix == NULL) - return NULL; -#endif - memcpy (curr_prefix, curr_installdir, curr_prefix_len); - curr_prefix[curr_prefix_len] = '\0'; - - return curr_prefix; - } - } -} - -#if defined PIC && defined INSTALLDIR - -/* Full pathname of shared library, or NULL. */ -static char *shared_library_fullname; - -#if defined _WIN32 || defined __WIN32__ - -/* Determine the full pathname of the shared library when it is loaded. */ - -BOOL WINAPI -DllMain (HINSTANCE module_handle, DWORD event, LPVOID reserved) -{ - (void) reserved; - - if (event == DLL_PROCESS_ATTACH) - { - /* The DLL is being loaded into an application's address range. */ - static char location[MAX_PATH]; - - if (!GetModuleFileName (module_handle, location, sizeof (location))) - /* Shouldn't happen. */ - return FALSE; - - if (!IS_PATH_WITH_DIR (location)) - /* Shouldn't happen. */ - return FALSE; - - shared_library_fullname = strdup (location); - } - - return TRUE; -} - -#else /* Unix */ - -static void -find_shared_library_fullname () -{ -#ifdef __linux__ - FILE *fp; - - /* Open the current process' maps file. It describes one VMA per line. */ - fp = fopen ("/proc/self/maps", "r"); - if (fp) - { - unsigned long address = (unsigned long) &find_shared_library_fullname; - for (;;) - { - unsigned long start, end; - int c; - - if (fscanf (fp, "%lx-%lx", &start, &end) != 2) - break; - if (address >= start && address <= end - 1) - { - /* Found it. Now see if this line contains a filename. */ - while (c = getc (fp), c != EOF && c != '\n' && c != '/') - continue; - if (c == '/') - { - size_t size; - int len; - - ungetc (c, fp); - shared_library_fullname = NULL; size = 0; - len = getline (&shared_library_fullname, &size, fp); - if (len >= 0) - { - /* Success: filled shared_library_fullname. */ - if (len > 0 && shared_library_fullname[len - 1] == '\n') - shared_library_fullname[len - 1] = '\0'; - } - } - break; - } - while (c = getc (fp), c != EOF && c != '\n') - continue; - } - fclose (fp); - } -#endif -} - -#endif /* WIN32 / Unix */ - -/* Return the full pathname of the current shared library. - Return NULL if unknown. - Guaranteed to work only on Linux and Woe32. */ -static char * -get_shared_library_fullname () -{ -#if !(defined _WIN32 || defined __WIN32__) - static bool tried_find_shared_library_fullname; - if (!tried_find_shared_library_fullname) - { - find_shared_library_fullname (); - tried_find_shared_library_fullname = true; - } -#endif - return shared_library_fullname; -} - -#endif /* PIC */ - -/* Returns the pathname, relocated according to the current installation - directory. */ -const char * -relocate (const char *pathname) -{ -#if defined PIC && defined INSTALLDIR - static int initialized; - - /* Initialization code for a shared library. */ - if (!initialized) - { - /* At this point, orig_prefix and curr_prefix likely have already been - set through the main program's set_program_name_and_installdir - function. This is sufficient in the case that the library has - initially been installed in the same orig_prefix. But we can do - better, to also cover the cases that 1. it has been installed - in a different prefix before being moved to orig_prefix and (later) - to curr_prefix, 2. unlike the program, it has not moved away from - orig_prefix. */ - const char *orig_installprefix = INSTALLPREFIX; - const char *orig_installdir = INSTALLDIR; - const char *curr_prefix_better; - - curr_prefix_better = - compute_curr_prefix (orig_installprefix, orig_installdir, - get_shared_library_fullname ()); - if (curr_prefix_better == NULL) - curr_prefix_better = curr_prefix; - - set_relocation_prefix (orig_installprefix, curr_prefix_better); - - initialized = 1; - } -#endif - - /* Note: It is not necessary to perform case insensitive comparison here, - even for DOS-like filesystems, because the pathname argument was - typically created from the same Makefile variable as orig_prefix came - from. */ - if (orig_prefix != NULL && curr_prefix != NULL - && strncmp (pathname, orig_prefix, orig_prefix_len) == 0) - { - if (pathname[orig_prefix_len] == '\0') - /* pathname equals orig_prefix. */ - return curr_prefix; - if (ISSLASH (pathname[orig_prefix_len])) - { - /* pathname starts with orig_prefix. */ - const char *pathname_tail = &pathname[orig_prefix_len]; - char *result = - (char *) xmalloc (curr_prefix_len + strlen (pathname_tail) + 1); - -#ifdef NO_XMALLOC - if (result != NULL) -#endif - { - memcpy (result, curr_prefix, curr_prefix_len); - strcpy (result + curr_prefix_len, pathname_tail); - return result; - } - } - } - /* Nothing to relocate. */ - return pathname; -} - -#endif diff --git a/intl/relocatable.h b/intl/relocatable.h deleted file mode 100644 index d141200a6..000000000 --- a/intl/relocatable.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Provide relocatable packages. - Copyright (C) 2003 Free Software Foundation, Inc. - Written by Bruno Haible <bruno@clisp.org>, 2003. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _RELOCATABLE_H -#define _RELOCATABLE_H - -/* This can be enabled through the configure --enable-relocatable option. */ -#if ENABLE_RELOCATABLE - -/* When building a DLL, we must export some functions. Note that because - this is a private .h file, we don't need to use __declspec(dllimport) - in any case. */ -#if defined _MSC_VER && BUILDING_DLL -# define RELOCATABLE_DLL_EXPORTED __declspec(dllexport) -#else -# define RELOCATABLE_DLL_EXPORTED -#endif - -/* Sets the original and the current installation prefix of the package. - Relocation simply replaces a pathname starting with the original prefix - by the corresponding pathname with the current prefix instead. Both - prefixes should be directory names without trailing slash (i.e. use "" - instead of "/"). */ -extern RELOCATABLE_DLL_EXPORTED void - set_relocation_prefix (const char *orig_prefix, - const char *curr_prefix); - -/* Returns the pathname, relocated according to the current installation - directory. */ -extern const char * relocate (const char *pathname); - -/* Memory management: relocate() leaks memory, because it has to construct - a fresh pathname. If this is a problem because your program calls - relocate() frequently, think about caching the result. */ - -/* Convenience function: - Computes the current installation prefix, based on the original - installation prefix, the original installation directory of a particular - file, and the current pathname of this file. Returns NULL upon failure. */ -extern const char * compute_curr_prefix (const char *orig_installprefix, - const char *orig_installdir, - const char *curr_pathname); - -#else - -/* By default, we use the hardwired pathnames. */ -#define relocate(pathname) (pathname) - -#endif - -#endif /* _RELOCATABLE_H */ diff --git a/intl/textdomain.c b/intl/textdomain.c deleted file mode 100644 index f259c696d..000000000 --- a/intl/textdomain.c +++ /dev/null @@ -1,142 +0,0 @@ -/* Implementation of the textdomain(3) function. - Copyright (C) 1995-1998, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif -#include "gettextP.h" - -#ifdef _LIBC -/* We have to handle multi-threaded applications. */ -# include <bits/libc-lock.h> -#else -/* Provide dummy implementation if this is outside glibc. */ -# define __libc_rwlock_define(CLASS, NAME) -# define __libc_rwlock_wrlock(NAME) -# define __libc_rwlock_unlock(NAME) -#endif - -/* The internal variables in the standalone libintl.a must have different - names than the internal variables in GNU libc, otherwise programs - using libintl.a cannot be linked statically. */ -#if !defined _LIBC -# define _nl_default_default_domain libintl_nl_default_default_domain -# define _nl_current_default_domain libintl_nl_current_default_domain -#endif - -/* @@ end of prolog @@ */ - -/* Name of the default text domain. */ -extern const char _nl_default_default_domain[] attribute_hidden; - -/* Default text domain in which entries for gettext(3) are to be found. */ -extern const char *_nl_current_default_domain attribute_hidden; - - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define TEXTDOMAIN __textdomain -# ifndef strdup -# define strdup(str) __strdup (str) -# endif -#else -# define TEXTDOMAIN libintl_textdomain -#endif - -/* Lock variable to protect the global data in the gettext implementation. */ -__libc_rwlock_define (extern, _nl_state_lock attribute_hidden) - -/* Set the current default message catalog to DOMAINNAME. - If DOMAINNAME is null, return the current default. - If DOMAINNAME is "", reset to the default of "messages". */ -char * -TEXTDOMAIN (domainname) - const char *domainname; -{ - char *new_domain; - char *old_domain; - - /* A NULL pointer requests the current setting. */ - if (domainname == NULL) - return (char *) _nl_current_default_domain; - - __libc_rwlock_wrlock (_nl_state_lock); - - old_domain = (char *) _nl_current_default_domain; - - /* If domain name is the null string set to default domain "messages". */ - if (domainname[0] == '\0' - || strcmp (domainname, _nl_default_default_domain) == 0) - { - _nl_current_default_domain = _nl_default_default_domain; - new_domain = (char *) _nl_current_default_domain; - } - else if (strcmp (domainname, old_domain) == 0) - /* This can happen and people will use it to signal that some - environment variable changed. */ - new_domain = old_domain; - else - { - /* If the following malloc fails `_nl_current_default_domain' - will be NULL. This value will be returned and so signals we - are out of core. */ -#if defined _LIBC || defined HAVE_STRDUP - new_domain = strdup (domainname); -#else - size_t len = strlen (domainname) + 1; - new_domain = (char *) malloc (len); - if (new_domain != NULL) - memcpy (new_domain, domainname, len); -#endif - - if (new_domain != NULL) - _nl_current_default_domain = new_domain; - } - - /* We use this possibility to signal a change of the loaded catalogs - since this is most likely the case and there is no other easy we - to do it. Do it only when the call was successful. */ - if (new_domain != NULL) - { - ++_nl_msg_cat_cntr; - - if (old_domain != new_domain && old_domain != _nl_default_default_domain) - free (old_domain); - } - - __libc_rwlock_unlock (_nl_state_lock); - - return new_domain; -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__textdomain, textdomain); -#endif diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog deleted file mode 100644 index e9f643774..000000000 --- a/jnlib/ChangeLog +++ /dev/null @@ -1,209 +0,0 @@ -2004-05-05 Werner Koch <wk@gnupg.org> - - * logging.c (log_set_file): Oops, don't close if LOGSTREAM is NULL. - -2004-04-30 Werner Koch <wk@gnupg.org> - - * logging.c (log_set_file): Make sure the log stream will be - closed even if the stderr fileno will be assigned to a new socket. - -2004-04-16 Werner Koch <wk@gnupg.org> - - * logging.h (JNLIB_LOG_WITH_PREFIX): Add constants for the flag - values. - * logging.c (log_set_prefix): New flag DETACHED. - (fun_writer): Take care of this flag. - (log_test_fd): New. - -2004-02-18 Werner Koch <wk@gnupg.org> - - * stringhelp.c (print_sanitized_buffer): Don't care about - non-ASCII characaters. - (sanitize_buffer): Ditto. - -2004-02-12 Werner Koch <wk@gnupg.org> - - * Makefile.am: Replaced INCLUDES by AM_CPPFLAGS. - -2004-01-05 Werner Koch <wk@gnupg.org> - - * argparse.c (strusage): Changed default copyright year to 2004. - -2003-12-17 Werner Koch <wk@gnupg.org> - - * argparse.c (initialize): Replaced use of non-literal format - args. Suggested by Florian Weimer. - -2003-12-16 Werner Koch <wk@gnupg.org> - - * logging.c (writen, fun_writer, fun_closer): New. - (log_set_file): Add feature to log to a socket. - (log_set_file, do_logv): Force printing with prefix and pid. - -2003-11-13 Werner Koch <wk@gnupg.org> - - * strlist.c (strlist_copy): New. - - * dotlock.c: Define DIRSEP_C et al. if not defined. - -2003-11-06 Werner Koch <wk@gnupg.org> - - * strlist.h (strlist_t): New. STRLIST is now deprecated. - -2003-06-18 Werner Koch <wk@gnupg.org> - - * strlist.c (strlist_pop): New. - - * dotlock.c (dotlock_remove_lockfiles): Prefixed with dotlock_ and - made global. - -2003-06-17 Werner Koch <wk@gnupg.org> - - * stringhelp.c (length_sans_trailing_chars) - (length_sans_trailing_ws): New. - - * logging.c (log_inc_errorcount): New. - - * stringhelp.c (print_sanitized_utf8_buffer): Implement utf8 - conversion. - (sanitize_buffer): New. Based on gnupg 1.3.2 make_printable_string. - - * dotlock.c: Updated to match the version from 1.3.2 - * utf8conv.c: New. Code taken from strgutil.c of gnupg 1.3.2. - * utf8conv.h: New. - -2003-06-16 Werner Koch <wk@gnupg.org> - - * logging.c (do_logv): Hack to optionally suppress a leading space. - - * stringhelp.c (ascii_strncasecmp): New. Taken from gnupg 1.3. - (ascii_memistr): New. Taken from gnupg 1.3 - -2003-06-13 Werner Koch <wk@gnupg.org> - - * mischelp.h (wipememory2,wipememory): New. Taken from GnuPG 1.3.2. - -2002-06-04 Werner Koch <wk@gnupg.org> - - * stringhelp.c (print_sanitized_utf8_string): New. No real - implementation for now. - (print_sanitized_utf8_buffer): Ditto. - -2002-04-04 Werner Koch <wk@gnupg.org> - - * logging.c (log_get_prefix): New. - -2002-03-15 Werner Koch <wk@gnupg.org> - - * argparse.c (optfile_parse): Fixed missing argument handling. - -2002-02-25 Werner Koch <wk@gnupg.org> - - * stringhelp.c (ascii_memcasemem): New. - -2002-02-14 Werner Koch <wk@gnupg.org> - - * Makefile.am (INCLUDES): Add cflags for libgcrypt. - -2002-02-07 Werner Koch <wk@gnupg.org> - - * logging.c (log_set_fd): New. - - * stringhelp.c (print_sanitized_buffer): New. - (print_sanitized_string): New. - -2002-01-24 Werner Koch <wk@gnupg.org> - - * argparse.c (strusage): Set default copyright notice year to 2002. - - Fixed the copyright notice of this file, as it has always been - part of GnuPG and therefore belongs to the FSF. - -2001-11-01 Marcus Brinkmann <marcus@g10code.de> - - * logging.c (log_printf): Do not initialize ARG_PTR with 0, we - don't know the correct type. Instead, run va_start and va_end - unconditionally. - Reported by Jose Carlos Garcia Sogo <jsogo@debian.org>. - -2002-01-19 Werner Koch <wk@gnupg.org> - - * logging.c (log_get_stream): New. - -2001-12-05 Werner Koch <wk@gnupg.org> - - * logging.c (log_set_prefix): New. - (do_logv): Include prefix and pid only if enabled. Print time only - when explicitly enabled. - (log_logv): New. - * logging.h: Include log_logv() only when requested. - -2001-11-06 Werner Koch <wk@gnupg.org> - - * strlist.c, strlist.h: New. Taken from pgnupg/util/strgutil.c - -2001-08-30 Werner Koch <wk@gnupg.org> - - * logging.c (log_printf): Don't pass NULL instead of arg_ptr. - -2001-07-19 Werner Koch <wk@gnupg.org> - - * stringhelp.c (ascii_memistr,ascii_isupper,ascii_islower, - ascii_toupper,ascii_tolower, ascii_strcasecmp, ascii_memcasecmp): New. - -2000-07-26 10:02:51 Werner Koch (wk@habibti.openit.de) - - * stringhelp.c.: Add stdarg.h - * argparse.h: s/ulong/unsigned long/ although this should be defined - by types.h. - -2000-06-28 19:40:23 Werner Koch (wk@habibti.openit.de) - - * Makefile.am: Replaced second logging.c by .h - -2000-05-24 08:58:15 Werner Koch (wk@habibti.openit.de) - - * logging.c (log_get_errorcount): New. - -2000-05-24 08:44:47 Werner Koch (wk@habibti.openit.de) - - * stringhelp.c: Added a few filename related helper functions. - -2000-05-11 18:04:43 Werner Koch (wk@habibti.openit.de) - - * xmalloc.c (xstrcat2): Replaced stpcpy to quickly address W32 - problems. - -2000-05-02 19:43:38 Werner Koch (wk@habibti.openit.de) - - * xmalloc.c (xstrcat2): New. - -Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de> - - * README: New. - * Makefile.am: new. - * argparse.c argparse.h logging.c logging.h - mischelp.h stringhelp.c stringhelp.h xmalloc.c - xmalloc.h dotlock.c: Moved from ../util to here. - * dotlock.h: New. - * libjnlib-config.h: New. - - * logging.c (log_set_file): New. - (log_printf): New. - (do_logv): Add kludge to insert LFs. - - - *********************************************************** - * Please note that Jnlib is maintained as part of GnuPG. * - * You may find it source-copied in other packages. * - *********************************************************** - - Copyright 2000, 2001, 2002, 2003, 2004 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. diff --git a/jnlib/Makefile.am b/jnlib/Makefile.am deleted file mode 100644 index bad3c5a71..000000000 --- a/jnlib/Makefile.am +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (C) 1999, 2000, 2001, 2004 Feee Software Soundation, Inc. -# -# This file is part of GnuPG -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -EXTRA_DIST = README - -AM_CPPFLAGS = -I$(top_srcdir)/intl - -# We need libgcrypt because libjnlib-config includes gcrypt.h -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) - -noinst_LIBRARIES = libjnlib.a - - -#libjnlib_a_LDFLAGS = -libjnlib_a_SOURCES = \ - libjnlib-config.h \ - stringhelp.c stringhelp.h \ - strlist.c strlist.h \ - utf8conv.c utf8conv.h \ - argparse.c argparse.h \ - logging.c logging.h \ - dotlock.c dotlock.h \ - types.h mischelp.h - -# xmalloc.c xmalloc.h - diff --git a/jnlib/README b/jnlib/README deleted file mode 100644 index e49ef4450..000000000 --- a/jnlib/README +++ /dev/null @@ -1,7 +0,0 @@ -jnlib - this is a collection of utility function which are -too small to put into a library. - -libjnlib-config.h should be be modified for each project -to make these functions fit into the software. Mainly these -are memory functions in case you need another allocator. - diff --git a/jnlib/argparse.c b/jnlib/argparse.c deleted file mode 100644 index de828e8ce..000000000 --- a/jnlib/argparse.c +++ /dev/null @@ -1,999 +0,0 @@ -/* [argparse.c wk 17.06.97] Argument Parser for option handling - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <string.h> - -#include "libjnlib-config.h" -#include "mischelp.h" -#include "stringhelp.h" -#include "logging.h" -#include "argparse.h" - - -/********************************* - * @Summary arg_parse - * #include <wk/lib.h> - * - * typedef struct { - * char *argc; pointer to argc (value subject to change) - * char ***argv; pointer to argv (value subject to change) - * unsigned flags; Global flags (DO NOT CHANGE) - * int err; print error about last option - * 1 = warning, 2 = abort - * int r_opt; return option - * int r_type; type of return value (0 = no argument found) - * union { - * int ret_int; - * long ret_long - * ulong ret_ulong; - * char *ret_str; - * } r; Return values - * struct { - * int idx; - * const char *last; - * void *aliases; - * } internal; DO NOT CHANGE - * } ARGPARSE_ARGS; - * - * typedef struct { - * int short_opt; - * const char *long_opt; - * unsigned flags; - * } ARGPARSE_OPTS; - * - * int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts ); - * - * @Description - * This is my replacement for getopt(). See the example for a typical usage. - * Global flags are: - * Bit 0 : Do not remove options form argv - * Bit 1 : Do not stop at last option but return other args - * with r_opt set to -1. - * Bit 2 : Assume options and real args are mixed. - * Bit 3 : Do not use -- to stop option processing. - * Bit 4 : Do not skip the first arg. - * Bit 5 : allow usage of long option with only one dash - * Bit 6 : ignore --version - * all other bits must be set to zero, this value is modified by the - * function, so assume this is write only. - * Local flags (for each option): - * Bit 2-0 : 0 = does not take an argument - * 1 = takes int argument - * 2 = takes string argument - * 3 = takes long argument - * 4 = takes ulong argument - * Bit 3 : argument is optional (r_type will the be set to 0) - * Bit 4 : allow 0x etc. prefixed values. - * Bit 7 : this is a command and not an option - * You stop the option processing by setting opts to NULL, the function will - * then return 0. - * @Return Value - * Returns the args.r_opt or 0 if ready - * r_opt may be -2/-7 to indicate an unknown option/command. - * @See Also - * ArgExpand - * @Notes - * You do not need to process the options 'h', '--help' or '--version' - * because this function includes standard help processing; but if you - * specify '-h', '--help' or '--version' you have to do it yourself. - * The option '--' stops argument processing; if bit 1 is set the function - * continues to return normal arguments. - * To process float args or unsigned args you must use a string args and do - * the conversion yourself. - * @Example - * - * ARGPARSE_OPTS opts[] = { - * { 'v', "verbose", 0 }, - * { 'd', "debug", 0 }, - * { 'o', "output", 2 }, - * { 'c', "cross-ref", 2|8 }, - * { 'm', "my-option", 1|8 }, - * { 500, "have-no-short-option-for-this-long-option", 0 }, - * {0} }; - * ARGPARSE_ARGS pargs = { &argc, &argv, 0 } - * - * while( ArgParse( &pargs, &opts) ) { - * switch( pargs.r_opt ) { - * case 'v': opt.verbose++; break; - * case 'd': opt.debug++; break; - * case 'o': opt.outfile = pargs.r.ret_str; break; - * case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break; - * case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break; - * case 500: opt.a_long_one++; break - * default : pargs.err = 1; break; -- force warning output -- - * } - * } - * if( argc > 1 ) - * log_fatal( "Too many args"); - * - */ - -typedef struct alias_def_s *ALIAS_DEF; -struct alias_def_s { - ALIAS_DEF next; - char *name; /* malloced buffer with name, \0, value */ - const char *value; /* ptr into name */ -}; - -static const char *(*strusage_handler)( int ) = NULL; - -static int set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s); -static void show_help(ARGPARSE_OPTS *opts, unsigned flags); -static void show_version(void); - - -static void -initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno ) -{ - if( !(arg->flags & (1<<15)) ) { /* initialize this instance */ - arg->internal.idx = 0; - arg->internal.last = NULL; - arg->internal.inarg = 0; - arg->internal.stopped = 0; - arg->internal.aliases = NULL; - arg->internal.cur_alias = NULL; - arg->err = 0; - arg->flags |= 1<<15; /* mark initialized */ - if( *arg->argc < 0 ) - jnlib_log_bug("Invalid argument for ArgParse\n"); - } - - - if( arg->err ) { /* last option was erroneous */ - const char *s; - - if( filename ) { - if( arg->r_opt == -6 ) - s = "argument not expected\n"; - else if( arg->r_opt == -5 ) - s = "read error\n"; - else if( arg->r_opt == -4 ) - s = "keyword too long\n"; - else if( arg->r_opt == -3 ) - s = "missing argument\n"; - else if( arg->r_opt == -7 ) - s = "invalid command\n"; - else if( arg->r_opt == -10 ) - s = "invalid alias definition\n"; - else - s = "invalid option\n"; - jnlib_log_error("%s:%u: %s\n", filename, *lineno, s); - } - else { - s = arg->internal.last? arg->internal.last:"[??]"; - - if( arg->r_opt == -3 ) - jnlib_log_error ("Missing argument for option \"%.50s\"\n", s); - else if( arg->r_opt == -6 ) - jnlib_log_error ("Option \"%.50s\" does not expect an argument\n", - s ); - else if( arg->r_opt == -7 ) - jnlib_log_error ("Invalid command \"%.50s\"\n", s); - else if( arg->r_opt == -8 ) - jnlib_log_error ("Option \"%.50s\" is ambiguous\n", s); - else if( arg->r_opt == -9 ) - jnlib_log_error ("Command \"%.50s\" is ambiguous\n",s ); - else - jnlib_log_error ("Invalid option \"%.50s\"\n", s); - } - if( arg->err != 1 ) - exit(2); - arg->err = 0; - } - - /* clearout the return value union */ - arg->r.ret_str = NULL; - arg->r.ret_long= 0; -} - - -static void -store_alias( ARGPARSE_ARGS *arg, char *name, char *value ) -{ - /* TODO: replace this dummy function with a rea one - * and fix the probelms IRIX has with (ALIAS_DEV)arg.. - * used as lvalue - */ -#if 0 - ALIAS_DEF a = jnlib_xmalloc( sizeof *a ); - a->name = name; - a->value = value; - a->next = (ALIAS_DEF)arg->internal.aliases; - (ALIAS_DEF)arg->internal.aliases = a; -#endif -} - -/**************** - * Get options from a file. - * Lines starting with '#' are comment lines. - * Syntax is simply a keyword and the argument. - * Valid keywords are all keywords from the long_opt list without - * the leading dashes. The special keywords "help", "warranty" and "version" - * are not valid here. - * The special keyword "alias" may be used to store alias definitions, - * which are later expanded like long options. - * Caller must free returned strings. - * If called with FP set to NULL command line args are parse instead. - * - * Q: Should we allow the syntax - * keyword = value - * and accept for boolean options a value of 1/0, yes/no or true/false? - * Note: Abbreviation of options is here not allowed. - */ -int -optfile_parse( FILE *fp, const char *filename, unsigned *lineno, - ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts) -{ - int state, i, c; - int idx=0; - char keyword[100]; - char *buffer = NULL; - size_t buflen = 0; - int inverse=0; - int in_alias=0; - - if( !fp ) /* same as arg_parse() in this case */ - return arg_parse( arg, opts ); - - initialize( arg, filename, lineno ); - - /* find the next keyword */ - state = i = 0; - for(;;) { - c=getc(fp); - if( c == '\n' || c== EOF ) { - if( c != EOF ) - ++*lineno; - if( state == -1 ) - break; - else if( state == 2 ) { - keyword[i] = 0; - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) ) - break; - idx = i; - arg->r_opt = opts[idx].short_opt; - if( inverse ) /* this does not have an effect, hmmm */ - arg->r_opt = -arg->r_opt; - if( !opts[idx].short_opt ) /* unknown command/option */ - arg->r_opt = (opts[idx].flags & 256)? -7:-2; - else if( !(opts[idx].flags & 7) ) /* does not take an arg */ - arg->r_type = 0; /* okay */ - else if( (opts[idx].flags & 8) ) /* argument is optional */ - arg->r_type = 0; /* okay */ - else /* required argument */ - arg->r_opt = -3; /* error */ - break; - } - else if( state == 3 ) { /* no argument found */ - if( in_alias ) - arg->r_opt = -3; /* error */ - else if( !(opts[idx].flags & 7) ) /* does not take an arg */ - arg->r_type = 0; /* okay */ - else if( (opts[idx].flags & 8) ) /* no optional argument */ - arg->r_type = 0; /* okay */ - else /* no required argument */ - arg->r_opt = -3; /* error */ - break; - } - else if( state == 4 ) { /* have an argument */ - if( in_alias ) { - if( !buffer ) - arg->r_opt = -6; - else { - char *p; - - buffer[i] = 0; - p = strpbrk( buffer, " \t" ); - if( p ) { - *p++ = 0; - trim_spaces( p ); - } - if( !p || !*p ) { - jnlib_free( buffer ); - arg->r_opt = -10; - } - else { - store_alias( arg, buffer, p ); - } - } - } - else if( !(opts[idx].flags & 7) ) /* does not take an arg */ - arg->r_opt = -6; /* error */ - else { - char *p; - if( !buffer ) { - keyword[i] = 0; - buffer = jnlib_xstrdup(keyword); - } - else - buffer[i] = 0; - - trim_spaces( buffer ); - p = buffer; - if( *p == '"' ) { /* remove quotes */ - p++; - if( *p && p[strlen(p)-1] == '"' ) - p[strlen(p)-1] = 0; - } - if( !set_opt_arg(arg, opts[idx].flags, p) ) - jnlib_free(buffer); - } - break; - } - else if( c == EOF ) { - if( ferror(fp) ) - arg->r_opt = -5; /* read error */ - else - arg->r_opt = 0; /* eof */ - break; - } - state = 0; - i = 0; - } - else if( state == -1 ) - ; /* skip */ - else if( !state && isspace(c) ) - ; /* skip leading white space */ - else if( !state && c == '#' ) - state = 1; /* start of a comment */ - else if( state == 1 ) - ; /* skip comments */ - else if( state == 2 && isspace(c) ) { - keyword[i] = 0; - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) ) - break; - idx = i; - arg->r_opt = opts[idx].short_opt; - if( !opts[idx].short_opt ) { - if( !strcmp( keyword, "alias" ) ) { - in_alias = 1; - state = 3; - } - else { - arg->r_opt = (opts[idx].flags & 256)? -7:-2; - state = -1; /* skip rest of line and leave */ - } - } - else - state = 3; - } - else if( state == 3 ) { /* skip leading spaces of the argument */ - if( !isspace(c) ) { - i = 0; - keyword[i++] = c; - state = 4; - } - } - else if( state == 4 ) { /* collect the argument */ - if( buffer ) { - if( i < buflen-1 ) - buffer[i++] = c; - else { - buflen += 50; - buffer = jnlib_xrealloc(buffer, buflen); - buffer[i++] = c; - } - } - else if( i < DIM(keyword)-1 ) - keyword[i++] = c; - else { - buflen = DIM(keyword)+50; - buffer = jnlib_xmalloc(buflen); - memcpy(buffer, keyword, i); - buffer[i++] = c; - } - } - else if( i >= DIM(keyword)-1 ) { - arg->r_opt = -4; /* keyword to long */ - state = -1; /* skip rest of line and leave */ - } - else { - keyword[i++] = c; - state = 2; - } - } - - return arg->r_opt; -} - - - -static int -find_long_option( ARGPARSE_ARGS *arg, - ARGPARSE_OPTS *opts, const char *keyword ) -{ - int i; - size_t n; - - /* Would be better if we can do a binary search, but it is not - possible to reorder our option table because we would mess - up our help strings - What we can do is: Build a nice option - lookup table wehn this function is first invoked */ - if( !*keyword ) - return -1; - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) ) - return i; - #if 0 - { - ALIAS_DEF a; - /* see whether it is an alias */ - for( a = args->internal.aliases; a; a = a->next ) { - if( !strcmp( a->name, keyword) ) { - /* todo: must parse the alias here */ - args->internal.cur_alias = a; - return -3; /* alias available */ - } - } - } - #endif - /* not found, see whether it is an abbreviation */ - /* aliases may not be abbreviated */ - n = strlen( keyword ); - for(i=0; opts[i].short_opt; i++ ) { - if( opts[i].long_opt && !strncmp( opts[i].long_opt, keyword, n ) ) { - int j; - for(j=i+1; opts[j].short_opt; j++ ) { - if( opts[j].long_opt - && !strncmp( opts[j].long_opt, keyword, n ) ) - return -2; /* abbreviation is ambiguous */ - } - return i; - } - } - return -1; -} - -int -arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts) -{ - int idx; - int argc; - char **argv; - char *s, *s2; - int i; - - initialize( arg, NULL, NULL ); - argc = *arg->argc; - argv = *arg->argv; - idx = arg->internal.idx; - - if( !idx && argc && !(arg->flags & (1<<4)) ) { /* skip the first entry */ - argc--; argv++; idx++; - } - - next_one: - if( !argc ) { /* no more args */ - arg->r_opt = 0; - goto leave; /* ready */ - } - - s = *argv; - arg->internal.last = s; - - if( arg->internal.stopped && (arg->flags & (1<<1)) ) { - arg->r_opt = -1; /* not an option but a argument */ - arg->r_type = 2; - arg->r.ret_str = s; - argc--; argv++; idx++; /* set to next one */ - } - else if( arg->internal.stopped ) { /* ready */ - arg->r_opt = 0; - goto leave; - } - else if( *s == '-' && s[1] == '-' ) { /* long option */ - char *argpos; - - arg->internal.inarg = 0; - if( !s[2] && !(arg->flags & (1<<3)) ) { /* stop option processing */ - arg->internal.stopped = 1; - argc--; argv++; idx++; - goto next_one; - } - - argpos = strchr( s+2, '=' ); - if( argpos ) - *argpos = 0; - i = find_long_option( arg, opts, s+2 ); - if( argpos ) - *argpos = '='; - - if( i < 0 && !strcmp( "help", s+2) ) - show_help(opts, arg->flags); - else if( i < 0 && !strcmp( "version", s+2) ) { - if( !(arg->flags & (1<<6)) ) { - show_version(); - exit(0); - } - } - else if( i < 0 && !strcmp( "warranty", s+2) ) { - puts( strusage(16) ); - exit(0); - } - else if( i < 0 && !strcmp( "dump-options", s+2) ) { - for(i=0; opts[i].short_opt; i++ ) { - if( opts[i].long_opt ) - printf( "--%s\n", opts[i].long_opt ); - } - fputs("--dump-options\n--help\n--version\n--warranty\n", stdout ); - exit(0); - } - - if( i == -2 ) /* ambiguous option */ - arg->r_opt = -8; - else if( i == -1 ) { - arg->r_opt = -2; - arg->r.ret_str = s+2; - } - else - arg->r_opt = opts[i].short_opt; - if( i < 0 ) - ; - else if( (opts[i].flags & 7) ) { - if( argpos ) { - s2 = argpos+1; - if( !*s2 ) - s2 = NULL; - } - else - s2 = argv[1]; - if( !s2 && (opts[i].flags & 8) ) { /* no argument but it is okay*/ - arg->r_type = 0; /* because it is optional */ - } - else if( !s2 ) { - arg->r_opt = -3; /* missing argument */ - } - else if( !argpos && *s2 == '-' && (opts[i].flags & 8) ) { - /* the argument is optional and the next seems to be - * an option. We do not check this possible option - * but assume no argument */ - arg->r_type = 0; - } - else { - set_opt_arg(arg, opts[i].flags, s2); - if( !argpos ) { - argc--; argv++; idx++; /* skip one */ - } - } - } - else { /* does not take an argument */ - if( argpos ) - arg->r_type = -6; /* argument not expected */ - else - arg->r_type = 0; - } - argc--; argv++; idx++; /* set to next one */ - } - else if( (*s == '-' && s[1]) || arg->internal.inarg ) { /* short option */ - int dash_kludge = 0; - i = 0; - if( !arg->internal.inarg ) { - arg->internal.inarg++; - if( arg->flags & (1<<5) ) { - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, s+1)) { - dash_kludge=1; - break; - } - } - } - s += arg->internal.inarg; - - if( !dash_kludge ) { - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].short_opt == *s ) - break; - } - - if( !opts[i].short_opt && ( *s == 'h' || *s == '?' ) ) - show_help(opts, arg->flags); - - arg->r_opt = opts[i].short_opt; - if( !opts[i].short_opt ) { - arg->r_opt = (opts[i].flags & 256)? -7:-2; - arg->internal.inarg++; /* point to the next arg */ - arg->r.ret_str = s; - } - else if( (opts[i].flags & 7) ) { - if( s[1] && !dash_kludge ) { - s2 = s+1; - set_opt_arg(arg, opts[i].flags, s2); - } - else { - s2 = argv[1]; - if( !s2 && (opts[i].flags & 8) ) { /* no argument but it is okay*/ - arg->r_type = 0; /* because it is optional */ - } - else if( !s2 ) { - arg->r_opt = -3; /* missing argument */ - } - else if( *s2 == '-' && s2[1] && (opts[i].flags & 8) ) { - /* the argument is optional and the next seems to be - * an option. We do not check this possible option - * but assume no argument */ - arg->r_type = 0; - } - else { - set_opt_arg(arg, opts[i].flags, s2); - argc--; argv++; idx++; /* skip one */ - } - } - s = "x"; /* so that !s[1] yields false */ - } - else { /* does not take an argument */ - arg->r_type = 0; - arg->internal.inarg++; /* point to the next arg */ - } - if( !s[1] || dash_kludge ) { /* no more concatenated short options */ - arg->internal.inarg = 0; - argc--; argv++; idx++; - } - } - else if( arg->flags & (1<<2) ) { - arg->r_opt = -1; /* not an option but a argument */ - arg->r_type = 2; - arg->r.ret_str = s; - argc--; argv++; idx++; /* set to next one */ - } - else { - arg->internal.stopped = 1; /* stop option processing */ - goto next_one; - } - - leave: - *arg->argc = argc; - *arg->argv = argv; - arg->internal.idx = idx; - return arg->r_opt; -} - - - -static int -set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s) -{ - int base = (flags & 16)? 0 : 10; - - switch( arg->r_type = (flags & 7) ) { - case 1: /* takes int argument */ - arg->r.ret_int = (int)strtol(s,NULL,base); - return 0; - case 3: /* takes long argument */ - arg->r.ret_long= strtol(s,NULL,base); - return 0; - case 4: /* takes ulong argument */ - arg->r.ret_ulong= strtoul(s,NULL,base); - return 0; - case 2: /* takes string argument */ - default: - arg->r.ret_str = s; - return 1; - } -} - - -static size_t -long_opt_strlen( ARGPARSE_OPTS *o ) -{ - size_t n = strlen(o->long_opt); - - if( o->description && *o->description == '|' ) { - const char *s; - - s=o->description+1; - if( *s != '=' ) - n++; - for(; *s && *s != '|'; s++ ) - n++; - } - return n; -} - -/**************** - * Print formatted help. The description string has some special - * meanings: - * - A description string which is "@" suppresses help output for - * this option - * - a description,ine which starts with a '@' and is followed by - * any other characters is printed as is; this may be used for examples - * ans such. - * - A description which starts with a '|' outputs the string between this - * bar and the next one as arguments of the long option. - */ -static void -show_help( ARGPARSE_OPTS *opts, unsigned flags ) -{ - const char *s; - - show_version(); - putchar('\n'); - s = strusage(41); - puts(s); - if( opts[0].description ) { /* auto format the option description */ - int i,j, indent; - /* get max. length of long options */ - for(i=indent=0; opts[i].short_opt; i++ ) { - if( opts[i].long_opt ) - if( !opts[i].description || *opts[i].description != '@' ) - if( (j=long_opt_strlen(opts+i)) > indent && j < 35 ) - indent = j; - } - /* example: " -v, --verbose Viele Sachen ausgeben" */ - indent += 10; - if( *opts[0].description != '@' ) - puts("Options:"); - for(i=0; opts[i].short_opt; i++ ) { - s = _( opts[i].description ); - if( s && *s== '@' && !s[1] ) /* hide this line */ - continue; - if( s && *s == '@' ) { /* unindented comment only line */ - for(s++; *s; s++ ) { - if( *s == '\n' ) { - if( s[1] ) - putchar('\n'); - } - else - putchar(*s); - } - putchar('\n'); - continue; - } - - j = 3; - if( opts[i].short_opt < 256 ) { - printf(" -%c", opts[i].short_opt ); - if( !opts[i].long_opt ) { - if(s && *s == '|' ) { - putchar(' '); j++; - for(s++ ; *s && *s != '|'; s++, j++ ) - putchar(*s); - if( *s ) - s++; - } - } - } - else - fputs(" ", stdout); - if( opts[i].long_opt ) { - j += printf("%c --%s", opts[i].short_opt < 256?',':' ', - opts[i].long_opt ); - if(s && *s == '|' ) { - if( *++s != '=' ) { - putchar(' '); - j++; - } - for( ; *s && *s != '|'; s++, j++ ) - putchar(*s); - if( *s ) - s++; - } - fputs(" ", stdout); - j += 3; - } - for(;j < indent; j++ ) - putchar(' '); - if( s ) { - if( *s && j > indent ) { - putchar('\n'); - for(j=0;j < indent; j++ ) - putchar(' '); - } - for(; *s; s++ ) { - if( *s == '\n' ) { - if( s[1] ) { - putchar('\n'); - for(j=0;j < indent; j++ ) - putchar(' '); - } - } - else - putchar(*s); - } - } - putchar('\n'); - } - if( flags & 32 ) - puts("\n(A single dash may be used instead of the double ones)"); - } - if( (s=strusage(19)) ) { /* bug reports to ... */ - putchar('\n'); - fputs(s, stdout); - } - fflush(stdout); - exit(0); -} - -static void -show_version() -{ - const char *s; - int i; - /* version line */ - fputs(strusage(11), stdout); - if( (s=strusage(12)) ) - printf(" (%s)", s ); - printf(" %s\n", strusage(13) ); - /* additional version lines */ - for(i=20; i < 30; i++ ) - if( (s=strusage(i)) ) - printf("%s\n", s ); - /* copyright string */ - if( (s=strusage(14)) ) - printf("%s\n", s ); - /* copying conditions */ - if( (s=strusage(15)) ) - fputs(s, stdout); - /* thanks */ - if( (s=strusage(18)) ) - fputs(s, stdout); - /* additional program info */ - for(i=30; i < 40; i++ ) - if( (s=strusage(i)) ) - fputs( (const byte*)s, stdout); - fflush(stdout); -} - - -void -usage( int level ) -{ - if( !level ) { - fprintf(stderr,"%s %s; %s\n", strusage(11), strusage(13), - strusage(14) ); - fflush(stderr); - } - else if( level == 1 ) { - fputs(strusage(40),stderr); - exit(2); - } - else if( level == 2 ) { - puts(strusage(41)); - exit(0); - } -} - -/* Level - * 0: Copyright String auf stderr ausgeben - * 1: Kurzusage auf stderr ausgeben und beenden - * 2: Langusage auf stdout ausgeben und beenden - * 11: name of program - * 12: optional name of package which includes this program. - * 13: version string - * 14: copyright string - * 15: Short copying conditions (with LFs) - * 16: Long copying conditions (with LFs) - * 17: Optional printable OS name - * 18: Optional thanks list (with LFs) - * 19: Bug report info - *20..29: Additional lib version strings. - *30..39: Additional program info (with LFs) - * 40: short usage note (with LF) - * 41: long usage note (with LF) - */ -const char * -strusage( int level ) -{ - const char *p = strusage_handler? strusage_handler(level) : NULL; - - if( p ) - return p; - - switch( level ) { - case 11: p = "foo"; break; - case 13: p = "0.0"; break; - case 14: p = "Copyright (C) 2004 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" -"under certain conditions. See the file COPYING for details.\n"; break; - case 16: p = -"This is free software; you can redistribute it and/or modify\n" -"it under the terms of the GNU General Public License as published by\n" -"the Free Software Foundation; either version 2 of the License, or\n" -"(at your option) any later version.\n\n" -"It is distributed in the hope that it will be useful,\n" -"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" -"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" -"GNU General Public License for more details.\n\n" -"You should have received a copy of the GNU General Public License\n" -"along with this program; if not, write to the Free Software\n" -"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"; - break; - case 40: /* short and long usage */ - case 41: p = ""; break; - } - - return p; -} - -void -set_strusage( const char *(*f)( int ) ) -{ - strusage_handler = f; -} - - -#ifdef TEST -static struct { - int verbose; - int debug; - char *outfile; - char *crf; - int myopt; - int echo; - int a_long_one; -}opt; - -int -main(int argc, char **argv) -{ - ARGPARSE_OPTS opts[] = { - { 'v', "verbose", 0 , "Laut sein"}, - { 'e', "echo" , 0 , "Zeile ausgeben, damit wir sehen, was wir einegegeben haben"}, - { 'd', "debug", 0 , "Debug\nfalls mal etasws\nSchief geht"}, - { 'o', "output", 2 }, - { 'c', "cross-ref", 2|8, "cross-reference erzeugen\n" }, - { 'm', "my-option", 1|8 }, - { 500, "a-long-option", 0 }, - {0} }; - ARGPARSE_ARGS pargs = { &argc, &argv, 2|4|32 }; - int i; - - while( ArgParse( &pargs, opts) ) { - switch( pargs.r_opt ) { - case -1 : printf( "arg=`%s'\n", pargs.r.ret_str); break; - case 'v': opt.verbose++; break; - case 'e': opt.echo++; break; - case 'd': opt.debug++; break; - case 'o': opt.outfile = pargs.r.ret_str; break; - case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break; - case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break; - case 500: opt.a_long_one++; break; - default : pargs.err = 1; break; /* force warning output */ - } - } - for(i=0; i < argc; i++ ) - printf("%3d -> (%s)\n", i, argv[i] ); - puts("Options:"); - if( opt.verbose ) - printf(" verbose=%d\n", opt.verbose ); - if( opt.debug ) - printf(" debug=%d\n", opt.debug ); - if( opt.outfile ) - printf(" outfile=`%s'\n", opt.outfile ); - if( opt.crf ) - printf(" crffile=`%s'\n", opt.crf ); - if( opt.myopt ) - printf(" myopt=%d\n", opt.myopt ); - if( opt.a_long_one ) - printf(" a-long-one=%d\n", opt.a_long_one ); - if( opt.echo ) - printf(" echo=%d\n", opt.echo ); - return 0; -} -#endif - -/**** bottom of file ****/ diff --git a/jnlib/argparse.h b/jnlib/argparse.h deleted file mode 100644 index e8922faa4..000000000 --- a/jnlib/argparse.h +++ /dev/null @@ -1,67 +0,0 @@ -/* argparse.h - * Copyright (C) 1998,1999,2000,2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_ARGPARSE_H -#define LIBJNLIB_ARGPARSE_H - -#include <stdio.h> -#include "types.h" - -typedef struct { - int *argc; /* pointer to argc (value subject to change) */ - char ***argv; /* pointer to argv (value subject to change) */ - unsigned flags; /* Global flags (DO NOT CHANGE) */ - int err; /* print error about last option */ - /* 1 = warning, 2 = abort */ - int r_opt; /* return option */ - int r_type; /* type of return value (0 = no argument found)*/ - union { - int ret_int; - long ret_long; - unsigned long ret_ulong; - char *ret_str; - } r; /* Return values */ - struct { - int idx; - int inarg; - int stopped; - const char *last; - void *aliases; - const void *cur_alias; - } internal; /* DO NOT CHANGE */ -} ARGPARSE_ARGS; - -typedef struct { - int short_opt; - const char *long_opt; - unsigned flags; - const char *description; /* optional option description */ -} ARGPARSE_OPTS; - - - -int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); -int optfile_parse( FILE *fp, const char *filename, unsigned *lineno, - ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); -void usage( int level ); -const char *strusage( int level ); -void set_strusage( const char *(*f)( int ) ); - -#endif /*LIBJNLIB_ARGPARSE_H*/ diff --git a/jnlib/dotlock.c b/jnlib/dotlock.c deleted file mode 100644 index a50a0ee99..000000000 --- a/jnlib/dotlock.c +++ /dev/null @@ -1,436 +0,0 @@ -/* dotlock.c - dotfile locking - * Copyright (C) 1998,2000,2001,2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <ctype.h> -#include <errno.h> -#include <unistd.h> -#ifndef HAVE_DOSISH_SYSTEM -#include <sys/utsname.h> -#endif -#include <sys/types.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> - -#include "libjnlib-config.h" -#include "dotlock.h" - -#if !defined(DIRSEP_C) && !defined(EXTSEP_C) \ - && !defined(DIRSEP_S) && !defined(EXTSEP_S) -#ifdef HAVE_DOSISH_SYSTEM -#define DIRSEP_C '\\' -#define EXTSEP_C '.' -#define DIRSEP_S "\\" -#define EXTSEP_S "." -#else -#define DIRSEP_C '/' -#define EXTSEP_C '.' -#define DIRSEP_S "/" -#define EXTSEP_S "." -#endif -#endif - - -struct dotlock_handle { - struct dotlock_handle *next; - char *tname; /* name of lockfile template */ - char *lockname; /* name of the real lockfile */ - int locked; /* lock status */ - int disable; /* locking */ -}; - - -static volatile DOTLOCK all_lockfiles; -static int never_lock; - -static int read_lockfile( const char *name ); - -void -disable_dotlock(void) -{ - never_lock = 1; -} - -/**************** - * Create a lockfile with the given name and return an object of - * type DOTLOCK which may be used later to actually do the lock. - * A cleanup routine gets installed to cleanup left over locks - * or other files used together with the lockmechanism. - * Althoug the function is called dotlock, this does not necessarily - * mean that real lockfiles are used - the function may decide to - * use fcntl locking. Calling the function with NULL only install - * the atexit handler and maybe used to assure that the cleanup - * is called after all other atexit handlers. - * - * Notes: This function creates a lock file in the same directory - * as file_to_lock with the name "file_to_lock.lock" - * A temporary file ".#lk.<hostname>.pid[.threadid] is used. - * This function does nothing for Windoze. - */ -DOTLOCK -create_dotlock( const char *file_to_lock ) -{ - static int initialized; - DOTLOCK h; - int fd = -1; - char pidstr[16]; - #ifndef HAVE_DOSISH_SYSTEM - struct utsname utsbuf; - #endif - const char *nodename; - const char *dirpart; - int dirpartlen; - - if( !initialized ) { - atexit( dotlock_remove_lockfiles ); - initialized = 1; - } - if( !file_to_lock ) - return NULL; - - h = jnlib_xcalloc( 1, sizeof *h ); - if( never_lock ) { - h->disable = 1; -#ifdef _REENTRANT - /* fixme: aquire mutex on all_lockfiles */ -#endif - h->next = all_lockfiles; - all_lockfiles = h; - return h; - } - -#ifndef HAVE_DOSISH_SYSTEM - sprintf( pidstr, "%10d\n", (int)getpid() ); - /* fixme: add the hostname to the second line (FQDN or IP addr?) */ - - /* create a temporary file */ - if( uname( &utsbuf ) ) - nodename = "unknown"; - else - nodename = utsbuf.nodename; - -#ifdef __riscos__ - { - char *iter = (char *) nodename; - for (; iter[0]; iter++) - if (iter[0] == '.') - iter[0] = '/'; - } -#endif /* __riscos__ */ - - if( !(dirpart = strrchr( file_to_lock, DIRSEP_C )) ) { - dirpart = EXTSEP_S; - dirpartlen = 1; - } - else { - dirpartlen = dirpart - file_to_lock; - dirpart = file_to_lock; - } - - #ifdef _REENTRANT - /* fixme: aquire mutex on all_lockfiles */ - #endif - h->next = all_lockfiles; - all_lockfiles = h; - - h->tname = jnlib_xmalloc( dirpartlen + 6+30+ strlen(nodename) + 11 ); -#ifndef __riscos__ - sprintf( h->tname, "%.*s/.#lk%p.%s.%d", - dirpartlen, dirpart, h, nodename, (int)getpid() ); -#else /* __riscos__ */ - sprintf( h->tname, "%.*s.lk%p/%s/%d", - dirpartlen, dirpart, h, nodename, (int)getpid() ); -#endif /* __riscos__ */ - - do { - errno = 0; - fd = open( h->tname, O_WRONLY|O_CREAT|O_EXCL, - S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR ); - } while( fd == -1 && errno == EINTR ); - if( fd == -1 ) { - all_lockfiles = h->next; - log_error( "failed to create temporary file `%s': %s\n", - h->tname, strerror(errno)); - jnlib_free(h->tname); - jnlib_free(h); - return NULL; - } - if( write(fd, pidstr, 11 ) != 11 ) { - all_lockfiles = h->next; - #ifdef _REENTRANT - /* release mutex */ - #endif - log_fatal( "error writing to `%s': %s\n", h->tname, strerror(errno) ); - close(fd); - unlink(h->tname); - jnlib_free(h->tname); - jnlib_free(h); - return NULL; - } - if( close(fd) ) { - all_lockfiles = h->next; - #ifdef _REENTRANT - /* release mutex */ - #endif - log_fatal( "error writing to `%s': %s\n", h->tname, strerror(errno) ); - close(fd); - unlink(h->tname); - jnlib_free(h->tname); - jnlib_free(h); - return NULL; - } - - #ifdef _REENTRANT - /* release mutex */ - #endif -#endif /* !HAVE_DOSISH_SYSTEM */ - h->lockname = jnlib_xmalloc( strlen(file_to_lock) + 6 ); - strcpy(stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock"); - return h; -} - -static int -maybe_deadlock( DOTLOCK h ) -{ - DOTLOCK r; - - for( r=all_lockfiles; r; r = r->next ) { - if( r != h && r->locked ) - return 1; - } - return 0; -} - -/**************** - * Do a lock on H. A TIMEOUT of 0 returns immediately, - * -1 waits forever (hopefully not), other - * values are timeouts in milliseconds. - * Returns: 0 on success - */ -int -make_dotlock( DOTLOCK h, long timeout ) -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else - int pid; - const char *maybe_dead=""; - int backoff=0; - - if( h->disable ) { - return 0; - } - - if( h->locked ) { -#ifndef __riscos__ - log_debug("oops, `%s' is already locked\n", h->lockname ); -#endif /* !__riscos__ */ - return 0; - } - - for(;;) { -#ifndef __riscos__ - if( !link(h->tname, h->lockname) ) { - /* fixme: better use stat to check the link count */ - h->locked = 1; - return 0; /* okay */ - } - if( errno != EEXIST ) { - log_error( "lock not made: link() failed: %s\n", strerror(errno) ); - return -1; - } -#else /* __riscos__ */ - if( !renamefile(h->tname, h->lockname) ) { - h->locked = 1; - return 0; /* okay */ - } - if( errno != EEXIST ) { - log_error( "lock not made: rename() failed: %s\n", strerror(errno) ); - return -1; - } -#endif /* __riscos__ */ - if( (pid = read_lockfile(h->lockname)) == -1 ) { - if( errno != ENOENT ) { - log_info("cannot read lockfile\n"); - return -1; - } - log_info( "lockfile disappeared\n"); - continue; - } - else if( pid == getpid() ) { - log_info( "Oops: lock already held by us\n"); - h->locked = 1; - return 0; /* okay */ - } - else if( kill(pid, 0) && errno == ESRCH ) { -#ifndef __riscos__ - maybe_dead = " - probably dead"; -#if 0 /* we should not do this without checking the permissions */ - /* and the hostname */ - log_info( "removing stale lockfile (created by %d)", pid ); -#endif -#else /* __riscos__ */ - /* we are *pretty* sure that the other task is dead and therefore - we remove the other lock file */ - maybe_dead = " - probably dead - removing lock"; - unlink(h->lockname); -#endif /* __riscos__ */ - } - if( timeout == -1 ) { - struct timeval tv; - log_info( "waiting for lock (held by %d%s) %s...\n", - pid, maybe_dead, maybe_deadlock(h)? "(deadlock?) ":""); - - - /* can't use sleep, cause signals may be blocked */ - tv.tv_sec = 1 + backoff; - tv.tv_usec = 0; - select(0, NULL, NULL, NULL, &tv); - if( backoff < 10 ) - backoff++ ; - } - else - return -1; - } - /*not reached */ -#endif /* !HAVE_DOSISH_SYSTEM */ -} - - -/**************** - * release a lock - * Returns: 0 := success - */ -int -release_dotlock( DOTLOCK h ) -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else - int pid; - - if( h->disable ) { - return 0; - } - - if( !h->locked ) { - log_debug("oops, `%s' is not locked\n", h->lockname ); - return 0; - } - - pid = read_lockfile( h->lockname ); - if( pid == -1 ) { - log_error( "release_dotlock: lockfile error\n"); - return -1; - } - if( pid != getpid() ) { - log_error( "release_dotlock: not our lock (pid=%d)\n", pid); - return -1; - } -#ifndef __riscos__ - if( unlink( h->lockname ) ) { - log_error( "release_dotlock: error removing lockfile `%s'", - h->lockname); - return -1; - } -#else /* __riscos__ */ - if( renamefile(h->lockname, h->tname) ) { - log_error( "release_dotlock: error renaming lockfile `%s' to `%s'", - h->lockname, h->tname); - return -1; - } -#endif /* __riscos__ */ - /* fixme: check that the link count is now 1 */ - h->locked = 0; - return 0; -#endif /* !HAVE_DOSISH_SYSTEM */ -} - - -/**************** - * Read the lock file and return the pid, returns -1 on error. - */ -static int -read_lockfile( const char *name ) -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else - int fd, pid; - char pidstr[16]; - - if( (fd = open(name, O_RDONLY)) == -1 ) { - int e = errno; - log_debug("error opening lockfile `%s': %s\n", name, strerror(errno) ); - errno = e; - return -1; - } - if( read(fd, pidstr, 10 ) != 10 ) { /* Read 10 digits w/o newline */ - log_debug("error reading lockfile `%s'", name ); - close(fd); - errno = 0; - return -1; - } - pidstr[10] = 0; /* terminate pid string */ - close(fd); - pid = atoi(pidstr); -#ifndef __riscos__ - if( !pid || pid == -1 ) { -#else /* __riscos__ */ - if( (!pid && riscos_getpid()) || pid == -1 ) { -#endif /* __riscos__ */ - log_error("invalid pid %d in lockfile `%s'", pid, name ); - errno = 0; - return -1; - } - return pid; -#endif -} - - -void -dotlock_remove_lockfiles() -{ -#ifndef HAVE_DOSISH_SYSTEM - DOTLOCK h, h2; - - h = all_lockfiles; - all_lockfiles = NULL; - - while( h ) { - h2 = h->next; - if (!h->disable ) { - if( h->locked ) - unlink( h->lockname ); - unlink(h->tname); - jnlib_free(h->tname); - jnlib_free(h->lockname); - } - jnlib_free(h); - h = h2; - } -#endif -} - diff --git a/jnlib/dotlock.h b/jnlib/dotlock.h deleted file mode 100644 index 9235687df..000000000 --- a/jnlib/dotlock.h +++ /dev/null @@ -1,36 +0,0 @@ -/* dotlock.h - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_DOTLOCK_H -#define LIBJNLIB_DOTLOCK_H - -struct dotlock_handle; -typedef struct dotlock_handle *DOTLOCK; - -void disable_dotlock (void); -DOTLOCK create_dotlock(const char *file_to_lock); -int make_dotlock (DOTLOCK h, long timeout); -int release_dotlock (DOTLOCK h); -void dotlock_remove_lockfiles (void); - -#endif /*LIBJNLIB_DOTLOCK_H*/ - - - diff --git a/jnlib/libjnlib-config.h b/jnlib/libjnlib-config.h deleted file mode 100644 index ad7e353fd..000000000 --- a/jnlib/libjnlib-config.h +++ /dev/null @@ -1,72 +0,0 @@ -/* libjnlib-config.h - local configuration of the jnlib functions - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/**************** - * This header is to be included only by the files in this directory - * it should not be used by other modules. - */ - -#ifndef LIBJNLIB_CONFIG_H -#define LIBJNLIB_CONFIG_H - -#include <gcrypt.h> /* gcry_malloc & Cie. */ -#include "logging.h" - -#ifdef USE_SIMPLE_GETTEXT - int set_gettext_file( const char *filename ); - const char *gettext( const char *msgid ); - - #define _(a) gettext (a) - #define N_(a) (a) - -#else -#ifdef HAVE_LOCALE_H - #include <locale.h> -#endif - -#ifdef ENABLE_NLS - #include <libintl.h> - #define _(a) gettext (a) - #ifdef gettext_noop - #define N_(a) gettext_noop (a) - #else - #define N_(a) (a) - #endif -#else - #define _(a) (a) - #define N_(a) (a) -#endif -#endif /* !USE_SIMPLE_GETTEXT */ - - -#define jnlib_xmalloc(a) gcry_xmalloc( (a) ) -#define jnlib_xcalloc(a,b) gcry_xcalloc( (a), (b) ) -#define jnlib_xrealloc(a,n) gcry_xrealloc( (a), (n) ) -#define jnlib_xstrdup(a) gcry_xstrdup( (a) ) -#define jnlib_free(a) gcry_free( (a) ) - -#define jnlib_log_debug log_debug -#define jnlib_log_info log_info -#define jnlib_log_error log_error -#define jnlib_log_fatal log_fatal -#define jnlib_log_bug log_bug - - -#endif /*LIBJNUTIL_CONFIG_H*/ diff --git a/jnlib/logging.c b/jnlib/logging.c deleted file mode 100644 index c75efaf85..000000000 --- a/jnlib/logging.c +++ /dev/null @@ -1,558 +0,0 @@ -/* logging.c - useful logging functions - * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -/* This file should replace logger.c in the future - for now it is not - * used by GnuPG but by GPA. - * It is a quite simple implemenation but sufficient for most purposes. - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stddef.h> -#include <errno.h> -#include <time.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <unistd.h> -#ifdef __MINGW32__ -# include <io.h> -#endif - -#define JNLIB_NEED_LOG_LOGV 1 -#include "libjnlib-config.h" -#include "logging.h" - - -static FILE *logstream; -static int log_socket = -1; -static char prefix_buffer[80]; -static int with_time; -static int with_prefix; -static int with_pid; -static int running_detached; -static int force_prefixes; - -static int missing_lf; -static int errorcount; - -#if 0 -static void -write2stderr( const char *s ) -{ - write( 2, s, strlen(s) ); -} - - -static void -do_die(int rc, const char *text ) -{ - write2stderr("\nFatal error: "); - write2stderr(text); - write2stderr("\n"); - abort(); -} -#endif - -int -log_get_errorcount (int clear) -{ - int n = errorcount; - if( clear ) - errorcount = 0; - return n; -} - -void -log_inc_errorcount (void) -{ - errorcount++; -} - - -/* The follwing 3 functions are used by funopen to write logs to a - socket. */ -#if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN) -struct fun_cookie_s { - int fd; - int quiet; - char name[1]; -}; - -/* Write NBYTES of BUF to file descriptor FD. */ -static int -writen (int fd, const unsigned char *buf, size_t nbytes) -{ - size_t nleft = nbytes; - int nwritten; - - while (nleft > 0) - { - nwritten = write (fd, buf, nleft); - if (nwritten < 0 && errno == EINTR) - continue; - if (nwritten < 0) - return -1; - nleft -= nwritten; - buf = buf + nwritten; - } - - return 0; -} - - -static int -fun_writer (void *cookie_arg, const char *buffer, size_t size) -{ - struct fun_cookie_s *cookie = cookie_arg; - - /* Note that we always try to reconnect to the socket but print - error messages only the first time an error occured. IF - RUNNING_DETACHED is set we don't fall back to stderr and even do - not print any error messages. This is needed becuase detached - processes often close stderr and my printing to fiel descriptor 2 - we might send the log message to a file not intended for logging - (e.g. a pipe or network connection). */ - if (cookie->fd == -1) - { - /* Note yet open or meanwhile closed due to an error. */ - struct sockaddr_un addr; - size_t addrlen; - - cookie->fd = socket (PF_LOCAL, SOCK_STREAM, 0); - if (cookie->fd == -1) - { - if (!cookie->quiet && !running_detached) - fprintf (stderr, "failed to create socket for logging: %s\n", - strerror(errno)); - goto failure; - } - log_socket = cookie->fd; - - memset (&addr, 0, sizeof addr); - addr.sun_family = PF_LOCAL; - strncpy (addr.sun_path, cookie->name, sizeof (addr.sun_path)-1); - addr.sun_path[sizeof (addr.sun_path)-1] = 0; - addrlen = (offsetof (struct sockaddr_un, sun_path) - + strlen (addr.sun_path) + 1); - - if (connect (cookie->fd, (struct sockaddr *) &addr, addrlen) == -1) - { - log_socket = -1; - if (!cookie->quiet && !running_detached) - fprintf (stderr, "can't connect to `%s': %s\n", - cookie->name, strerror(errno)); - close (cookie->fd); - cookie->fd = -1; - goto failure; - } - /* Connection established. */ - cookie->quiet = 0; - } - - if (!writen (cookie->fd, buffer, size)) - return size; /* Okay. */ - - log_socket = -1; - if (!running_detached) - fprintf (stderr, "error writing to `%s': %s\n", - cookie->name, strerror(errno)); - close (cookie->fd); - cookie->fd = -1; - - failure: - if (!running_detached) - { - if (!cookie->quiet) - { - fputs ("switching logging to stderr\n", stderr); - cookie->quiet = 1; - } - - fwrite (buffer, size, 1, stderr); - } - return size; -} - -static int -fun_closer (void *cookie_arg) -{ - struct fun_cookie_s *cookie = cookie_arg; - - if (cookie->fd != -1) - close (cookie->fd); - jnlib_free (cookie); - return 0; -} -#endif /* HAVE_FOPENCOOKIE || HAVE_FUNOPEN */ - - - - -/* Set the file to write log to. The special names NULL and "-" may - be used to select stderr and names formatted like - "socket:///home/foo/mylogs" may be used to write the logging to the - socket "/home/foo/mylogs". If the connection to the socket fails - or a write error is detected, the function writes to stderr and - tries the next time again to connect the socket. - */ -void -log_set_file (const char *name) -{ - FILE *fp; - - force_prefixes = 0; - if (name && !strncmp (name, "socket://", 9) && name[9]) - { -#if defined (HAVE_FOPENCOOKIE)|| defined (HAVE_FUNOPEN) - struct fun_cookie_s *cookie; - - cookie = jnlib_xmalloc (sizeof *cookie + strlen (name+9)); - cookie->fd = -1; - cookie->quiet = 0; - strcpy (cookie->name, name+9); - -#ifdef HAVE_FOPENCOOKIE - { - cookie_io_functions_t io = { NULL }; - io.write = fun_writer; - io.close = fun_closer; - - fp = fopencookie (cookie, "w", io); - } -#else /*!HAVE_FOPENCOOKIE*/ - { - fp = funopen (cookie, NULL, fun_writer, NULL, fun_closer); - } -#endif /*!HAVE_FOPENCOOKIE*/ -#else /* Neither fopencookie nor funopen. */ - { - fprintf (stderr, "system does not support logging to a socket - " - "using stderr\n"); - fp = stderr; - } -#endif /* Neither fopencookie nor funopen. */ - - /* We always need to print the prefix and the pid, so that the - server reading the socket can do something meanigful. */ - force_prefixes = 1; - /* On success close the old logstream right now, so that we are - really sure it has been closed. */ - if (fp && logstream) - { - fclose (logstream); - logstream = NULL; - } - } - else - fp = (name && strcmp(name,"-"))? fopen (name, "a") : stderr; - if (!fp) - { - fprintf (stderr, "failed to open log file `%s': %s\n", - name? name:"[stderr]", strerror(errno)); - return; - } - setvbuf (fp, NULL, _IOLBF, 0); - - if (logstream && logstream != stderr && logstream != stdout) - fclose (logstream); - logstream = fp; - missing_lf = 0; -} - - -void -log_set_fd (int fd) -{ - FILE *fp; - - force_prefixes = 0; - if (fd == 1) - fp = stdout; - else if (fd == 2) - fp = stderr; - else - fp = fdopen (fd, "a"); - if (!fp) - { - fprintf (stderr, "failed to fdopen log fd %d: %s\n", - fd, strerror(errno)); - return; - } - setvbuf (fp, NULL, _IOLBF, 0); - - if (logstream && logstream != stderr && logstream != stdout) - fclose( logstream); - logstream = fp; - missing_lf = 0; -} - - -void -log_set_prefix (const char *text, unsigned int flags) -{ - if (text) - { - strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1); - prefix_buffer[sizeof (prefix_buffer)-1] = 0; - } - - with_prefix = (flags & JNLIB_LOG_WITH_PREFIX); - with_time = (flags & JNLIB_LOG_WITH_TIME); - with_pid = (flags & JNLIB_LOG_WITH_PID); - running_detached = (flags & JNLIB_LOG_RUN_DETACHED); -} - - -const char * -log_get_prefix (unsigned int *flags) -{ - if (flags) - { - *flags = 0; - if (with_prefix) - *flags |= JNLIB_LOG_WITH_PREFIX; - if (with_time) - *flags |= JNLIB_LOG_WITH_TIME; - if (with_pid) - *flags |= JNLIB_LOG_WITH_PID; - if (running_detached) - *flags |= JNLIB_LOG_RUN_DETACHED; - } - return prefix_buffer; -} - -/* This function returns true if the file descriptor FD is in use for - logging. This is preferable over a test using log_get_fd in that - it allows the logging code to use more then one file descriptor. */ -int -log_test_fd (int fd) -{ - if (fileno (logstream?logstream:stderr) == fd) - return 1; - if (log_socket == fd) - return 1; - return 0; -} - -int -log_get_fd () -{ - return fileno(logstream?logstream:stderr); -} - -FILE * -log_get_stream () -{ - return logstream?logstream:stderr; -} - - -static void -do_logv (int level, const char *fmt, va_list arg_ptr) -{ - if (!logstream) - logstream = stderr; - - if (missing_lf && level != JNLIB_LOG_CONT) - putc('\n', logstream ); - missing_lf = 0; - - if (level != JNLIB_LOG_CONT) - { /* Note this does not work for multiple line logging as we would - * need to print to a buffer first */ - if (with_time && !force_prefixes) - { - struct tm *tp; - time_t atime = time (NULL); - - tp = localtime (&atime); - fprintf (logstream, "%04d-%02d-%02d %02d:%02d:%02d ", - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec ); - } - if (with_prefix || force_prefixes) - fputs (prefix_buffer, logstream); - if (with_pid || force_prefixes) - fprintf (logstream, "[%u]", (unsigned int)getpid ()); - if (!with_time || force_prefixes) - putc (':', logstream); - /* A leading backspace suppresses the extra space so that we can - correctly output, programname, filename and linenumber. */ - if (fmt && *fmt == '\b') - fmt++; - else - putc (' ', logstream); - } - - switch (level) - { - case JNLIB_LOG_BEGIN: break; - case JNLIB_LOG_CONT: break; - case JNLIB_LOG_INFO: break; - case JNLIB_LOG_WARN: break; - case JNLIB_LOG_ERROR: break; - case JNLIB_LOG_FATAL: fputs("Fatal: ",logstream ); break; - case JNLIB_LOG_BUG: fputs("Ohhhh jeeee: ", logstream); break; - case JNLIB_LOG_DEBUG: fputs("DBG: ", logstream ); break; - default: fprintf(logstream,"[Unknown log level %d]: ", level ); break; - } - - - if (fmt) - { - vfprintf(logstream,fmt,arg_ptr) ; - if (*fmt && fmt[strlen(fmt)-1] != '\n') - missing_lf = 1; - } - - if (level == JNLIB_LOG_FATAL) - exit(2); - if (level == JNLIB_LOG_BUG) - abort(); -} - -static void -do_log( int level, const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - do_logv( level, fmt, arg_ptr ); - va_end(arg_ptr); -} - - -void -log_logv (int level, const char *fmt, va_list arg_ptr) -{ - do_logv (level, fmt, arg_ptr); -} - -void -log_info( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - do_logv( JNLIB_LOG_INFO, fmt, arg_ptr ); - va_end(arg_ptr); -} - -void -log_error( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - do_logv( JNLIB_LOG_ERROR, fmt, arg_ptr ); - va_end(arg_ptr); - /* protect against counter overflow */ - if( errorcount < 30000 ) - errorcount++; -} - - -void -log_fatal( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - do_logv( JNLIB_LOG_FATAL, fmt, arg_ptr ); - va_end(arg_ptr); - abort(); /* never called, but it makes the compiler happy */ -} - -void -log_bug( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - do_logv( JNLIB_LOG_BUG, fmt, arg_ptr ); - va_end(arg_ptr); - abort(); /* never called, but it makes the compiler happy */ -} - -void -log_debug( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - do_logv( JNLIB_LOG_DEBUG, fmt, arg_ptr ); - va_end(arg_ptr); -} - - -void -log_printf (const char *fmt, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, fmt); - do_logv (fmt ? JNLIB_LOG_CONT : JNLIB_LOG_BEGIN, fmt, arg_ptr); - va_end (arg_ptr); -} - -/* Print a hexdump of BUFFER. With TEXT of NULL print just the raw - dump, with TEXT just an empty string, print a trailing linefeed, - otherwise print an entire debug line. */ -void -log_printhex (const char *text, const void *buffer, size_t length) -{ - if (text && *text) - log_debug ("%s ", text); - if (length) - { - const unsigned char *p = buffer; - log_printf ("%02X", *p); - for (length--, p++; length--; p++) - log_printf (" %02X", *p); - } - if (text) - log_printf ("\n"); -} - - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) -void -bug_at( const char *file, int line, const char *func ) -{ - do_log( JNLIB_LOG_BUG, - ("... this is a bug (%s:%d:%s)\n"), file, line, func ); - abort(); /* never called, but it makes the compiler happy */ -} -#else -void -bug_at( const char *file, int line ) -{ - do_log( JNLIB_LOG_BUG, - _("you found a bug ... (%s:%d)\n"), file, line); - abort(); /* never called, but it makes the compiler happy */ -} -#endif - diff --git a/jnlib/logging.h b/jnlib/logging.h deleted file mode 100644 index b5c0bd741..000000000 --- a/jnlib/logging.h +++ /dev/null @@ -1,83 +0,0 @@ -/* logging.h - * Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_LOGGING_H -#define LIBJNLIB_LOGGING_H - -#include <stdio.h> -#include "mischelp.h" - -/* Flag values for log_set_prefix. */ -#define JNLIB_LOG_WITH_PREFIX 1 -#define JNLIB_LOG_WITH_TIME 2 -#define JNLIB_LOG_WITH_PID 4 -#define JNLIB_LOG_RUN_DETACHED 256 - -int log_get_errorcount (int clear); -void log_inc_errorcount (void); -void log_set_file( const char *name ); -void log_set_fd (int fd); -void log_set_prefix (const char *text, unsigned int flags); -const char *log_get_prefix (unsigned int *flags); -int log_test_fd (int fd); -int log_get_fd(void); -FILE *log_get_stream (void); - -#ifdef JNLIB_GCC_M_FUNCTION - void bug_at( const char *file, int line, const char *func ) JNLIB_GCC_A_NR; -# define BUG() bug_at( __FILE__ , __LINE__, __FUNCTION__ ) -#else - void bug_at( const char *file, int line ); -# define BUG() bug_at( __FILE__ , __LINE__ ) -#endif - -/* To avoid mandatory inclusion of stdarg and other stuff, do it only - if explicitly requested to do so. */ -#ifdef JNLIB_NEED_LOG_LOGV -#include <stdarg.h> -enum jnlib_log_levels { - JNLIB_LOG_BEGIN, - JNLIB_LOG_CONT, - JNLIB_LOG_INFO, - JNLIB_LOG_WARN, - JNLIB_LOG_ERROR, - JNLIB_LOG_FATAL, - JNLIB_LOG_BUG, - JNLIB_LOG_DEBUG -}; -void log_logv (int level, const char *fmt, va_list arg_ptr); -#endif /*JNLIB_NEED_LOG_LOGV*/ - - -void log_bug( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2); -void log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2); -void log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); -void log_info( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); -void log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); -void log_printf( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); -void log_printhex (const char *text, const void *buffer, size_t length); - - -#endif /*LIBJNLIB_LOGGING_H*/ - - - - - diff --git a/jnlib/mischelp.h b/jnlib/mischelp.h deleted file mode 100644 index 54da4cc1f..000000000 --- a/jnlib/mischelp.h +++ /dev/null @@ -1,54 +0,0 @@ -/* mischelp.h - * Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_MISCHELP_H -#define LIBJNLIB_MISCHHELP_H - - -#define DIM(v) (sizeof(v)/sizeof((v)[0])) -#define DIMof(type,member) DIM(((type *)0)->member) - - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) -# define JNLIB_GCC_M_FUNCTION 1 -# define JNLIB_GCC_A_NR __attribute__ ((noreturn)) -# define JNLIB_GCC_A_PRINTF( f, a ) __attribute__ ((format (printf,f,a))) -# define JNLIB_GCC_A_NR_PRINTF( f, a ) \ - __attribute__ ((noreturn, format (printf,f,a))) -#else -# define JNLIB_GCC_A_NR -# define JNLIB_GCC_A_PRINTF( f, a ) -# define JNLIB_GCC_A_NR_PRINTF( f, a ) -#endif - - -/* To avoid that a compiler optimizes certain memset calls away, these - macros may be used instead. */ -#define wipememory2(_ptr,_set,_len) do { \ - volatile char *_vptr=(volatile char *)(_ptr); \ - size_t _vlen=(_len); \ - while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \ - } while(0) -#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) - - - - -#endif /*LIBJNLIB_MISCHELP_H*/ diff --git a/jnlib/stringhelp.c b/jnlib/stringhelp.c deleted file mode 100644 index 4c8ab314b..000000000 --- a/jnlib/stringhelp.c +++ /dev/null @@ -1,627 +0,0 @@ -/* stringhelp.c - standard string helper functions - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <ctype.h> - -#include "libjnlib-config.h" -#include "utf8conv.h" -#include "stringhelp.h" - - -/**************** - * look for the substring SUB in buffer and return a pointer to that - * substring in BUF or NULL if not found. - * Comparison is case-insensitive. - */ -const char * -memistr( const char *buf, size_t buflen, const char *sub ) -{ - const byte *t, *s ; - size_t n; - - for( t=buf, n=buflen, s=sub ; n ; t++, n-- ) - if( toupper(*t) == toupper(*s) ) { - for( buf=t++, buflen = n--, s++; - n && toupper(*t) == toupper(*s); t++, s++, n-- ) - ; - if( !*s ) - return buf; - t = buf; n = buflen; s = sub ; - } - - return NULL ; -} - -const char * -ascii_memistr( const char *buf, size_t buflen, const char *sub ) -{ - const byte *t, *s ; - size_t n; - - for( t=buf, n=buflen, s=sub ; n ; t++, n-- ) - if( ascii_toupper(*t) == ascii_toupper(*s) ) { - for( buf=t++, buflen = n--, s++; - n && ascii_toupper(*t) == ascii_toupper(*s); t++, s++, n-- ) - ; - if( !*s ) - return buf; - t = buf; n = buflen; s = sub ; - } - - return NULL ; -} - -/**************** - * Wie strncpy(), aber es werden maximal n-1 zeichen kopiert und ein - * '\0' angehängt. Ist n = 0, so geschieht nichts, ist Destination - * gleich NULL, so wird via jnlib_xmalloc Speicher besorgt, ist dann nicht - * genügend Speicher vorhanden, so bricht die funktion ab. - */ -char * -mem2str( char *dest , const void *src , size_t n ) -{ - char *d; - const char *s; - - if( n ) { - if( !dest ) - dest = jnlib_xmalloc( n ) ; - d = dest; - s = src ; - for(n--; n && *s; n-- ) - *d++ = *s++; - *d = '\0' ; - } - - return dest ; -} - - -/**************** - * remove leading and trailing white spaces - */ -char * -trim_spaces( char *str ) -{ - char *string, *p, *mark; - - string = str; - /* find first non space character */ - for( p=string; *p && isspace( *(byte*)p ) ; p++ ) - ; - /* move characters */ - for( (mark = NULL); (*string = *p); string++, p++ ) - if( isspace( *(byte*)p ) ) { - if( !mark ) - mark = string ; - } - else - mark = NULL ; - if( mark ) - *mark = '\0' ; /* remove trailing spaces */ - - return str ; -} - -/**************** - * remove trailing white spaces - */ -char * -trim_trailing_spaces( char *string ) -{ - char *p, *mark; - - for( mark = NULL, p = string; *p; p++ ) { - if( isspace( *(byte*)p ) ) { - if( !mark ) - mark = p; - } - else - mark = NULL; - } - if( mark ) - *mark = '\0' ; - - return string ; -} - - -unsigned -trim_trailing_chars( byte *line, unsigned len, const char *trimchars ) -{ - byte *p, *mark; - unsigned n; - - for(mark=NULL, p=line, n=0; n < len; n++, p++ ) { - if( strchr(trimchars, *p ) ) { - if( !mark ) - mark = p; - } - else - mark = NULL; - } - - if( mark ) { - *mark = 0; - return mark - line; - } - return len; -} - -/**************** - * remove trailing white spaces and return the length of the buffer - */ -unsigned -trim_trailing_ws( byte *line, unsigned len ) -{ - return trim_trailing_chars( line, len, " \t\r\n" ); -} - -size_t -length_sans_trailing_chars (const unsigned char *line, size_t len, - const char *trimchars ) -{ - const unsigned char *p, *mark; - size_t n; - - for( mark=NULL, p=line, n=0; n < len; n++, p++ ) - { - if (strchr (trimchars, *p )) - { - if( !mark ) - mark = p; - } - else - mark = NULL; - } - - if (mark) - return mark - line; - return len; -} - -/**************** - * remove trailing white spaces and return the length of the buffer - */ -size_t -length_sans_trailing_ws (const unsigned char *line, size_t len) -{ - return length_sans_trailing_chars (line, len, " \t\r\n"); -} - - - -/*************** - * Extract from a given path the filename component. - * - */ -char * -make_basename(const char *filepath) -{ - char *p; - - if ( !(p=strrchr(filepath, '/')) ) - #ifdef HAVE_DRIVE_LETTERS - if ( !(p=strrchr(filepath, '\\')) ) - if ( !(p=strrchr(filepath, ':')) ) - #endif - { - return jnlib_xstrdup(filepath); - } - - return jnlib_xstrdup(p+1); -} - - - -/*************** - * Extract from a given filename the path prepended to it. - * If their isn't a path prepended to the filename, a dot - * is returned ('.'). - * - */ -char * -make_dirname(const char *filepath) -{ - char *dirname; - int dirname_length; - char *p; - - if ( !(p=strrchr(filepath, '/')) ) - #ifdef HAVE_DRIVE_LETTERS - if ( !(p=strrchr(filepath, '\\')) ) - if ( !(p=strrchr(filepath, ':')) ) - #endif - { - return jnlib_xstrdup("."); - } - - dirname_length = p-filepath; - dirname = jnlib_xmalloc(dirname_length+1); - strncpy(dirname, filepath, dirname_length); - dirname[dirname_length] = 0; - - return dirname; -} - - - -/**************** - * Construct a filename from the NULL terminated list of parts. - * Tilde expansion is done here. - */ -char * -make_filename( const char *first_part, ... ) -{ - va_list arg_ptr ; - size_t n; - const char *s; - char *name, *home, *p; - - va_start( arg_ptr, first_part ) ; - n = strlen(first_part)+1; - while( (s=va_arg(arg_ptr, const char *)) ) - n += strlen(s) + 1; - va_end(arg_ptr); - - home = NULL; - if( *first_part == '~' && first_part[1] == '/' - && (home = getenv("HOME")) && *home ) - n += strlen(home); - - name = jnlib_xmalloc(n); - p = home ? stpcpy(stpcpy(name,home), first_part+1) - : stpcpy(name, first_part); - va_start( arg_ptr, first_part ) ; - while( (s=va_arg(arg_ptr, const char *)) ) - p = stpcpy(stpcpy(p,"/"), s); - va_end(arg_ptr); - - return name; -} - - -int -compare_filenames( const char *a, const char *b ) -{ - /* ? check whether this is an absolute filename and - * resolve symlinks? - */ -#ifdef HAVE_DRIVE_LETTERS - return stricmp(a,b); -#else - return strcmp(a,b); -#endif -} - -/* Print a BUFFER to stream FP while replacing all control characters - and the character DELIM with standard C escape sequences. Returns - the number of characters printed. */ -size_t -print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, - int delim) -{ - const unsigned char *p = buffer; - size_t count = 0; - - for (; length; length--, p++, count++) - { - if (*p < 0x20 || *p == 0x7f || *p == delim) - { - putc ('\\', fp); - count++; - if (*p == '\n') - putc ('n', fp); - else if (*p == '\r') - putc ('r', fp); - else if (*p == '\f') - putc ('f', fp); - else if (*p == '\v') - putc ('v', fp); - else if (*p == '\b') - putc ('b', fp); - else if (!*p) - putc('0', fp); - else - { - fprintf (fp, "x%02x", *p); - count += 2; - } - } - else - putc (*p, fp); - } - - return count; -} - -size_t -print_sanitized_utf8_buffer (FILE *fp, const void *buffer, - size_t length, int delim) -{ - const char *p = buffer; - size_t i; - - /* We can handle plain ascii simpler, so check for it first. */ - for (i=0; i < length; i++ ) - { - if ( (p[i] & 0x80) ) - break; - } - if (i < length) - { - char *buf = utf8_to_native (p, length, delim); - /*(utf8 conversion already does the control character quoting)*/ - i = strlen (buf); - fputs (buf, fp); - jnlib_free (buf); - return i; - } - else - return print_sanitized_buffer (fp, p, length, delim); -} - - -size_t -print_sanitized_string (FILE *fp, const char *string, int delim) -{ - return string? print_sanitized_buffer (fp, string, strlen (string), delim):0; -} - -size_t -print_sanitized_utf8_string (FILE *fp, const char *string, int delim) -{ - /* FIXME: convert to local characterset */ - return print_sanitized_string (fp, string, delim); -} - -/* Create a string from the buffer P of length N which is suitable for - printing. Caller must release the created string using xfree. */ -char * -sanitize_buffer (const unsigned char *p, size_t n, int delim) -{ - size_t save_n, buflen; - const byte *save_p; - char *buffer, *d; - - /* first count length */ - for (save_n = n, save_p = p, buflen=1 ; n; n--, p++ ) - { - if ( *p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) - { - if ( *p=='\n' || *p=='\r' || *p=='\f' - || *p=='\v' || *p=='\b' || !*p ) - buflen += 2; - else - buflen += 4; - } - else - buflen++; - } - p = save_p; - n = save_n; - /* and now make the string */ - d = buffer = jnlib_xmalloc( buflen ); - for ( ; n; n--, p++ ) - { - if (*p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) { - *d++ = '\\'; - if( *p == '\n' ) - *d++ = 'n'; - else if( *p == '\r' ) - *d++ = 'r'; - else if( *p == '\f' ) - *d++ = 'f'; - else if( *p == '\v' ) - *d++ = 'v'; - else if( *p == '\b' ) - *d++ = 'b'; - else if( !*p ) - *d++ = '0'; - else { - sprintf(d, "x%02x", *p ); - d += 2; - } - } - else - *d++ = *p; - } - *d = 0; - return buffer; -} - -/**************************************************** - ******** locale insensitive ctype functions ******** - ****************************************************/ -/* FIXME: replace them by a table lookup and macros */ -int -ascii_isupper (int c) -{ - return c >= 'A' && c <= 'Z'; -} - -int -ascii_islower (int c) -{ - return c >= 'a' && c <= 'z'; -} - -int -ascii_toupper (int c) -{ - if (c >= 'a' && c <= 'z') - c &= ~0x20; - return c; -} - -int -ascii_tolower (int c) -{ - if (c >= 'A' && c <= 'Z') - c |= 0x20; - return c; -} - - -int -ascii_strcasecmp( const char *a, const char *b ) -{ - if (a == b) - return 0; - - for (; *a && *b; a++, b++) { - if (*a != *b && ascii_toupper(*a) != ascii_toupper(*b)) - break; - } - return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); -} - -int -ascii_strncasecmp (const char *a, const char *b, size_t n) -{ - const unsigned char *p1 = (const unsigned char *)a; - const unsigned char *p2 = (const unsigned char *)b; - unsigned char c1, c2; - - if (p1 == p2 || !n ) - return 0; - - do - { - c1 = ascii_tolower (*p1); - c2 = ascii_tolower (*p2); - - if ( !--n || c1 == '\0') - break; - - ++p1; - ++p2; - } - while (c1 == c2); - - return c1 - c2; -} - - -int -ascii_memcasecmp( const char *a, const char *b, size_t n ) -{ - if (a == b) - return 0; - for ( ; n; n--, a++, b++ ) { - if( *a != *b && ascii_toupper (*a) != ascii_toupper (*b) ) - return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); - } - return 0; -} - -int -ascii_strcmp( const char *a, const char *b ) -{ - if (a == b) - return 0; - - for (; *a && *b; a++, b++) { - if (*a != *b ) - break; - } - return *a == *b? 0 : (*(signed char *)a - *(signed char *)b); -} - - -void * -ascii_memcasemem (const void *haystack, size_t nhaystack, - const void *needle, size_t nneedle) -{ - - if (!nneedle) - return (void*)haystack; /* finding an empty needle is really easy */ - if (nneedle <= nhaystack) - { - const unsigned char *a = haystack; - const unsigned char *b = a + nhaystack - nneedle; - - for (; a <= b; a++) - { - if ( !ascii_memcasecmp (a, needle, nneedle) ) - return (void *)a; - } - } - return NULL; -} - -/********************************************* - ********** missing string functions ********* - *********************************************/ - -#ifndef HAVE_STPCPY -char * -stpcpy(char *a,const char *b) -{ - while( *b ) - *a++ = *b++; - *a = 0; - - return (char*)a; -} -#endif - -#ifndef HAVE_STRLWR -char * -strlwr(char *s) -{ - char *p; - for(p=s; *p; p++ ) - *p = tolower(*p); - return s; -} -#endif - - -#ifndef HAVE_STRCASECMP -int -strcasecmp( const char *a, const char *b ) -{ - for( ; *a && *b; a++, b++ ) { - if( *a != *b && toupper(*a) != toupper(*b) ) - break; - } - return *(const byte*)a - *(const byte*)b; -} -#endif - - -/**************** - * mingw32/cpd has a memicmp() - */ -#ifndef HAVE_MEMICMP -int -memicmp( const char *a, const char *b, size_t n ) -{ - for( ; n; n--, a++, b++ ) - if( *a != *b && toupper(*(const byte*)a) != toupper(*(const byte*)b) ) - return *(const byte *)a - *(const byte*)b; - return 0; -} -#endif diff --git a/jnlib/stringhelp.h b/jnlib/stringhelp.h deleted file mode 100644 index fe5786e59..000000000 --- a/jnlib/stringhelp.h +++ /dev/null @@ -1,90 +0,0 @@ -/* stringhelp.h - * Copyright (C) 1998,1999,2000,2001,2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_STRINGHELP_H -#define LIBJNLIB_STRINGHELP_H - -#include "types.h" - -const char *memistr( const char *buf, size_t buflen, const char *sub ); -char *mem2str( char *, const void *, size_t); -char *trim_spaces( char *string ); -char *trim_trailing_spaces( char *string ); -unsigned int trim_trailing_chars( unsigned char *line, unsigned len, - const char *trimchars); -unsigned int trim_trailing_ws( unsigned char *line, unsigned len ); -size_t length_sans_trailing_chars (const unsigned char *line, size_t len, - const char *trimchars ); -size_t length_sans_trailing_ws (const unsigned char *line, size_t len); - - -char *make_basename(const char *filepath); -char *make_dirname(const char *filepath); -char *make_filename( const char *first_part, ... ); -int compare_filenames( const char *a, const char *b ); - -size_t print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, - int delim); -size_t print_sanitized_utf8_buffer (FILE *fp, const void *buffer, - size_t length, int delim); -size_t print_sanitized_string (FILE *fp, const char *string, int delim); -size_t print_sanitized_utf8_string (FILE *fp, const char *string, int delim); -char *sanitize_buffer (const unsigned char *p, size_t n, int delim); - - -const char *ascii_memistr( const char *buf, size_t buflen, const char *sub ); -int ascii_isupper (int c); -int ascii_islower (int c); -int ascii_toupper (int c); -int ascii_tolower (int c); -int ascii_strcasecmp( const char *a, const char *b ); -int ascii_strncasecmp (const char *a, const char *b, size_t n); -int ascii_memcasecmp( const char *a, const char *b, size_t n ); -const char *ascii_memistr ( const char *buf, size_t buflen, const char *sub); -void *ascii_memcasemem (const void *haystack, size_t nhaystack, - const void *needle, size_t nneedle); - - -#ifndef HAVE_MEMICMP -int memicmp( const char *a, const char *b, size_t n ); -#endif -#ifndef HAVE_STPCPY -char *stpcpy(char *a,const char *b); -#endif -#ifndef HAVE_STRLWR -char *strlwr(char *a); -#endif -#ifndef HAVE_STRTOUL - #define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c))) -#endif -#ifndef HAVE_MEMMOVE - #define memmove(d, s, n) bcopy((s), (d), (n)) -#endif -#ifndef HAVE_STRICMP - #define stricmp(a,b) strcasecmp( (a), (b) ) -#endif - -#ifndef STR - #define STR(v) #v -#endif -#define STR2(v) STR(v) - - -#endif /*LIBJNLIB_STRINGHELP_H*/ diff --git a/jnlib/strlist.c b/jnlib/strlist.c deleted file mode 100644 index 49b510666..000000000 --- a/jnlib/strlist.c +++ /dev/null @@ -1,172 +0,0 @@ -/* strlist.c - string helpers - * Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <ctype.h> - -#include "libjnlib-config.h" -#include "strlist.h" - - -void -free_strlist( strlist_t sl ) -{ - strlist_t sl2; - - for(; sl; sl = sl2 ) { - sl2 = sl->next; - jnlib_free(sl); - } -} - - -strlist_t -add_to_strlist( strlist_t *list, const char *string ) -{ - strlist_t sl; - - sl = jnlib_xmalloc( sizeof *sl + strlen(string)); - sl->flags = 0; - strcpy(sl->d, string); - sl->next = *list; - *list = sl; - return sl; -} - -#if 0 -/**************** - * same as add_to_strlist() but if is_utf8 is *not* set a conversion - * to UTF8 is done - */ -strlist_t -add_to_strlist2( strlist_t *list, const char *string, int is_utf8 ) -{ - strlist_t sl; - - if( is_utf8 ) - sl = add_to_strlist( list, string ); - else { - char *p = native_to_utf8( string ); - sl = add_to_strlist( list, p ); - m_free( p ); - } - return sl; -} -#endif - -strlist_t -append_to_strlist( strlist_t *list, const char *string ) -{ - strlist_t r, sl; - - sl = jnlib_xmalloc( sizeof *sl + strlen(string)); - sl->flags = 0; - strcpy(sl->d, string); - sl->next = NULL; - if( !*list ) - *list = sl; - else { - for( r = *list; r->next; r = r->next ) - ; - r->next = sl; - } - return sl; -} - -#if 0 -strlist_t -append_to_strlist2( strlist_t *list, const char *string, int is_utf8 ) -{ - strlist_t sl; - - if( is_utf8 ) - sl = append_to_strlist( list, string ); - else { - char *p = native_to_utf8( string ); - sl = append_to_strlist( list, p ); - m_free( p ); - } - return sl; -} -#endif - - -/* Return a copy of LIST. */ -strlist_t -strlist_copy (strlist_t list) -{ - strlist_t newlist = NULL, sl, *last; - - last = &newlist; - for (; list; list = list->next) - { - sl = jnlib_xmalloc (sizeof *sl + strlen (list->d)); - sl->flags = list->flags; - strcpy(sl->d, list->d); - sl->next = NULL; - *last = sl; - last = &sl; - } - return newlist; -} - - - -strlist_t -strlist_prev( strlist_t head, strlist_t node ) -{ - strlist_t n; - - for(n=NULL; head && head != node; head = head->next ) - n = head; - return n; -} - -strlist_t -strlist_last( strlist_t node ) -{ - if( node ) - for( ; node->next ; node = node->next ) - ; - return node; -} - - -char * -strlist_pop (strlist_t *list) -{ - char *str=NULL; - strlist_t sl=*list; - - if(sl) - { - str=jnlib_xmalloc(strlen(sl->d)+1); - strcpy(str,sl->d); - - *list=sl->next; - jnlib_free(sl); - } - - return str; -} - diff --git a/jnlib/strlist.h b/jnlib/strlist.h deleted file mode 100644 index 72da241bc..000000000 --- a/jnlib/strlist.h +++ /dev/null @@ -1,51 +0,0 @@ -/* strlist.h - * Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_STRLIST_H -#define LIBJNLIB_STRLIST_H - -struct string_list { - struct string_list *next; - unsigned int flags; - char d[1]; -}; -typedef struct string_list *STRLIST; /* Deprecated. */ -typedef struct string_list *strlist_t; - -void free_strlist (strlist_t sl); -strlist_t add_to_strlist (strlist_t *list, const char *string); - -/*strlist_t add_to_strlist2( strlist_t *list, - const char *string, int is_utf8);*/ - -strlist_t append_to_strlist (strlist_t *list, const char *string); - -strlist_t strlist_copy (strlist_t list); - -/*strlist_t append_to_strlist2( strlist_t *list, const char *string, - int is_utf8);*/ -strlist_t strlist_prev (strlist_t head, strlist_t node); -strlist_t strlist_last (strlist_t node); -char * strlist_pop (strlist_t *list); - -#define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0) - - -#endif /*LIBJNLIB_STRLIST_H*/ diff --git a/jnlib/types.h b/jnlib/types.h deleted file mode 100644 index 230d1502f..000000000 --- a/jnlib/types.h +++ /dev/null @@ -1,101 +0,0 @@ -/* types.h - * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_TYPES_H -#define LIBJNLIB_TYPES_H - -/* The AC_CHECK_SIZEOF() in configure fails for some machines. - * we provide some fallback values here */ -#if !SIZEOF_UNSIGNED_SHORT - #undef SIZEOF_UNSIGNED_SHORT - #define SIZEOF_UNSIGNED_SHORT 2 -#endif -#if !SIZEOF_UNSIGNED_INT - #undef SIZEOF_UNSIGNED_INT - #define SIZEOF_UNSIGNED_INT 4 -#endif -#if !SIZEOF_UNSIGNED_LONG - #undef SIZEOF_UNSIGNED_LONG - #define SIZEOF_UNSIGNED_LONG 4 -#endif - - -#include <sys/types.h> - - -#ifndef HAVE_BYTE_TYPEDEF - #undef byte /* maybe there is a macro with this name */ - typedef unsigned char byte; - #define HAVE_BYTE_TYPEDEF -#endif - -#ifndef HAVE_USHORT_TYPEDEF - #undef ushort /* maybe there is a macro with this name */ - typedef unsigned short ushort; - #define HAVE_USHORT_TYPEDEF -#endif - -#ifndef HAVE_ULONG_TYPEDEF - #undef ulong /* maybe there is a macro with this name */ - typedef unsigned long ulong; - #define HAVE_ULONG_TYPEDEF -#endif - -#ifndef HAVE_U16_TYPEDEF - #undef u16 /* maybe there is a macro with this name */ - #if SIZEOF_UNSIGNED_INT == 2 - typedef unsigned int u16; - #elif SIZEOF_UNSIGNED_SHORT == 2 - typedef unsigned short u16; - #else - #error no typedef for u16 - #endif - #define HAVE_U16_TYPEDEF -#endif - -#ifndef HAVE_U32_TYPEDEF - #undef u32 /* maybe there is a macro with this name */ - #if SIZEOF_UNSIGNED_INT == 4 - typedef unsigned int u32; - #elif SIZEOF_UNSIGNED_LONG == 4 - typedef unsigned long u32; - #else - #error no typedef for u32 - #endif - #define HAVE_U32_TYPEDEF -#endif - -#ifndef HAVE_U64_TYPEDEF - #undef u64 /* maybe there is a macro with this name */ - #if SIZEOF_UNSIGNED_INT == 8 - typedef unsigned int u64; - #define HAVE_U64_TYPEDEF - #elif SIZEOF_UNSIGNED_LONG == 8 - typedef unsigned long u64; - #define HAVE_U64_TYPEDEF - #elif __GNUC__ >= 2 || defined(__SUNPRO_C) - typedef unsigned long long u64; - #define HAVE_U64_TYPEDEF - #endif -#endif - - - -#endif /*LIBJNLIB_TYPES_H*/ diff --git a/jnlib/utf8conv.c b/jnlib/utf8conv.c deleted file mode 100644 index 691176766..000000000 --- a/jnlib/utf8conv.c +++ /dev/null @@ -1,448 +0,0 @@ -/* utf8conf.c - UTF8 character set conversion - * Copyright (C) 1994, 1998, 1999, 2000, 2001, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <ctype.h> -#ifdef HAVE_LANGINFO_CODESET -#include <langinfo.h> -#endif - -#include "libjnlib-config.h" -#include "stringhelp.h" -#include "utf8conv.h" - - -static ushort koi8_unicode[128] = { - 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, - 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, - 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248, - 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, - 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, - 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, - 0x255f, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, - 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x00a9, - 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, - 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, - 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, - 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, - 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, - 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, - 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, - 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a -}; - -static ushort latin2_unicode[128] = { - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, - 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, - 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, - 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, - 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, - 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, - 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, - 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, - 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, - 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, - 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, - 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, - 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, - 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 -}; - - -static const char *active_charset_name = "iso-8859-1"; -static ushort *active_charset = NULL; -static int no_translation = 0; - -int -set_native_charset (const char *newset) -{ - if (!newset) -#ifdef HAVE_LANGINFO_CODESET - newset = nl_langinfo (CODESET); -#else - newset = "8859-1"; -#endif - - if (strlen (newset) > 3 && !ascii_memcasecmp (newset, "iso", 3)) - { - newset += 3; - if (*newset == '-' || *newset == '_') - newset++; - } - - if (!*newset - || !ascii_strcasecmp (newset, "8859-1") - || !ascii_strcasecmp (newset, "8859-15")) - { - active_charset_name = "iso-8859-1"; - no_translation = 0; - active_charset = NULL; - } - else if (!ascii_strcasecmp (newset, "8859-2")) - { - active_charset_name = "iso-8859-2"; - no_translation = 0; - active_charset = latin2_unicode; - } - else if (!ascii_strcasecmp (newset, "koi8-r")) - { - active_charset_name = "koi8-r"; - no_translation = 0; - active_charset = koi8_unicode; - } - else if (!ascii_strcasecmp (newset, "utf8") - || !ascii_strcasecmp (newset, "utf-8")) - { - active_charset_name = "utf-8"; - no_translation = 1; - active_charset = NULL; - } - else - return -1; - return 0; -} - -const char * -get_native_charset () -{ - return active_charset_name; -} - -/**************** - * Convert string, which is in native encoding to UTF8 and return the - * new allocated UTF8 string. - */ -char * -native_to_utf8 (const char *string) -{ - const byte *s; - char *buffer; - byte *p; - size_t length = 0; - - if (no_translation) - { - buffer = jnlib_xstrdup (string); - } - else if (active_charset) - { - for (s = string; *s; s++) - { - length++; - if (*s & 0x80) - length += 2; /* we may need 3 bytes */ - } - buffer = jnlib_xmalloc (length + 1); - for (p = buffer, s = string; *s; s++) - { - if ((*s & 0x80)) - { - ushort val = active_charset[*s & 0x7f]; - if (val < 0x0800) - { - *p++ = 0xc0 | ((val >> 6) & 0x1f); - *p++ = 0x80 | (val & 0x3f); - } - else - { - *p++ = 0xe0 | ((val >> 12) & 0x0f); - *p++ = 0x80 | ((val >> 6) & 0x3f); - *p++ = 0x80 | (val & 0x3f); - } - } - else - *p++ = *s; - } - *p = 0; - } - else - { - for (s = string; *s; s++) - { - length++; - if (*s & 0x80) - length++; - } - buffer = jnlib_xmalloc (length + 1); - for (p = buffer, s = string; *s; s++) - { - if (*s & 0x80) - { - *p++ = 0xc0 | ((*s >> 6) & 3); - *p++ = 0x80 | (*s & 0x3f); - } - else - *p++ = *s; - } - *p = 0; - } - return buffer; -} - - -/* Convert string, which is in UTF8 to native encoding. Replace - * illegal encodings by some "\xnn" and quote all control - * characters. A character with value DELIM will always be quoted, it - * must be a vanilla ASCII character. */ -char * -utf8_to_native (const char *string, size_t length, int delim) -{ - int nleft; - int i; - byte encbuf[8]; - int encidx; - const byte *s; - size_t n; - byte *buffer = NULL, *p = NULL; - unsigned long val = 0; - size_t slen; - int resync = 0; - - /* 1. pass (p==NULL): count the extended utf-8 characters */ - /* 2. pass (p!=NULL): create string */ - for (;;) - { - for (slen = length, nleft = encidx = 0, n = 0, s = string; slen; - s++, slen--) - { - if (resync) - { - if (!(*s < 128 || (*s >= 0xc0 && *s <= 0xfd))) - { - /* still invalid */ - if (p) - { - sprintf (p, "\\x%02x", *s); - p += 4; - } - n += 4; - continue; - } - resync = 0; - } - if (!nleft) - { - if (!(*s & 0x80)) - { /* plain ascii */ - if (*s < 0x20 || *s == 0x7f || *s == delim || - (delim && *s == '\\')) - { - n++; - if (p) - *p++ = '\\'; - switch (*s) - { - case '\n': - n++; - if (p) - *p++ = 'n'; - break; - case '\r': - n++; - if (p) - *p++ = 'r'; - break; - case '\f': - n++; - if (p) - *p++ = 'f'; - break; - case '\v': - n++; - if (p) - *p++ = 'v'; - break; - case '\b': - n++; - if (p) - *p++ = 'b'; - break; - case 0: - n++; - if (p) - *p++ = '0'; - break; - default: - n += 3; - if (p) - { - sprintf (p, "x%02x", *s); - p += 3; - } - break; - } - } - else - { - if (p) - *p++ = *s; - n++; - } - } - else if ((*s & 0xe0) == 0xc0) - { /* 110x xxxx */ - val = *s & 0x1f; - nleft = 1; - encidx = 0; - encbuf[encidx++] = *s; - } - else if ((*s & 0xf0) == 0xe0) - { /* 1110 xxxx */ - val = *s & 0x0f; - nleft = 2; - encidx = 0; - encbuf[encidx++] = *s; - } - else if ((*s & 0xf8) == 0xf0) - { /* 1111 0xxx */ - val = *s & 0x07; - nleft = 3; - encidx = 0; - encbuf[encidx++] = *s; - } - else if ((*s & 0xfc) == 0xf8) - { /* 1111 10xx */ - val = *s & 0x03; - nleft = 4; - encidx = 0; - encbuf[encidx++] = *s; - } - else if ((*s & 0xfe) == 0xfc) - { /* 1111 110x */ - val = *s & 0x01; - nleft = 5; - encidx = 0; - encbuf[encidx++] = *s; - } - else - { /* invalid encoding: print as \xnn */ - if (p) - { - sprintf (p, "\\x%02x", *s); - p += 4; - } - n += 4; - resync = 1; - } - } - else if (*s < 0x80 || *s >= 0xc0) - { /* invalid */ - if (p) - { - for (i = 0; i < encidx; i++) - { - sprintf (p, "\\x%02x", encbuf[i]); - p += 4; - } - sprintf (p, "\\x%02x", *s); - p += 4; - } - n += 4 + 4 * encidx; - nleft = 0; - encidx = 0; - resync = 1; - } - else - { - encbuf[encidx++] = *s; - val <<= 6; - val |= *s & 0x3f; - if (!--nleft) - { /* ready */ - if (no_translation) - { - if (p) - { - for (i = 0; i < encidx; i++) - *p++ = encbuf[i]; - } - n += encidx; - encidx = 0; - } - else if (active_charset) - { /* table lookup */ - for (i = 0; i < 128; i++) - { - if (active_charset[i] == val) - break; - } - if (i < 128) - { /* we can print this one */ - if (p) - *p++ = i + 128; - n++; - } - else - { /* we do not have a translation: print utf8 */ - if (p) - { - for (i = 0; i < encidx; i++) - { - sprintf (p, "\\x%02x", encbuf[i]); - p += 4; - } - } - n += encidx * 4; - encidx = 0; - } - } - else - { /* native set */ - if (val >= 0x80 && val < 256) - { - n++; /* we can simply print this character */ - if (p) - *p++ = val; - } - else - { /* we do not have a translation: print utf8 */ - if (p) - { - for (i = 0; i < encidx; i++) - { - sprintf (p, "\\x%02x", encbuf[i]); - p += 4; - } - } - n += encidx * 4; - encidx = 0; - } - } - } - - } - } - if (!buffer) - { /* allocate the buffer after the first pass */ - buffer = p = jnlib_xmalloc (n + 1); - } - else - { - *p = 0; /* make a string */ - return buffer; - } - } -} diff --git a/jnlib/utf8conv.h b/jnlib/utf8conv.h deleted file mode 100644 index 6e2ce9944..000000000 --- a/jnlib/utf8conv.h +++ /dev/null @@ -1,31 +0,0 @@ -/* utf8conf.h - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_UTF8CONF_H -#define LIBJNLIB_UTF8CONF_H - -int set_native_charset (const char *newset); -const char *get_native_charset (void); - -char *native_to_utf8 (const char *string); -char *utf8_to_native (const char *string, size_t length, int delim); - - -#endif /*LIBJNLIB_UTF8CONF_H*/ diff --git a/jnlib/xmalloc.c b/jnlib/xmalloc.c deleted file mode 100644 index 1cfaab9f7..000000000 --- a/jnlib/xmalloc.c +++ /dev/null @@ -1,88 +0,0 @@ -/* xmalloc.c - standard malloc wrappers - * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include "libjnlib-config.h" -#include "xmalloc.h" - -static void -out_of_core(void) -{ - fputs("\nfatal: out of memory\n", stderr ); - exit(2); -} - - -void * -xmalloc( size_t n ) -{ - void *p = malloc( n ); - if( !p ) - out_of_core(); - return p; -} - -void * -xrealloc( void *a, size_t n ) -{ - void *p = realloc( a, n ); - if( !p ) - out_of_core(); - return p; -} - -void * -xcalloc( size_t n, size_t m ) -{ - void *p = calloc( n, m ); - if( !p ) - out_of_core(); - return p; -} - -char * -xstrdup( const char *string ) -{ - void *p = xmalloc( strlen(string)+1 ); - strcpy( p, string ); - return p; -} - - -char * -xstrcat2( const char *a, const char *b ) -{ - size_t n1; - char *p; - - if( !b ) - return xstrdup( a ); - - n1 = strlen(a); - p = xmalloc( n1 + strlen(b) + 1 ); - memcpy(p, a, n1 ); - strcpy(p+n1, b ); - return p; -} - diff --git a/jnlib/xmalloc.h b/jnlib/xmalloc.h deleted file mode 100644 index 150ef3664..000000000 --- a/jnlib/xmalloc.h +++ /dev/null @@ -1,31 +0,0 @@ -/* xmalloc.h - * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_XMALLOC_H -#define LIBJNLIB_XMALLOC_H - -void *xmalloc( size_t n ); -void *xrealloc( void *a, size_t n ); -void *xcalloc( size_t n, size_t m ); -char *xstrdup( const char *string ); -char *xstrcat2( const char *a, const char *b ); - - -#endif /*LIBJNLIB_XMALLOC_H*/ diff --git a/kbx/ChangeLog b/kbx/ChangeLog deleted file mode 100644 index 1c3b9e3a1..000000000 --- a/kbx/ChangeLog +++ /dev/null @@ -1,166 +0,0 @@ -2004-06-18 Werner Koch <wk@gnupg.org> - - * keybox-dump.c (_keybox_dump_file): New arg STATS_ONLY. - (update_stats): New. - * kbxutil.c (main): New command --stats. - -2004-04-23 Werner Koch <wk@gnupg.org> - - * keybox-blob.c (_keybox_update_header_blob): New. - * keybox-update.c (blob_filecopy): Handle header blob. - * keybox-file.c (_keybox_read_blob2): New. Moved code from - _keybox_read_blob to there. - * keybox-dump.c (dump_header_blob): Print header info. - -2004-04-21 Werner Koch <wk@gnupg.org> - - * keybox-search.c (_keybox_get_flag_location): Add flag - KEYBOX_FLAG_CREATED_AT. - * keybox-update.c (keybox_compress): New. - - * keybox-search.c (get32, get16, blob_get_type) - (blob_get_blob_flags, has_short_kid, has_long_kid) - (has_fingerprint, has_issuer, has_issuer_sn, has_sn, has_subject) - (has_subject_or_alt, has_mail): inline them. - - * keybox-update.c (blob_filecopy): Fixed an error/eof check - (s/if(fread)/if(nread)/). - - * keybox-dump.c (_keybox_dump_blob): Really print the timestamps. - -2004-04-20 Werner Koch <wk@gnupg.org> - - * keybox-defs.h: Include jnlib/types.h and remove our own - definitions for byte.u16 and u32. - -2004-02-02 Werner Koch <wk@gnupg.org> - - * keybox.h (keybox_flag_t): New. - * keybox-search.c (get_flag_from_image, keybox_get_flags): New. - (_keybox_get_flag_location): New. - -2003-11-12 Werner Koch <wk@gnupg.org> - - Adjusted for API changes in Libksba. - - * keybox-blob.c: Include time.h - -2003-06-03 Werner Koch <wk@gnupg.org> - - Changed all error codes in all files to the new libgpg-error scheme. - - * keybox-defs.h: Include gpg-error.h . - (KeyboxError): Removed. - * Makefile.am: Removed keybox-error.c stuff. - -2002-11-14 Werner Koch <wk@gnupg.org> - - * keybox-search.c (blob_cmp_name) <compare all names>: Fixed - length compare; there is no 0 stored since nearly a year. - -2002-10-31 Neal H. Walfield <neal@g10code.de> - - * Makefile.am (AM_CPPFLAGS): Fix ytpo. - -2002-08-10 Werner Koch <wk@gnupg.org> - - * keybox-search.c (blob_cmp_fpr_part): New. - (has_short_kid, has_long_kid): Implemented. - -2002-07-22 Werner Koch <wk@gnupg.org> - - * keybox-defs.h: New BLOBTYPTE_EMPTY. - * keybox-dump.c (_keybox_dump_blob): Handle new type. - * keybox-file.c (_keybox_read_blob): Skip over empty blobs. Store - the file offset. - * keybox-blob.c (_keybox_new_blob): Add new arg OFF. - (_keybox_get_blob_fileoffset): New. - * keybox-update.c (keybox_delete): Implemented. - -2002-06-19 Werner Koch <wk@gnupg.org> - - * keybox-init.c (keybox_set_ephemeral): New. - * keybox-blob.c (create_blob_header): Store ephemeral flag. - (_keybox_create_x509_blob): Pass epheermal flag on. - * keybox-update.c (keybox_insert_cert): Ditto. - * keybox-search.c (blob_get_blob_flags): New. - (keybox_search): Ignore ephemeral blobs when not in ephemeral mode. - - * keybox-dump.c (_keybox_dump_blob): Print blob flags as strings. - -2002-02-25 Werner Koch <wk@gnupg.org> - - * keybox-search.c (blob_cmp_mail): Use case-insensitive compare - because mail addresses are in general case insensitive (well - RFC2822 allows for case sensitive mailbox parts, but this is in - general considired a Bad Thing). Add additional substr parameter - to allow for substring matches within the mail address. Change - all callers to pass this along. - (blob_cmp_name): Likewise but do the case-insensitive search only - in sub string mode. - (keybox_search): Implement MAILSUB and SUBSTR mode. - -2002-01-21 Werner Koch <wk@gnupg.org> - - * keybox-search.c (keybox_search): Allow KEYDB_SEARCH_MODE_FPR20. - -2002-01-15 Werner Koch <wk@gnupg.org> - - * keybox-search.c (blob_cmp_fpr): New. - (has_fingerprint): Implemented; - -2001-12-20 Werner Koch <wk@gnupg.org> - - * keybox-blob.c (_keybox_create_x509_blob): Skip the leading - parenthesis of the serial number's S-exp. - (_keybox_create_x509_blob): And fixed length calculation. - (create_blob_header): Don't add an offset when writing the serial. - -2001-12-18 Werner Koch <wk@gnupg.org> - - * Makefile.am (AM_CPPFLAGS): Add flags for libksba - - * keybox-blob.c (_keybox_create_x509_blob): Use - gcry_sexp_canon_len to get the length of the serial number. - (_keybox_release_blob): Need to use a new serialbuf to free the memory. - -2001-12-17 Werner Koch <wk@gnupg.org> - - * keybox-search.c: Changed the way the serial number is - represented. - -2001-12-15 Werner Koch <wk@gnupg.org> - - * keybox-search.c (blob_cmp_name): There is no terminating 0 stored - for the uid; fixed length compare. - -2001-12-14 Werner Koch <wk@gnupg.org> - - * keybox-blob.c (x509_email_kludge): New. - (_keybox_create_x509_blob): Insert an extra email address if the - subject's DN has an email part. - * keybox-defs.h: Added the xtoi_2 and digitp macros. - -2001-12-13 Werner Koch <wk@gnupg.org> - - * keybox-search.c (blob_cmp_name): Kludge to allow searching for - more than one name. - (has_subject_or_alt): New. - (blob_cmp_mail): New. - (has_mail): New. - (keybox_search): Implemented exact search and exact mail search. - - * kbx/keybox-blob.c (_keybox_create_x509_blob): Insert alternate - names. - - - Copyright 2001 g10 Code GmbH - - 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. - \ No newline at end of file diff --git a/kbx/Makefile.am b/kbx/Makefile.am deleted file mode 100644 index 4f0c40043..000000000 --- a/kbx/Makefile.am +++ /dev/null @@ -1,52 +0,0 @@ -# Keybox Makefile -# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -localedir = $(datadir)/locale -INCLUDES = -I../intl -DLOCALEDIR=\"$(localedir)\" - -EXTRA_DIST = mkerrors -AM_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/intl \ - $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) - -noinst_LIBRARIES = libkeybox.a -bin_PROGRAMS = kbxutil - -common_sources = \ - keybox.h keybox-defs.h keybox-search-desc.h \ - keybox-util.c \ - keybox-init.c \ - keybox-blob.c \ - keybox-file.c \ - keybox-search.c \ - keybox-update.c \ - keybox-dump.c - - -libkeybox_a_SOURCES = $(common_sources) - -kbxutil_SOURCES = kbxutil.c $(common_sources) -kbxutil_LDADD = ../jnlib/libjnlib.a $(KSBA_LIBS) $(LIBGCRYPT_LIBS) \ - -lgpg-error @INTLLIBS@ - - - - - diff --git a/kbx/Manifest b/kbx/Manifest deleted file mode 100644 index 95f48d73f..000000000 --- a/kbx/Manifest +++ /dev/null @@ -1,8 +0,0 @@ - -keybox-update.c -keybox-file.c - - - - -$names$ diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c deleted file mode 100644 index 37c19130b..000000000 --- a/kbx/kbxutil.c +++ /dev/null @@ -1,357 +0,0 @@ -/* kbxutil.c - The Keybox utility - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> - -#include "../jnlib/logging.h" -#include "../jnlib/argparse.h" -#include "../jnlib/stringhelp.h" -#include "../common/i18n.h" -#include "keybox-defs.h" - -#include <gcrypt.h> - - -enum cmd_and_opt_values { - aNull = 0, - oArmor = 'a', - oDryRun = 'n', - oOutput = 'o', - oQuiet = 'q', - oVerbose = 'v', - - aNoSuchCmd = 500, /* force other values not to be a letter */ - aFindByFpr, - aFindByKid, - aFindByUid, - aStats, - - oDebug, - oDebugAll, - - oNoArmor, - - - aTest -}; - - -static ARGPARSE_OPTS opts[] = { - { 300, NULL, 0, N_("@Commands:\n ") }, - -/* { aFindByFpr, "find-by-fpr", 0, "|FPR| find key using it's fingerprnt" }, */ -/* { aFindByKid, "find-by-kid", 0, "|KID| find key using it's keyid" }, */ -/* { aFindByUid, "find-by-uid", 0, "|NAME| find key by user name" }, */ - { aStats, "stats", 0, "show key statistics" }, - - { 301, NULL, 0, N_("@\nOptions:\n ") }, - -/* { oArmor, "armor", 0, N_("create ascii armored output")}, */ -/* { oArmor, "armour", 0, "@" }, */ -/* { oOutput, "output", 2, N_("use as output file")}, */ - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - - { oDebug, "debug" ,4|16, N_("set debugging flags")}, - { oDebugAll, "debug-all" ,0, N_("enable full debugging")}, - - {0} /* end of list */ -}; - - -void myexit (int rc); - -int keybox_errors_seen = 0; - - -static const char * -my_strusage( int level ) -{ - const char *p; - switch( level ) { - case 11: p = "kbxutil (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = - _("Please report bugs to " PACKAGE_BUGREPORT ".\n"); - break; - case 1: - case 40: p = - _("Usage: kbxutil [options] [files] (-h for help)"); - break; - case 41: p = - _("Syntax: kbxutil [options] [files]\n" - "list, export, import Keybox data\n"); - break; - - - default: p = NULL; - } - return p; -} - - -static void -i18n_init(void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE_GT ); -#else -#ifdef ENABLE_NLS - #ifdef HAVE_LC_MESSAGES - setlocale( LC_TIME, "" ); - setlocale( LC_MESSAGES, "" ); - #else - setlocale( LC_ALL, "" ); - #endif - bindtextdomain( PACKAGE_GT, LOCALEDIR ); - textdomain( PACKAGE_GT ); -#endif -#endif -} - - -/* static void */ -/* wrong_args( const char *text ) */ -/* { */ -/* log_error("usage: kbxutil %s\n", text); */ -/* myexit ( 1 ); */ -/* } */ - - -#if 0 -static int -hextobyte( const byte *s ) -{ - int c; - - if( *s >= '0' && *s <= '9' ) - c = 16 * (*s - '0'); - else if( *s >= 'A' && *s <= 'F' ) - c = 16 * (10 + *s - 'A'); - else if( *s >= 'a' && *s <= 'f' ) - c = 16 * (10 + *s - 'a'); - else - return -1; - s++; - if( *s >= '0' && *s <= '9' ) - c += *s - '0'; - else if( *s >= 'A' && *s <= 'F' ) - c += 10 + *s - 'A'; - else if( *s >= 'a' && *s <= 'f' ) - c += 10 + *s - 'a'; - else - return -1; - return c; -} -#endif - -#if 0 -static char * -format_fingerprint ( const char *s ) -{ - int i, c; - byte fpr[20]; - - for (i=0; i < 20 && *s; ) { - if ( *s == ' ' || *s == '\t' ) { - s++; - continue; - } - c = hextobyte(s); - if (c == -1) { - return NULL; - } - fpr[i++] = c; - s += 2; - } - return gcry_xstrdup ( fpr ); -} -#endif - -#if 0 -static int -format_keyid ( const char *s, u32 *kid ) -{ - char helpbuf[9]; - switch ( strlen ( s ) ) { - case 8: - kid[0] = 0; - kid[1] = strtoul( s, NULL, 16 ); - return 10; - - case 16: - mem2str( helpbuf, s, 9 ); - kid[0] = strtoul( helpbuf, NULL, 16 ); - kid[1] = strtoul( s+8, NULL, 16 ); - return 11; - } - return 0; /* error */ -} -#endif - - -int -main( int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - enum cmd_and_opt_values cmd = 0; - - set_strusage( my_strusage ); - /*log_set_name("kbxutil"); fixme */ -#if 0 - /* check that the libraries are suitable. Do it here because - * the option parse may need services of the library */ - if ( !gcry_check_version ( "1.1.4" ) ) - { - log_fatal(_("libgcrypt is too old (need %s, have %s)\n"), - "1.1.4", gcry_check_version(NULL) ); - } -#endif - - /*create_dotlock(NULL); register locking cleanup */ - i18n_init(); - - /* We need to use the gcry malloc function because jnlib does use them */ - keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free ); - - - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - while (arg_parse( &pargs, opts) ) - { - switch (pargs.r_opt) - { - case oVerbose: - /*opt.verbose++;*/ - /*gcry_control( GCRYCTL_SET_VERBOSITY, (int)opt.verbose );*/ - break; - case oDebug: - /*opt.debug |= pargs.r.ret_ulong; */ - break; - case oDebugAll: - /*opt.debug = ~0;*/ - break; - - case aFindByFpr: - case aFindByKid: - case aFindByUid: - case aStats: - cmd = pargs.r_opt; - break; - - default: - pargs.err = 2; - break; - } - } - if (log_get_errorcount(0) ) - myexit(2); - - if (!cmd) - { /* default is to list a KBX file */ - if (!argc) - _keybox_dump_file (NULL, 0, stdout); - else - { - for (; argc; argc--, argv++) - _keybox_dump_file (*argv, 0, stdout); - } - } - else if (cmd == aStats ) - { - if (!argc) - _keybox_dump_file (NULL, 1, stdout); - else - { - for (; argc; argc--, argv++) - _keybox_dump_file (*argv, 1, stdout); - } - } -#if 0 - else if ( cmd == aFindByFpr ) - { - char *fpr; - if ( argc != 2 ) - wrong_args ("kbxfile foingerprint"); - fpr = format_fingerprint ( argv[1] ); - if ( !fpr ) - log_error ("invalid formatted fingerprint\n"); - else - { - kbxfile_search_by_fpr ( argv[0], fpr ); - gcry_free ( fpr ); - } - } - else if ( cmd == aFindByKid ) - { - u32 kid[2]; - int mode; - - if ( argc != 2 ) - wrong_args ("kbxfile short-or-long-keyid"); - mode = format_keyid ( argv[1], kid ); - if ( !mode ) - log_error ("invalid formatted keyID\n"); - else - { - kbxfile_search_by_kid ( argv[0], kid, mode ); - } - } - else if ( cmd == aFindByUid ) - { - if ( argc != 2 ) - wrong_args ("kbxfile userID"); - kbxfile_search_by_uid ( argv[0], argv[1] ); - } -#endif - else - log_error ("unsupported action\n"); - - myexit(0); - return 8; /*NEVER REACHED*/ -} - - -void -myexit( int rc ) -{ - /* if( opt.debug & DBG_MEMSTAT_VALUE ) {*/ -/* gcry_control( GCRYCTL_DUMP_MEMORY_STATS ); */ -/* gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); */ - /* }*/ -/* if( opt.debug ) */ -/* gcry_control( GCRYCTL_DUMP_SECMEM_STATS ); */ - rc = rc? rc : log_get_errorcount(0)? 2 : - keybox_errors_seen? 1 : 0; - exit(rc ); -} - - diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c deleted file mode 100644 index 48bce28e2..000000000 --- a/kbx/keybox-blob.c +++ /dev/null @@ -1,1031 +0,0 @@ -/* keybox-blob.c - KBX Blob handling - * Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -/* The keybox data formats - -The KeyBox uses an augmented OpenPGP/X.509 key format. This makes -random access to a keyblock/Certificate easier and also gives the -opportunity to store additional information (e.g. the fingerprint) -along with the key. All integers are stored in network byte order, -offsets are counted from the beginning of the Blob. - -The first record of a plain KBX file has a special format: - - u32 length of the first record - byte Blob type (1) - byte version number (1) - byte reserved - byte reserved - u32 magic 'KBXf' - u32 reserved - u32 file_created_at - u32 last_maintenance_run - u32 reserved - u32 reserved - -The OpenPGP and X.509 blob are very similiar, things which are -X.509 specific are noted like [X.509: xxx] - - u32 length of this blob (including these 4 bytes) - byte Blob type (2) [X509: 3] - byte version number of this blob type (1) - u16 Blob flags - bit 0 = contains secret key material - bit 1 = ephemeral blob (e.g. used while quering external resources) - - u32 offset to the OpenPGP keyblock or X509 DER encoded certificate - u32 and its length - u16 number of keys (at least 1!) [X509: always 1] - u16 size of additional key information - n times: - b20 The keys fingerprint - (fingerprints are always 20 bytes, MD5 left padded with zeroes) - u32 offset to the n-th key's keyID (a keyID is always 8 byte) - or 0 if not known which is the case only for X509. - u16 special key flags - bit 0 = - u16 reserved - u16 size of serialnumber(may be zero) - n u16 (see above) bytes of serial number - u16 number of user IDs - u16 size of additional user ID information - n times: - u32 offset to the n-th user ID - u32 length of this user ID. - u16 special user ID flags. - bit 0 = - byte validity - byte reserved - [For X509, the first user ID is the Issuer, the second the Subject - and the others are subjectAltNames] - u16 number of signatures - u16 size of signature information (4) - u32 expiration time of signature with some special values: - 0x00000000 = not checked - 0x00000001 = missing key - 0x00000002 = bad signature - 0x10000000 = valid and expires at some date in 1978. - 0xffffffff = valid and does not expire - u8 assigned ownertrust [X509: not used] - u8 all_validity - OpenPGP: see ../g10/trustdb/TRUST_* [not yet used] - X509: Bit 4 set := key has been revoked. Note that this value - matches TRUST_FLAG_REVOKED - u16 reserved - u32 recheck_after - u32 Newest timestamp in the keyblock (useful for KS syncronsiation?) - u32 Blob created at - u32 size of reserved space (not including this field) - reserved space - - Here we might want to put other data - - Here comes the keyblock - - maybe we put a signature here later. - - b16 MD5 checksum (useful for KS syncronisation), we might also want to use - a mac here. - b4 resevered - -*/ - - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <time.h> - -#include "keybox-defs.h" -#include <gcrypt.h> - -#ifdef KEYBOX_WITH_OPENPGP -/* include stuff to parse the packets */ -#endif -#ifdef KEYBOX_WITH_X509 -#include <ksba.h> -#endif - - - -/* special values of the signature status */ -#define SF_NONE(a) ( !(a) ) -#define SF_NOKEY(a) ((a) & (1<<0)) -#define SF_BAD(a) ((a) & (1<<1)) -#define SF_VALID(a) ((a) & (1<<29)) - - -struct membuf { - size_t len; - size_t size; - char *buf; - int out_of_core; -}; - - -/* #if MAX_FINGERPRINT_LEN < 20 */ -/* #error fingerprints are 20 bytes */ -/* #endif */ - -struct keyboxblob_key { - char fpr[20]; - u32 off_kid; - ulong off_kid_addr; - u16 flags; -}; -struct keyboxblob_uid { - ulong off_addr; - char *name; /* used only with x509 */ - u32 len; - u16 flags; - byte validity; -}; - -struct keyid_list { - struct keyid_list *next; - int seqno; - byte kid[8]; -}; - -struct fixup_list { - struct fixup_list *next; - u32 off; - u32 val; -}; - - -struct keyboxblob { - byte *blob; - size_t bloblen; - off_t fileoffset; - - /* stuff used only by keybox_create_blob */ - unsigned char *serialbuf; - const unsigned char *serial; - size_t seriallen; - int nkeys; - struct keyboxblob_key *keys; - int nuids; - struct keyboxblob_uid *uids; - int nsigs; - u32 *sigs; - struct fixup_list *fixups; - int fixup_out_of_core; - - struct keyid_list *temp_kids; - struct membuf bufbuf; /* temporary store for the blob */ - struct membuf *buf; -}; - - - -/* A simple implemention of a dynamic buffer. Use init_membuf() to - create a buffer, put_membuf to append bytes and get_membuf to - release and return the buffer. Allocation errors are detected but - only returned at the final get_membuf(), this helps not to clutter - the code with out of core checks. */ - -static void -init_membuf (struct membuf *mb, int initiallen) -{ - mb->len = 0; - mb->size = initiallen; - mb->out_of_core = 0; - mb->buf = xtrymalloc (initiallen); - if (!mb->buf) - mb->out_of_core = 1; -} - -static void -put_membuf (struct membuf *mb, const void *buf, size_t len) -{ - if (mb->out_of_core) - return; - - if (mb->len + len >= mb->size) - { - char *p; - - mb->size += len + 1024; - p = xtryrealloc (mb->buf, mb->size); - if (!p) - { - mb->out_of_core = 1; - return; - } - mb->buf = p; - } - memcpy (mb->buf + mb->len, buf, len); - mb->len += len; -} - -static void * -get_membuf (struct membuf *mb, size_t *len) -{ - char *p; - - if (mb->out_of_core) - { - xfree (mb->buf); - mb->buf = NULL; - return NULL; - } - - p = mb->buf; - *len = mb->len; - mb->buf = NULL; - mb->out_of_core = 1; /* don't allow a reuse */ - return p; -} - - -static void -put8 (struct membuf *mb, byte a ) -{ - put_membuf (mb, &a, 1); -} - -static void -put16 (struct membuf *mb, u16 a ) -{ - unsigned char tmp[2]; - tmp[0] = a>>8; - tmp[1] = a; - put_membuf (mb, tmp, 2); -} - -static void -put32 (struct membuf *mb, u32 a ) -{ - unsigned char tmp[4]; - tmp[0] = a>>24; - tmp[1] = a>>16; - tmp[2] = a>>8; - tmp[3] = a; - put_membuf (mb, tmp, 4); -} - - -/* Store a value in the fixup list */ -static void -add_fixup (KEYBOXBLOB blob, u32 off, u32 val) -{ - struct fixup_list *fl; - - if (blob->fixup_out_of_core) - return; - - fl = xtrycalloc(1, sizeof *fl); - if (!fl) - blob->fixup_out_of_core = 1; - else - { - fl->off = off; - fl->val = val; - fl->next = blob->fixups; - blob->fixups = fl; - } -} - - -/* - Some wrappers -*/ - -static u32 -make_timestamp (void) -{ - return time(NULL); -} - - - -#ifdef KEYBOX_WITH_OPENPGP -/* - OpenPGP specific stuff -*/ - - -/* - We must store the keyid at some place because we can't calculate the - offset yet. This is only used for v3 keyIDs. Function returns an - index value for later fixup or -1 for out of core. The value must be - a non-zero value */ -static int -pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk) -{ - struct keyid_list *k, *r; - - k = xtrymalloc (sizeof *k); - if (!k) - return -1; - k->kid[0] = pk->keyid[0] >> 24 ; - k->kid[1] = pk->keyid[0] >> 16 ; - k->kid[2] = pk->keyid[0] >> 8 ; - k->kid[3] = pk->keyid[0] ; - k->kid[4] = pk->keyid[0] >> 24 ; - k->kid[5] = pk->keyid[0] >> 16 ; - k->kid[6] = pk->keyid[0] >> 8 ; - k->kid[7] = pk->keyid[0] ; - k->seqno = 0; - k->next = blob->temp_kids; - blob->temp_kids = k; - for (r=k; r; r = r->next) - k->seqno++; - - return k->seqno; -} - -static int -pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock) -{ - KBNODE node; - size_t fprlen; - int n; - - for (n=0, node = keyblock; node; node = node->next) - { - if ( node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - { - PKT_public_key *pk = node->pkt->pkt.public_key; - char tmp[20]; - - fingerprint_from_pk (pk, tmp , &fprlen); - memcpy (blob->keys[n].fpr, tmp, 20); - if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/ - { - assert (fprlen == 16); - memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16); - memset (blob->keys[n].fpr, 0, 4); - blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk); - } - else - { - blob->keys[n].off_kid = 0; /* will be fixed up later */ - } - blob->keys[n].flags = 0; - n++; - } - else if ( node->pkt->pkttype == PKT_SECRET_KEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) - { - never_reached (); /* actually not yet implemented */ - } - } - assert (n == blob->nkeys); - return 0; -} - -static int -pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock) -{ - KBNODE node; - int n; - - for (n=0, node = keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID) - { - PKT_user_id *u = node->pkt->pkt.user_id; - - blob->uids[n].len = u->len; - blob->uids[n].flags = 0; - blob->uids[n].validity = 0; - n++; - } - } - assert (n == blob->nuids); - return 0; -} - -static int -pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock) -{ - KBNODE node; - int n; - - for (n=0, node = keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_SIGNATURE) - { - PKT_signature *sig = node->pkt->pkt.signature; - - blob->sigs[n] = 0; /* FIXME: check the signature here */ - n++; - } - } - assert( n == blob->nsigs ); - return 0; -} - -static int -pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock) -{ - struct membuf *a = blob->buf; - KBNODE node; - int rc; - int n; - u32 kbstart = a->len; - - add_fixup (blob, kbstart); - - for (n = 0, node = keyblock; node; node = node->next) - { - rc = build_packet ( a, node->pkt ); - if ( rc ) { - gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n", - node->pkt->pkttype, gpg_errstr(rc) ); - return GPGERR_WRITE_FILE; - } - if ( node->pkt->pkttype == PKT_USER_ID ) - { - PKT_user_id *u = node->pkt->pkt.user_id; - /* build_packet has set the offset of the name into u ; - * now we can do the fixup */ - add_fixup (blob, blob->uids[n].off_addr, u->stored_at); - n++; - } - } - assert (n == blob->nuids); - - add_fixup (blob, a->len - kbstart); - return 0; -} - -#endif /*KEYBOX_WITH_OPENPGP*/ - - -#ifdef KEYBOX_WITH_X509 -/* - X.509 specific stuff - */ - -/* Write the raw certificate out */ -static int -x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert) -{ - struct membuf *a = blob->buf; - const unsigned char *image; - size_t length; - u32 kbstart = a->len; - - /* Store our offset for later fixup */ - add_fixup (blob, 8, kbstart); - - image = ksba_cert_get_image (cert, &length); - if (!image) - return gpg_error (GPG_ERR_GENERAL); - put_membuf (a, image, length); - - add_fixup (blob, 12, a->len - kbstart); - return 0; -} - -#endif /*KEYBOX_WITH_X509*/ - -/* Write a stored keyID out to the buffer */ -static void -write_stored_kid (KEYBOXBLOB blob, int seqno) -{ - struct keyid_list *r; - - for ( r = blob->temp_kids; r; r = r->next ) - { - if (r->seqno == seqno ) - { - put_membuf (blob->buf, r->kid, 8); - return; - } - } - never_reached (); -} - -/* Release a list of key IDs */ -static void -release_kid_list (struct keyid_list *kl) -{ - struct keyid_list *r, *r2; - - for ( r = kl; r; r = r2 ) - { - r2 = r->next; - xfree (r); - } -} - - - -static int -create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral) -{ - struct membuf *a = blob->buf; - int i; - - put32 ( a, 0 ); /* blob length, needs fixup */ - put8 ( a, blobtype); - put8 ( a, 1 ); /* blob type version */ - put16 ( a, as_ephemeral? 2:0 ); /* blob flags */ - - put32 ( a, 0 ); /* offset to the raw data, needs fixup */ - put32 ( a, 0 ); /* length of the raw data, needs fixup */ - - put16 ( a, blob->nkeys ); - put16 ( a, 20 + 4 + 2 + 2 ); /* size of key info */ - for ( i=0; i < blob->nkeys; i++ ) - { - put_membuf (a, blob->keys[i].fpr, 20); - blob->keys[i].off_kid_addr = a->len; - put32 ( a, 0 ); /* offset to keyid, fixed up later */ - put16 ( a, blob->keys[i].flags ); - put16 ( a, 0 ); /* reserved */ - } - - put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/ - if (blob->serial) - put_membuf (a, blob->serial, blob->seriallen); - - put16 ( a, blob->nuids ); - put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */ - for (i=0; i < blob->nuids; i++) - { - blob->uids[i].off_addr = a->len; - put32 ( a, 0 ); /* offset to userid, fixed up later */ - put32 ( a, blob->uids[i].len ); - put16 ( a, blob->uids[i].flags ); - put8 ( a, 0 ); /* validity */ - put8 ( a, 0 ); /* reserved */ - } - - put16 ( a, blob->nsigs ); - put16 ( a, 4 ); /* size of sig info */ - for (i=0; i < blob->nsigs; i++) - { - put32 ( a, blob->sigs[i]); - } - - put8 ( a, 0 ); /* assigned ownertrust */ - put8 ( a, 0 ); /* validity of all user IDs */ - put16 ( a, 0 ); /* reserved */ - put32 ( a, 0 ); /* time of next recheck */ - put32 ( a, 0 ); /* newest timestamp (none) */ - put32 ( a, make_timestamp() ); /* creation time */ - put32 ( a, 0 ); /* size of reserved space */ - /* reserved space (which is currently of size 0) */ - - /* space where we write keyIDs and and other stuff so that the - pointers can actually point to somewhere */ - if (blobtype == BLOBTYPE_PGP) - { - /* We need to store the keyids for all pgp v3 keys because those key - IDs are not part of the fingerprint. While we are doing that, we - fixup all the keyID offsets */ - for (i=0; i < blob->nkeys; i++ ) - { - if (blob->keys[i].off_kid) - { /* this is a v3 one */ - add_fixup (blob, blob->keys[i].off_kid_addr, a->len); - write_stored_kid (blob, blob->keys[i].off_kid); - } - else - { /* the better v4 key IDs - just store an offset 8 bytes back */ - add_fixup (blob, blob->keys[i].off_kid_addr, - blob->keys[i].off_kid_addr - 8); - } - } - } - - if (blobtype == BLOBTYPE_X509) - { - /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to - the utf-8 string represenation of them */ - for (i=0; i < blob->nuids; i++ ) - { - if (blob->uids[i].name) - { /* this is a v3 one */ - add_fixup (blob, blob->uids[i].off_addr, a->len); - put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len); - } - } - } - - return 0; -} - - - -static int -create_blob_trailer (KEYBOXBLOB blob) -{ - return 0; -} - - -static int -create_blob_finish (KEYBOXBLOB blob) -{ - struct membuf *a = blob->buf; - byte *p; - char *pp; - int i; - size_t n; - - /* write a placeholder for the checksum */ - for (i = 0; i < 16; i++ ) - put32 (a, 0); /* Hmmm: why put32() ?? */ - - /* get the memory area */ - p = get_membuf (a, &n); - if (!p) - return gpg_error (GPG_ERR_ENOMEM); - assert (n >= 20); - - /* fixup the length */ - add_fixup (blob, 0, n); - - /* do the fixups */ - if (blob->fixup_out_of_core) - return gpg_error (GPG_ERR_ENOMEM); - - { - struct fixup_list *fl; - for (fl = blob->fixups; fl; fl = fl->next) - { - assert (fl->off+4 <= n); - p[fl->off+0] = fl->val >> 24; - p[fl->off+1] = fl->val >> 16; - p[fl->off+2] = fl->val >> 8; - p[fl->off+3] = fl->val; - } - } - - /* calculate and store the MD5 checksum */ - gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16); - - pp = xtrymalloc (n); - if ( !pp ) - return gpg_error (gpg_err_code_from_errno (errno)); - memcpy (pp , p, n); - blob->blob = pp; - blob->bloblen = n; - - return 0; -} - - -#ifdef KEYBOX_WITH_OPENPGP - -int -_keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock, int as_ephemeral) -{ - int rc = 0; - KBNODE node; - KEYBOXBLOB blob; - - *r_blob = NULL; - blob = xtrycalloc (1, sizeof *blob); - if (!blob) - return gpg_error (gpg_err_code_from_errno (errno)); - - /* fixme: Do some sanity checks on the keyblock */ - - /* count userids and keys so that we can allocate the arrays */ - for (node = keyblock; node; node = node->next) - { - switch (node->pkt->pkttype) - { - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - case PKT_PUBLIC_SUBKEY: - case PKT_SECRET_SUBKEY: blob->nkeys++; break; - case PKT_USER_ID: blob->nuids++; break; - case PKT_SIGNATURE: blob->nsigs++; break; - default: break; - } - } - - blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys ); - blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids ); - blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs ); - if (!blob->keys || !blob->uids || !blob->sigs) - { - rc = gpg_error (GPG_ERR_ENOMEM); - goto leave; - } - - rc = pgp_create_key_part ( blob, keyblock ); - if (rc) - goto leave; - rc = pgp_create_uid_part ( blob, keyblock ); - if (rc) - goto leave; - rc = pgp_create_sig_part ( blob, keyblock ); - if (rc) - goto leave; - - init_membuf (&blob->bufbuf, 1024); - blob->buf = &blob->bufbuf; - rc = create_blob_header (blob, BLOBTYPE_OPENPGP, as_ephemeral); - if (rc) - goto leave; - rc = pgp_create_blob_keyblock (blob, keyblock); - if (rc) - goto leave; - rc = create_blob_trailer (blob); - if (rc) - goto leave; - rc = create_blob_finish ( blob ); - if (rc) - goto leave; - - - leave: - release_kid_list (blob->temp_kids); - blob->temp_kids = NULL; - if (rc) - { - keybox_release_blob (blob); - *r_blob = NULL; - } - else - { - *r_blob = blob; - } - return rc; -} -#endif /*KEYBOX_WITH_OPENPGP*/ - -#ifdef KEYBOX_WITH_X509 - -/* return an allocated string with the email address extracted from a - DN */ -static char * -x509_email_kludge (const char *name) -{ - const unsigned char *p; - unsigned char *buf; - int n; - - if (strncmp (name, "1.2.840.113549.1.9.1=#", 22)) - return NULL; - /* This looks pretty much like an email address in the subject's DN - we use this to add an additional user ID entry. This way, - openSSL generated keys get a nicer and usable listing */ - name += 22; - for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++) - ; - if (*p != '#' || !n) - return NULL; - buf = xtrymalloc (n+3); - if (!buf) - return NULL; /* oops, out of core */ - *buf = '<'; - for (n=1, p=name; *p != '#'; p +=2, n++) - buf[n] = xtoi_2 (p); - buf[n++] = '>'; - buf[n] = 0; - return buf; -} - - - -/* Note: We should move calculation of the digest into libksba and - remove that parameter */ -int -_keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, - unsigned char *sha1_digest, int as_ephemeral) -{ - int i, rc = 0; - KEYBOXBLOB blob; - unsigned char *p; - unsigned char **names = NULL; - size_t max_names; - - *r_blob = NULL; - blob = xtrycalloc (1, sizeof *blob); - if( !blob ) - return gpg_error (gpg_err_code_from_errno (errno)); - - p = ksba_cert_get_serial (cert); - if (p) - { - size_t n, len; - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (n < 2) - { - xfree (p); - return gpg_error (GPG_ERR_GENERAL); - } - blob->serialbuf = p; - p++; n--; /* skip '(' */ - for (len=0; n && *p && *p != ':' && digitp (p); n--, p++) - len = len*10 + atoi_1 (p); - if (*p != ':') - { - xfree (blob->serialbuf); - blob->serialbuf = NULL; - return gpg_error (GPG_ERR_GENERAL); - } - p++; - blob->serial = p; - blob->seriallen = len; - } - - blob->nkeys = 1; - - /* create list of names */ - blob->nuids = 0; - max_names = 100; - names = xtrymalloc (max_names * sizeof *names); - if (!names) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - p = ksba_cert_get_issuer (cert, 0); - if (!p) - { - rc = gpg_error (GPG_ERR_MISSING_VALUE); - goto leave; - } - names[blob->nuids++] = p; - for (i=0; (p = ksba_cert_get_subject (cert, i)); i++) - { - - if (blob->nuids >= max_names) - { - unsigned char **tmp; - - max_names += 100; - tmp = xtryrealloc (names, max_names * sizeof *names); - if (!tmp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - } - names[blob->nuids++] = p; - if (!i && (p=x509_email_kludge (p))) - names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/ - } - - /* space for signature information */ - blob->nsigs = 1; - - blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys ); - blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids ); - blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs ); - if (!blob->keys || !blob->uids || !blob->sigs) - { - rc = gpg_error (GPG_ERR_ENOMEM); - goto leave; - } - - memcpy (blob->keys[0].fpr, sha1_digest, 20); - blob->keys[0].off_kid = 0; /* We don't have keyids */ - blob->keys[0].flags = 0; - - /* issuer and subject names */ - for (i=0; i < blob->nuids; i++) - { - blob->uids[i].name = names[i]; - blob->uids[i].len = strlen(names[i]); - names[i] = NULL; - blob->uids[i].flags = 0; - blob->uids[i].validity = 0; - } - xfree (names); - names = NULL; - - /* signatures */ - blob->sigs[0] = 0; /* not yet checked */ - - /* Create a temporary buffer for further processing */ - init_membuf (&blob->bufbuf, 1024); - blob->buf = &blob->bufbuf; - /* write out what we already have */ - rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral); - if (rc) - goto leave; - rc = x509_create_blob_cert (blob, cert); - if (rc) - goto leave; - rc = create_blob_trailer (blob); - if (rc) - goto leave; - rc = create_blob_finish ( blob ); - if (rc) - goto leave; - - - leave: - release_kid_list (blob->temp_kids); - blob->temp_kids = NULL; - if (blob && names) - { - for (i=0; i < blob->nuids; i++) - xfree (names[i]); - } - xfree (names); - if (rc) - { - _keybox_release_blob (blob); - *r_blob = NULL; - } - else - { - *r_blob = blob; - } - return rc; -} -#endif /*KEYBOX_WITH_X509*/ - - - -int -_keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen, off_t off) -{ - KEYBOXBLOB blob; - - *r_blob = NULL; - blob = xtrycalloc (1, sizeof *blob); - if (!blob) - return gpg_error (gpg_err_code_from_errno (errno)); - - blob->blob = image; - blob->bloblen = imagelen; - blob->fileoffset = off; - *r_blob = blob; - return 0; -} - - -void -_keybox_release_blob (KEYBOXBLOB blob) -{ - int i; - if (!blob) - return; - /* hmmm: release membuf here?*/ - xfree (blob->keys ); - xfree (blob->serialbuf); - for (i=0; i < blob->nuids; i++) - xfree (blob->uids[i].name); - xfree (blob->uids ); - xfree (blob->sigs ); - xfree (blob->blob ); - xfree (blob ); -} - - - -const char * -_keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n ) -{ - *n = blob->bloblen; - return blob->blob; -} - -off_t -_keybox_get_blob_fileoffset (KEYBOXBLOB blob) -{ - return blob->fileoffset; -} - - - -void -_keybox_update_header_blob (KEYBOXBLOB blob) -{ - if (blob->bloblen >= 32 && blob->blob[4] == BLOBTYPE_HEADER) - { - u32 val = make_timestamp (); - - /* Update the last maintenance run times tamp. */ - blob->blob[20] = (val >> 24); - blob->blob[20+1] = (val >> 16); - blob->blob[20+2] = (val >> 8); - blob->blob[20+3] = (val ); - } -} diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h deleted file mode 100644 index 759289a0e..000000000 --- a/kbx/keybox-defs.h +++ /dev/null @@ -1,191 +0,0 @@ -/* keybox-defs.h - interal Keybox defintions - * Copyright (C) 2001, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef KEYBOX_DEFS_H -#define KEYBOX_DEFS_H 1 - -#ifdef GPG_ERR_SOURCE_DEFAULT -#error GPG_ERR_SOURCE_DEFAULT already defined -#endif -#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_KEYBOX - -#include <gpg-error.h> -#include <sys/types.h> /* off_t */ - -/* We include the type defintions from jnlib instead of defining our - owns here. This will not allow us build KBX in a standalone way - but tehre is currently no need for it anyway. */ -#include "../jnlib/types.h" - -#include "keybox.h" - - -enum { - BLOBTYPE_EMPTY = 0, - BLOBTYPE_HEADER = 1, - BLOBTYPE_PGP = 2, - BLOBTYPE_X509 = 3 -}; - - -typedef struct keyboxblob *KEYBOXBLOB; - - -typedef struct keybox_name *KB_NAME; -typedef struct keybox_name const * CONST_KB_NAME; -struct keybox_name { - struct keybox_name *next; - int secret; - /*DOTLOCK lockhd;*/ - int is_locked; - int did_full_scan; - char fname[1]; -}; - - - -struct keybox_handle { - CONST_KB_NAME kb; - int secret; /* this is for a secret keybox */ - FILE *fp; - int eof; - int error; - int ephemeral; - struct { - KEYBOXBLOB blob; - off_t offset; - size_t pk_no; - size_t uid_no; - unsigned int n_packets; /*used for delete and update*/ - } found; - struct { - char *name; - char *pattern; - } word_match; -}; - - -/* Don't know whether this is needed: */ -/* static struct { */ -/* const char *homedir; */ -/* int dry_run; */ -/* int quiet; */ -/* int verbose; */ -/* int preserve_permissions; */ -/* } keybox_opt; */ - - -/*-- keybox-blob.c --*/ -#ifdef KEYBOX_WITH_OPENPGP - /* fixme */ -#endif /*KEYBOX_WITH_OPENPGP*/ -#ifdef KEYBOX_WITH_X509 -int _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, - unsigned char *sha1_digest, int as_ephemeral); -#endif /*KEYBOX_WITH_X509*/ - -int _keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen, - off_t off); -void _keybox_release_blob (KEYBOXBLOB blob); -const char *_keybox_get_blob_image (KEYBOXBLOB blob, size_t *n); -off_t _keybox_get_blob_fileoffset (KEYBOXBLOB blob); -void _keybox_update_header_blob (KEYBOXBLOB blob); - -/*-- keybox-file.c --*/ -int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp); -int _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted); -int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp); -int _keybox_write_header_blob (FILE *fp); - -/*-- keybox-search.c --*/ -gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer, - size_t length, - int what, - size_t *flag_off, size_t *flag_size); - -/*-- keybox-dump.c --*/ -int _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp); -int _keybox_dump_file (const char *filename, int stats_only, FILE *outfp); - - -/*-- keybox-util.c --*/ -void *_keybox_malloc (size_t n); -void *_keybox_calloc (size_t n, size_t m); -void *_keybox_realloc (void *p, size_t n); -void _keybox_free (void *p); - -#define xtrymalloc(a) _keybox_malloc ((a)) -#define xtrycalloc(a,b) _keybox_calloc ((a),(b)) -#define xtryrealloc(a,b) _keybox_realloc((a),(b)) -#define xfree(a) _keybox_free ((a)) - - -#define DIM(v) (sizeof(v)/sizeof((v)[0])) -#define DIMof(type,member) DIM(((type *)0)->member) -#ifndef STR - #define STR(v) #v -#endif -#define STR2(v) STR(v) - -/* - a couple of handy macros -*/ - -#define return_if_fail(expr) do { \ - if (!(expr)) { \ - fprintf (stderr, "%s:%d: assertion `%s' failed\n", \ - __FILE__, __LINE__, #expr ); \ - return; \ - } } while (0) -#define return_null_if_fail(expr) do { \ - if (!(expr)) { \ - fprintf (stderr, "%s:%d: assertion `%s' failed\n", \ - __FILE__, __LINE__, #expr ); \ - return NULL; \ - } } while (0) -#define return_val_if_fail(expr,val) do { \ - if (!(expr)) { \ - fprintf (stderr, "%s:%d: assertion `%s' failed\n", \ - __FILE__, __LINE__, #expr ); \ - return (val); \ - } } while (0) -#define never_reached() do { \ - fprintf (stderr, "%s:%d: oops; should never get here\n", \ - __FILE__, __LINE__ ); \ - } while (0) - - -/* some macros to replace ctype ones and avoid locale problems */ -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) -/* the atoi macros assume that the buffer has only valid digits */ -#define atoi_1(p) (*(p) - '0' ) -#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) -#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) - - -#endif /*KEYBOX_DEFS_H*/ - - diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c deleted file mode 100644 index 495fb249e..000000000 --- a/kbx/keybox-dump.c +++ /dev/null @@ -1,484 +0,0 @@ -/* keybox-dump.c - Debug helpers - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "keybox-defs.h" - -static ulong -get32 (const byte *buffer) -{ - ulong a; - a = *buffer << 24; - a |= buffer[1] << 16; - a |= buffer[2] << 8; - a |= buffer[3]; - return a; -} - -static ulong -get16 (const byte *buffer) -{ - ulong a; - a = *buffer << 8; - a |= buffer[1]; - return a; -} - -void -print_string (FILE *fp, const byte *p, size_t n, int delim) -{ - for ( ; n; n--, p++ ) - { - if (*p < 0x20 || (*p >= 0x7f && *p < 0xa0) || *p == delim) - { - putc('\\', fp); - if( *p == '\n' ) - putc('n', fp); - else if( *p == '\r' ) - putc('r', fp); - else if( *p == '\f' ) - putc('f', fp); - else if( *p == '\v' ) - putc('v', fp); - else if( *p == '\b' ) - putc('b', fp); - else if( !*p ) - putc('0', fp); - else - fprintf(fp, "x%02x", *p ); - } - else - putc(*p, fp); - } -} - - -static int -dump_header_blob (const byte *buffer, size_t length, FILE *fp) -{ - unsigned long n; - - if (length < 32) - { - fprintf (fp, "[blob too short]\n"); - return -1; - } - fprintf (fp, "Version: %d\n", buffer[5]); - if ( memcmp (buffer+8, "KBXf", 4)) - fprintf (fp, "[Error: invalid magic number]\n"); - - n = get32 (buffer+16); - fprintf( fp, "created-at: %lu\n", n ); - n = get32 (buffer+20); - fprintf( fp, "last-maint: %lu\n", n ); - - return 0; -} - - -/* Dump one block to FP */ -int -_keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) -{ - const byte *buffer; - size_t length; - int type; - ulong n, nkeys, keyinfolen; - ulong nuids, uidinfolen; - ulong nsigs, siginfolen; - ulong rawdata_off, rawdata_len; - ulong nserial; - const byte *p; - - buffer = _keybox_get_blob_image (blob, &length); - - if (length < 32) - { - fprintf (fp, "[blob too short]\n"); - return -1; - } - - n = get32( buffer ); - if (n > length) - fprintf (fp, "[blob larger than length - output truncated]\n"); - else - length = n; /* ignore the rest */ - - fprintf (fp, "Length: %lu\n", n ); - type = buffer[4]; - switch (type) - { - case BLOBTYPE_EMPTY: - fprintf (fp, "Type: Empty\n"); - return 0; - - case BLOBTYPE_HEADER: - fprintf (fp, "Type: Header\n"); - return dump_header_blob (buffer, length, fp); - case BLOBTYPE_PGP: - fprintf (fp, "Type: OpenPGP\n"); - break; - case BLOBTYPE_X509: - fprintf (fp, "Type: X.509\n"); - break; - default: - fprintf (fp, "Type: %d\n", type); - fprintf (fp, "[can't dump this blob type]\n"); - return 0; - } - fprintf (fp, "Version: %d\n", buffer[5]); - - if (length < 40) - { - fprintf (fp, "[blob too short]\n"); - return -1; - } - - n = get16 (buffer + 6); - fprintf( fp, "Blob-Flags: %04lX", n); - if (n) - { - int any = 0; - - fputs (" (", fp); - if ((n & 1)) - { - fputs ("secret", fp); - any++; - } - if ((n & 2)) - { - if (any) - putc (',', fp); - fputs ("ephemeral", fp); - any++; - } - putc (')', fp); - } - putc ('\n', fp); - - rawdata_off = get32 (buffer + 8); - rawdata_len = get32 (buffer + 12); - - fprintf( fp, "Data-Offset: %lu\n", rawdata_off ); - fprintf( fp, "Data-Length: %lu\n", rawdata_len ); - - nkeys = get16 (buffer + 16); - fprintf (fp, "Key-Count: %lu\n", nkeys ); - if (!nkeys) - fprintf (fp, "[Error: no keys]\n"); - if (nkeys > 1 && type == BLOBTYPE_X509) - fprintf (fp, "[Error: only one key allowed for X509]\n"); - - keyinfolen = get16 (buffer + 18 ); - fprintf (fp, "Key-Info-Length: %lu\n", keyinfolen); - /* fixme: check bounds */ - p = buffer + 20; - for (n=0; n < nkeys; n++, p += keyinfolen) - { - int i; - ulong kidoff, kflags; - - fprintf (fp, "Key-Fpr[%lu]: ", n ); - for (i=0; i < 20; i++ ) - fprintf (fp, "%02X", p[i]); - kidoff = get32 (p + 20); - fprintf (fp, "\nKey-Kid-Off[%lu]: %lu\n", n, kidoff ); - fprintf (fp, "Key-Kid[%lu]: ", n ); - /* fixme: check bounds */ - for (i=0; i < 8; i++ ) - fprintf (fp, "%02X", buffer[kidoff+i] ); - kflags = get16 (p + 24 ); - fprintf( fp, "\nKey-Flags[%lu]: %04lX\n", n, kflags); - } - - /* serial number */ - fputs ("Serial-No: ", fp); - nserial = get16 (p); - p += 2; - if (!nserial) - fputs ("none", fp); - else - { - for (; nserial; nserial--, p++) - fprintf (fp, "%02X", *p); - } - putc ('\n', fp); - - /* user IDs */ - nuids = get16 (p); - fprintf (fp, "Uid-Count: %lu\n", nuids ); - uidinfolen = get16 (p + 2); - fprintf (fp, "Uid-Info-Length: %lu\n", uidinfolen); - /* fixme: check bounds */ - p += 4; - for (n=0; n < nuids; n++, p += uidinfolen) - { - ulong uidoff, uidlen, uflags; - - uidoff = get32( p ); - uidlen = get32( p+4 ); - if (type == BLOBTYPE_X509 && !n) - { - fprintf (fp, "Issuer-Off: %lu\n", uidoff ); - fprintf (fp, "Issuer-Len: %lu\n", uidlen ); - fprintf (fp, "Issuer: \""); - } - else if (type == BLOBTYPE_X509 && n == 1) - { - fprintf (fp, "Subject-Off: %lu\n", uidoff ); - fprintf (fp, "Subject-Len: %lu\n", uidlen ); - fprintf (fp, "Subject: \""); - } - else - { - fprintf (fp, "Uid-Off[%lu]: %lu\n", n, uidoff ); - fprintf (fp, "Uid-Len[%lu]: %lu\n", n, uidlen ); - fprintf (fp, "Uid[%lu]: \"", n ); - } - print_string (fp, buffer+uidoff, uidlen, '\"'); - fputs ("\"\n", fp); - uflags = get16 (p + 8); - if (type == BLOBTYPE_X509 && !n) - { - fprintf (fp, "Issuer-Flags: %04lX\n", uflags ); - fprintf (fp, "Issuer-Validity: %d\n", p[10] ); - } - else if (type == BLOBTYPE_X509 && n == 1) - { - fprintf (fp, "Subject-Flags: %04lX\n", uflags ); - fprintf (fp, "Subject-Validity: %d\n", p[10] ); - } - else - { - fprintf (fp, "Uid-Flags[%lu]: %04lX\n", n, uflags ); - fprintf (fp, "Uid-Validity[%lu]: %d\n", n, p[10] ); - } - } - - nsigs = get16 (p); - fprintf (fp, "Sig-Count: %lu\n", nsigs ); - siginfolen = get16 (p + 2); - fprintf (fp, "Sig-Info-Length: %lu\n", siginfolen ); - /* fixme: check bounds */ - p += 4; - for (n=0; n < nsigs; n++, p += siginfolen) - { - ulong sflags; - - sflags = get32 (p); - fprintf (fp, "Sig-Expire[%lu]: ", n ); - if (!sflags) - fputs ("[not checked]", fp); - else if (sflags == 1 ) - fputs ("[missing key]", fp); - else if (sflags == 2 ) - fputs ("[bad signature]", fp); - else if (sflags < 0x10000000) - fprintf (fp, "[bad flag %0lx]", sflags); - else if (sflags == 0xffffffff) - fputs ("0", fp ); - else - fputs ("a time"/*strtimestamp( sflags )*/, fp ); - putc ('\n', fp ); - } - - fprintf (fp, "Ownertrust: %d\n", p[0] ); - fprintf (fp, "All-Validity: %d\n", p[1] ); - p += 4; - n = get32 (p); p += 4; - fprintf (fp, "Recheck-After: %lu\n", n ); - n = get32 (p ); p += 4; - fprintf( fp, "Latest-Timestamp: %lu\n", n ); - n = get32 (p ); p += 4; - fprintf (fp, "Created-At: %lu\n", n ); - n = get32 (p ); p += 4; - fprintf (fp, "Reserved-Space: %lu\n", n ); - - /* check that the keyblock is at the correct offset and other bounds */ - /*fprintf (fp, "Blob-Checksum: [MD5-hash]\n");*/ - return 0; -} - - -struct file_stats_s -{ - unsigned long too_short_blobs; - unsigned long too_large_blobs; - unsigned long total_blob_count; - unsigned long empty_blob_count; - unsigned long header_blob_count; - unsigned long pgp_blob_count; - unsigned long x509_blob_count; - unsigned long unknown_blob_count; - unsigned long non_flagged; - unsigned long secret_flagged; - unsigned long ephemeral_flagged; -}; - -static int -update_stats (KEYBOXBLOB blob, struct file_stats_s *s) -{ - const unsigned char *buffer; - size_t length; - int type; - unsigned long n; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 32) - { - s->too_short_blobs++; - return -1; - } - - n = get32( buffer ); - if (n > length) - s->too_large_blobs++; - else - length = n; /* ignore the rest */ - - s->total_blob_count++; - type = buffer[4]; - switch (type) - { - case BLOBTYPE_EMPTY: - s->empty_blob_count++; - return 0; - case BLOBTYPE_HEADER: - s->header_blob_count++; - return 0; - case BLOBTYPE_PGP: - s->pgp_blob_count++; - break; - case BLOBTYPE_X509: - s->x509_blob_count++; - break; - default: - s->unknown_blob_count++; - return 0; - } - - if (length < 40) - { - s->too_short_blobs++; - return -1; - } - - n = get16 (buffer + 6); - if (n) - { - if ((n & 1)) - s->secret_flagged++; - if ((n & 2)) - s->ephemeral_flagged++; - } - else - s->non_flagged++; - - return 0; -} - - - -int -_keybox_dump_file (const char *filename, int stats_only, FILE *outfp) -{ - FILE *fp; - KEYBOXBLOB blob; - int rc; - unsigned long count = 0; - struct file_stats_s stats; - - memset (&stats, 0, sizeof stats); - - if (!filename) - { - filename = "-"; - fp = stdin; - } - else - fp = fopen (filename, "rb"); - if (!fp) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - fprintf (outfp, "can't open `%s': %s\n", filename, strerror(errno)); - return tmperr; - } - - while ( !(rc = _keybox_read_blob (&blob, fp)) ) - { - if (stats_only) - { - update_stats (blob, &stats); - } - else - { - fprintf (outfp, "BEGIN-RECORD: %lu\n", count ); - _keybox_dump_blob (blob, outfp); - fprintf (outfp, "END-RECORD\n"); - } - _keybox_release_blob (blob); - count++; - } - if (rc == -1) - rc = 0; - if (rc) - fprintf (outfp, "error reading `%s': %s\n", filename, gpg_strerror (rc)); - - if (fp != stdin) - fclose (fp); - - if (stats_only) - { - fprintf (outfp, - "Total number of blobs: %8lu\n" - " header: %8lu\n" - " empty: %8lu\n" - " openpgp: %8lu\n" - " x509: %8lu\n" - " non flagged: %8lu\n" - " secret flagged: %8lu\n" - " ephemeral flagged: %8lu\n", - stats.total_blob_count, - stats.header_blob_count, - stats.empty_blob_count, - stats.pgp_blob_count, - stats.x509_blob_count, - stats.non_flagged, - stats.secret_flagged, - stats.ephemeral_flagged); - if (stats.unknown_blob_count) - fprintf (outfp, " unknown blob types: %8lu\n", - stats.unknown_blob_count); - if (stats.too_short_blobs) - fprintf (outfp, " too short blobs: %8lu\n", - stats.too_short_blobs); - if (stats.too_large_blobs) - fprintf (outfp, " too large blobs: %8lu\n", - stats.too_large_blobs); - } - - return rc; -} diff --git a/kbx/keybox-errors.c b/kbx/keybox-errors.c deleted file mode 100644 index e11efc10b..000000000 --- a/kbx/keybox-errors.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Generated automatically by mkerrors */ -/* Do not edit! */ - -#include <stdio.h> -#include "keybox-defs.h" - -/** - * keybox_strerror: - * @err: Error code - * - * This function returns a textual representaion of the given - * errorcode. If this is an unknown value, a string with the value - * is returned (Beware: it is hold in a static buffer). - * - * Return value: String with the error description. - **/ -const char * -keybox_strerror (KeyboxError err) -{ - const char *s; - static char buf[25]; - - switch (err) - { - case KEYBOX_No_Error: s="no error"; break; - case KEYBOX_General_Error: s="general error"; break; - case KEYBOX_Out_Of_Core: s="out of core"; break; - case KEYBOX_Invalid_Value: s="invalid value"; break; - case KEYBOX_Timeout: s="timeout"; break; - case KEYBOX_Read_Error: s="read error"; break; - case KEYBOX_Write_Error: s="write error"; break; - case KEYBOX_File_Error: s="file error"; break; - case KEYBOX_Blob_Too_Short: s="blob too short"; break; - case KEYBOX_Blob_Too_Large: s="blob too large"; break; - case KEYBOX_Invalid_Handle: s="invalid handle"; break; - case KEYBOX_File_Create_Error: s="file create error"; break; - case KEYBOX_File_Open_Error: s="file open error"; break; - case KEYBOX_File_Close_Error: s="file close error"; break; - case KEYBOX_Nothing_Found: s="nothing found"; break; - case KEYBOX_Wrong_Blob_Type: s="wrong blob type"; break; - case KEYBOX_Missing_Value: s="missing value"; break; - default: sprintf (buf, "ec=%d", err ); s=buf; break; - } - - return s; -} - diff --git a/kbx/keybox-file.c b/kbx/keybox-file.c deleted file mode 100644 index db3164fef..000000000 --- a/kbx/keybox-file.c +++ /dev/null @@ -1,146 +0,0 @@ -/* keybox-file.c - file oeprations - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <time.h> - -#include "keybox-defs.h" - -/* Read a block at the current postion and return it in r_blob. - r_blob may be NULL to simply skip the current block */ -int -_keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted) -{ - char *image; - size_t imagelen = 0; - int c1, c2, c3, c4, type; - int rc; - off_t off; - - *skipped_deleted = 0; - again: - *r_blob = NULL; - off = ftello (fp); - if (off == (off_t)-1) - return gpg_error (gpg_err_code_from_errno (errno)); - - if ((c1 = getc (fp)) == EOF - || (c2 = getc (fp)) == EOF - || (c3 = getc (fp)) == EOF - || (c4 = getc (fp)) == EOF - || (type = getc (fp)) == EOF) - { - if ( c1 == EOF && !ferror (fp) ) - return -1; /* eof */ - return gpg_error (gpg_err_code_from_errno (errno)); - } - - imagelen = (c1 << 24) | (c2 << 16) | (c3 << 8 ) | c4; - if (imagelen > 500000) /* Sanity check. */ - return gpg_error (GPG_ERR_TOO_LARGE); - - if (imagelen < 5) - return gpg_error (GPG_ERR_TOO_SHORT); - - if (!type) - { - /* Special treatment for empty blobs. */ - if (fseek (fp, imagelen-5, SEEK_CUR)) - return gpg_error (gpg_err_code_from_errno (errno)); - *skipped_deleted = 1; - goto again; - } - - image = xtrymalloc (imagelen); - if (!image) - return gpg_error (gpg_err_code_from_errno (errno)); - - image[0] = c1; image[1] = c2; image[2] = c3; image[3] = c4; image[4] = type; - if (fread (image+5, imagelen-5, 1, fp) != 1) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - xfree (image); - return tmperr; - } - - rc = r_blob? _keybox_new_blob (r_blob, image, imagelen, off) : 0; - if (rc || !r_blob) - xfree (image); - return rc; -} - -int -_keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp) -{ - int dummy; - return _keybox_read_blob2 (r_blob, fp, &dummy); -} - - -/* Write the block to the current file position */ -int -_keybox_write_blob (KEYBOXBLOB blob, FILE *fp) -{ - const char *image; - size_t length; - - image = _keybox_get_blob_image (blob, &length); - if (fwrite (image, length, 1, fp) != 1) - return gpg_error (gpg_err_code_from_errno (errno)); - return 0; -} - - -/* Write a fresh header type blob. */ -int -_keybox_write_header_blob (FILE *fp) -{ - unsigned char image[32]; - u32 val; - - memset (image, 0, sizeof image); - /* Length of this blob. */ - image[3] = 32; - - image[4] = BLOBTYPE_HEADER; - image[5] = 1; /* Version */ - - memcpy (image+8, "KBXf", 4); - val = time (NULL); - /* created_at and last maintenance run. */ - image[16] = (val >> 24); - image[16+1] = (val >> 16); - image[16+2] = (val >> 8); - image[16+3] = (val ); - image[20] = (val >> 24); - image[20+1] = (val >> 16); - image[20+2] = (val >> 8); - image[20+3] = (val ); - - if (fwrite (image, 32, 1, fp) != 1) - return gpg_error (gpg_err_code_from_errno (errno)); - return 0; -} - - diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c deleted file mode 100644 index e11c4f09c..000000000 --- a/kbx/keybox-init.c +++ /dev/null @@ -1,127 +0,0 @@ -/* keybox-init.c - Initalization of the library - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <assert.h> - -#include "keybox-defs.h" - -#define compare_filenames strcmp - -static KB_NAME kb_names; - - -/* - Register a filename for plain keybox files. Returns a pointer to be - used to create a handles etc or NULL to indicate that it has already - been registered */ -void * -keybox_register_file (const char *fname, int secret) -{ - KB_NAME kr; - - for (kr=kb_names; kr; kr = kr->next) - { - if ( !compare_filenames (kr->fname, fname) ) - return NULL; /* already registered */ - } - - kr = xtrymalloc (sizeof *kr + strlen (fname)); - if (!kr) - return NULL; - strcpy (kr->fname, fname); - kr->secret = !!secret; - /* kr->lockhd = NULL;*/ - kr->is_locked = 0; - kr->did_full_scan = 0; - /* keep a list of all issued pointers */ - kr->next = kb_names; - kb_names = kr; - - /* create the offset table the first time a function here is used */ -/* if (!kb_offtbl) */ -/* kb_offtbl = new_offset_hash_table (); */ - - return kr; -} - -int -keybox_is_writable (void *token) -{ - KB_NAME r = token; - - return r? !access (r->fname, W_OK) : 0; -} - - - -/* Create a new handle for the resource associated with TOKEN. SECRET - is just a cross-check. - - The returned handle must be released using keybox_release (). */ -KEYBOX_HANDLE -keybox_new (void *token, int secret) -{ - KEYBOX_HANDLE hd; - KB_NAME resource = token; - - assert (resource && !resource->secret == !secret); - hd = xtrycalloc (1, sizeof *hd); - if (hd) - { - hd->kb = resource; - hd->secret = !!secret; - } - return hd; -} - -void -keybox_release (KEYBOX_HANDLE hd) -{ - if (!hd) - return; - _keybox_release_blob (hd->found.blob); - xfree (hd->word_match.name); - xfree (hd->word_match.pattern); - xfree (hd); -} - - -const char * -keybox_get_resource_name (KEYBOX_HANDLE hd) -{ - if (!hd || !hd->kb) - return NULL; - return hd->kb->fname; -} - -int -keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes) -{ - if (!hd) - return gpg_error (GPG_ERR_INV_HANDLE); - hd->ephemeral = yes; - return 0; -} - diff --git a/kbx/keybox-search-desc.h b/kbx/keybox-search-desc.h deleted file mode 100644 index 4be59c27d..000000000 --- a/kbx/keybox-search-desc.h +++ /dev/null @@ -1,72 +0,0 @@ -/* keybox-search-desc.h - Keybox serch description - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* - This file is a temporary kludge until we can come up with solution - to share this description between keybox and the application - specific keydb -*/ - -#ifndef KEYBOX_SEARCH_DESC_H -#define KEYBOX_SEARCH_DESC_H 1 - -typedef enum { - KEYDB_SEARCH_MODE_NONE, - KEYDB_SEARCH_MODE_EXACT, - KEYDB_SEARCH_MODE_SUBSTR, - KEYDB_SEARCH_MODE_MAIL, - KEYDB_SEARCH_MODE_MAILSUB, - KEYDB_SEARCH_MODE_MAILEND, - KEYDB_SEARCH_MODE_WORDS, - KEYDB_SEARCH_MODE_SHORT_KID, - KEYDB_SEARCH_MODE_LONG_KID, - KEYDB_SEARCH_MODE_FPR16, - KEYDB_SEARCH_MODE_FPR20, - KEYDB_SEARCH_MODE_FPR, - KEYDB_SEARCH_MODE_ISSUER, - KEYDB_SEARCH_MODE_ISSUER_SN, - KEYDB_SEARCH_MODE_SN, - KEYDB_SEARCH_MODE_SUBJECT, - KEYDB_SEARCH_MODE_FIRST, - KEYDB_SEARCH_MODE_NEXT -} KeydbSearchMode; - -struct keydb_search_desc { - KeydbSearchMode mode; - int (*skipfnc)(void *,void*); /* used to be: void*, u32* */ - void *skipfncvalue; - const unsigned char *sn; - int snlen; /* -1 := sn is a hex string */ - union { - const char *name; - unsigned char fpr[24]; - unsigned char kid[8]; - } u; -}; - - -struct keydb_search_desc; -typedef struct keydb_search_desc KEYDB_SEARCH_DESC; - -typedef struct keydb_search_desc KEYBOX_SEARCH_DESC; - - - -#endif /*KEYBOX_SEARCH_DESC_H*/ diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c deleted file mode 100644 index 2ce3c1923..000000000 --- a/kbx/keybox-search.c +++ /dev/null @@ -1,944 +0,0 @@ -/* keybox-search.c - Search operations - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <errno.h> - -#include "../jnlib/stringhelp.h" /* ascii_xxxx() */ - -#include "keybox-defs.h" - - -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) - - -struct sn_array_s { - int snlen; - unsigned char *sn; -}; - - - -static inline ulong -get32 (const byte *buffer) -{ - ulong a; - a = *buffer << 24; - a |= buffer[1] << 16; - a |= buffer[2] << 8; - a |= buffer[3]; - return a; -} - -static inline ulong -get16 (const byte *buffer) -{ - ulong a; - a = *buffer << 8; - a |= buffer[1]; - return a; -} - - - -static inline int -blob_get_type (KEYBOXBLOB blob) -{ - const unsigned char *buffer; - size_t length; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 32) - return -1; /* blob too short */ - - return buffer[4]; -} - -static inline unsigned int -blob_get_blob_flags (KEYBOXBLOB blob) -{ - const unsigned char *buffer; - size_t length; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 8) - return 0; /* oops */ - - return get16 (buffer + 6); -} - - -/* Return information on the flag WHAT within the blob BUFFER,LENGTH. - Return the offset and the length (in bytes) of the flag in - FLAGOFF,FLAG_SIZE. */ -gpg_err_code_t -_keybox_get_flag_location (const unsigned char *buffer, size_t length, - int what, size_t *flag_off, size_t *flag_size) -{ - size_t pos; - size_t nkeys, keyinfolen; - size_t nuids, uidinfolen; - size_t nserial; - size_t nsigs, siginfolen; - - switch (what) - { - case KEYBOX_FLAG_BLOB: - if (length < 8) - return GPG_ERR_INV_OBJ; - *flag_off = 6; - *flag_size = 2; - break; - - case KEYBOX_FLAG_OWNERTRUST: - case KEYBOX_FLAG_VALIDITY: - case KEYBOX_FLAG_CREATED_AT: - if (length < 20) - return GPG_ERR_INV_OBJ; - /* Key info. */ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return GPG_ERR_INV_OBJ; - pos = 20 + keyinfolen*nkeys; - if (pos+2 > length) - return GPG_ERR_INV_OBJ; /* Out of bounds. */ - /* Serial number. */ - nserial = get16 (buffer+pos); - pos += 2 + nserial; - if (pos+4 > length) - return GPG_ERR_INV_OBJ; /* Out of bounds. */ - /* User IDs. */ - nuids = get16 (buffer + pos); pos += 2; - uidinfolen = get16 (buffer + pos); pos += 2; - if (uidinfolen < 12 ) - return GPG_ERR_INV_OBJ; - pos += uidinfolen*nuids; - if (pos+4 > length) - return GPG_ERR_INV_OBJ ; /* Out of bounds. */ - /* Signature info. */ - nsigs = get16 (buffer + pos); pos += 2; - siginfolen = get16 (buffer + pos); pos += 2; - if (siginfolen < 4 ) - return GPG_ERR_INV_OBJ; - pos += siginfolen*nsigs; - if (pos+1+1+2+4+4+4+4 > length) - return GPG_ERR_INV_OBJ ; /* Out of bounds. */ - *flag_size = 1; - *flag_off = pos; - switch (what) - { - case KEYBOX_FLAG_VALIDITY: - *flag_off += 1; - break; - case KEYBOX_FLAG_CREATED_AT: - *flag_size = 4; - *flag_off += 1+2+4+4+4; - break; - default: - break; - } - break; - - default: - return GPG_ERR_INV_FLAG; - } - return 0; -} - - - -/* Return one of the flags WHAT in VALUE from teh blob BUFFER of - LENGTH bytes. Return 0 on success or an raw error code. */ -static gpg_err_code_t -get_flag_from_image (const unsigned char *buffer, size_t length, - int what, unsigned int *value) -{ - gpg_err_code_t ec; - size_t pos, size; - - *value = 0; - ec = _keybox_get_flag_location (buffer, length, what, &pos, &size); - if (!ec) - switch (size) - { - case 1: *value = buffer[pos]; break; - case 2: *value = get16 (buffer + pos); break; - case 4: *value = get32 (buffer + pos); break; - default: ec = GPG_ERR_BUG; break; - } - - return ec; -} - - -static int -blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off; - size_t nkeys, keyinfolen; - size_t nserial; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20 + keyinfolen*nkeys; - if (pos+2 > length) - return 0; /* out of bounds */ - - /*serial*/ - nserial = get16 (buffer+pos); - off = pos + 2; - if (off+nserial > length) - return 0; /* out of bounds */ - - return nserial == snlen && !memcmp (buffer+off, sn, snlen); -} - - -static int -blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off; - size_t nkeys, keyinfolen; - int idx; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20; - if (pos + keyinfolen*nkeys > length) - return 0; /* out of bounds */ - - for (idx=0; idx < nkeys; idx++) - { - off = pos + idx*keyinfolen; - if (!memcmp (buffer + off, fpr, 20)) - return 1; /* found */ - } - return 0; /* not found */ -} - -static int -blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr, - int fproff, int fprlen) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off; - size_t nkeys, keyinfolen; - int idx; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20; - if (pos + keyinfolen*nkeys > length) - return 0; /* out of bounds */ - - for (idx=0; idx < nkeys; idx++) - { - off = pos + idx*keyinfolen; - if (!memcmp (buffer + off + fproff, fpr, fprlen)) - return 1; /* found */ - } - return 0; /* not found */ -} - - -static int -blob_cmp_name (KEYBOXBLOB blob, int idx, - const char *name, size_t namelen, int substr) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off, len; - size_t nkeys, keyinfolen; - size_t nuids, uidinfolen; - size_t nserial; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20 + keyinfolen*nkeys; - if (pos+2 > length) - return 0; /* out of bounds */ - - /*serial*/ - nserial = get16 (buffer+pos); - pos += 2 + nserial; - if (pos+4 > length) - return 0; /* out of bounds */ - - /* user ids*/ - nuids = get16 (buffer + pos); pos += 2; - uidinfolen = get16 (buffer + pos); pos += 2; - if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */) - return 0; /* invalid blob */ - if (pos + uidinfolen*nuids > length) - return 0; /* out of bounds */ - - if (idx < 0) - { /* compare all names starting with that (negated) index */ - idx = -idx; - - for ( ;idx < nuids; idx++) - { - size_t mypos = pos; - - mypos += idx*uidinfolen; - off = get32 (buffer+mypos); - len = get32 (buffer+mypos+4); - if (off+len > length) - return 0; /* error: better stop here out of bounds */ - if (len < 1) - continue; /* empty name */ - if (substr) - { - if (ascii_memcasemem (buffer+off, len, name, namelen)) - return 1; /* found */ - } - else - { - if (len == namelen && !memcmp (buffer+off, name, len)) - return 1; /* found */ - } - } - return 0; /* not found */ - } - else - { - if (idx > nuids) - return 0; /* no user ID with that idx */ - pos += idx*uidinfolen; - off = get32 (buffer+pos); - len = get32 (buffer+pos+4); - if (off+len > length) - return 0; /* out of bounds */ - if (len < 1) - return 0; /* empty name */ - - if (substr) - { - return !!ascii_memcasemem (buffer+off, len, name, namelen); - } - else - { - return len == namelen && !memcmp (buffer+off, name, len); - } - } -} - - -/* compare all email addresses of the subject. With SUBSTR given as - True a substring search is done in the mail address */ -static int -blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off, len; - size_t nkeys, keyinfolen; - size_t nuids, uidinfolen; - size_t nserial; - int idx; - - /* fixme: this code is common to blob_cmp_mail */ - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20 + keyinfolen*nkeys; - if (pos+2 > length) - return 0; /* out of bounds */ - - /*serial*/ - nserial = get16 (buffer+pos); - pos += 2 + nserial; - if (pos+4 > length) - return 0; /* out of bounds */ - - /* user ids*/ - nuids = get16 (buffer + pos); pos += 2; - uidinfolen = get16 (buffer + pos); pos += 2; - if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */) - return 0; /* invalid blob */ - if (pos + uidinfolen*nuids > length) - return 0; /* out of bounds */ - - if (namelen < 1) - return 0; - - for (idx=1 ;idx < nuids; idx++) - { - size_t mypos = pos; - - mypos += idx*uidinfolen; - off = get32 (buffer+mypos); - len = get32 (buffer+mypos+4); - if (off+len > length) - return 0; /* error: better stop here out of bounds */ - if (len < 2 || buffer[off] != '<') - continue; /* empty name or trailing 0 not stored */ - len--; /* one back */ - if ( len < 3 || buffer[off+len] != '>') - continue; /* not a proper email address */ - len--; - if (substr) - { - if (ascii_memcasemem (buffer+off+1, len, name, namelen)) - return 1; /* found */ - } - else - { - if (len == namelen && !ascii_memcasecmp (buffer+off+1, name, len)) - return 1; /* found */ - } - } - return 0; /* not found */ -} - - - - -/* - The has_foo functions are used as helpers for search -*/ -static inline int -has_short_kid (KEYBOXBLOB blob, const unsigned char *kid) -{ - return blob_cmp_fpr_part (blob, kid+4, 16, 4); -} - -static inline int -has_long_kid (KEYBOXBLOB blob, const unsigned char *kid) -{ - return blob_cmp_fpr_part (blob, kid, 12, 8); -} - -static inline int -has_fingerprint (KEYBOXBLOB blob, const unsigned char *fpr) -{ - return blob_cmp_fpr (blob, fpr); -} - - -static inline int -has_issuer (KEYBOXBLOB blob, const char *name) -{ - size_t namelen; - - return_val_if_fail (name, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0); -} - -static inline int -has_issuer_sn (KEYBOXBLOB blob, const char *name, - const unsigned char *sn, int snlen) -{ - size_t namelen; - - return_val_if_fail (name, 0); - return_val_if_fail (sn, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - - return (blob_cmp_sn (blob, sn, snlen) - && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0)); -} - -static inline int -has_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) -{ - return_val_if_fail (sn, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - return blob_cmp_sn (blob, sn, snlen); -} - -static inline int -has_subject (KEYBOXBLOB blob, const char *name) -{ - size_t namelen; - - return_val_if_fail (name, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0); -} - -static inline int -has_subject_or_alt (KEYBOXBLOB blob, const char *name, int substr) -{ - size_t namelen; - - return_val_if_fail (name, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - return blob_cmp_name (blob, -1 /* all subject names*/, name, - namelen, substr); -} - - -static inline int -has_mail (KEYBOXBLOB blob, const char *name, int substr) -{ - size_t namelen; - - return_val_if_fail (name, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - if (namelen && name[namelen-1] == '>') - namelen--; - return blob_cmp_mail (blob, name, namelen, substr); -} - - -static void -release_sn_array (struct sn_array_s *array, size_t size) -{ - size_t n; - - for (n=0; n < size; n++) - xfree (array[n].sn); - xfree (array); -} - - -/* - - The search API - -*/ - -int -keybox_search_reset (KEYBOX_HANDLE hd) -{ - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if (hd->found.blob) - { - _keybox_release_blob (hd->found.blob); - hd->found.blob = NULL; - } - - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - hd->error = 0; - hd->eof = 0; - return 0; -} - - -/* Note: When in ephemeral mode the search function does visit all - blobs but in standard mode, blobs flagged as ephemeral are ignored. */ -int -keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) -{ - int rc; - size_t n; - int need_words, any_skip; - KEYBOXBLOB blob = NULL; - struct sn_array_s *sn_array = NULL; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - /* clear last found result */ - if (hd->found.blob) - { - _keybox_release_blob (hd->found.blob); - hd->found.blob = NULL; - } - - if (hd->error) - return hd->error; /* still in error state */ - if (hd->eof) - return -1; /* still EOF */ - - /* figure out what information we need */ - need_words = any_skip = 0; - for (n=0; n < ndesc; n++) - { - switch (desc[n].mode) - { - case KEYDB_SEARCH_MODE_WORDS: - need_words = 1; - break; - case KEYDB_SEARCH_MODE_FIRST: - /* always restart the search in this mode */ - keybox_search_reset (hd); - break; - default: - break; - } - if (desc[n].skipfnc) - any_skip = 1; - if (desc[n].snlen == -1 && !sn_array) - { - sn_array = xtrycalloc (ndesc, sizeof *sn_array); - if (!sn_array) - return (hd->error = gpg_error (gpg_err_code_from_errno (errno))); - } - } - - if (!hd->fp) - { - hd->fp = fopen (hd->kb->fname, "rb"); - if (!hd->fp) - { - hd->error = gpg_error (gpg_err_code_from_errno (errno)); - xfree (sn_array); - return hd->error; - } - } - - /* kludge: we need to convert an SN given as hexstring to it's - binary representation - in some cases we are not able to store it - in the search descriptor, because due to its usage it is not - possible to free allocated memory */ - if (sn_array) - { - const unsigned char *s; - int i, odd; - size_t snlen; - - for (n=0; n < ndesc; n++) - { - if (!desc[n].sn) - ; - else if (desc[n].snlen == -1) - { - unsigned char *sn; - - s = desc[n].sn; - for (i=0; *s && *s != '/'; s++, i++) - ; - odd = (i & 1); - snlen = (i+1)/2; - sn_array[n].sn = xtrymalloc (snlen); - if (!sn_array[n].sn) - { - hd->error = gpg_error (gpg_err_code_from_errno (errno)); - release_sn_array (sn_array, n); - return hd->error; - } - sn_array[n].snlen = snlen; - sn = sn_array[n].sn; - s = desc[n].sn; - if (odd) - { - *sn++ = xtoi_1 (s); - s++; - } - for (; *s && *s != '/'; s += 2) - *sn++ = xtoi_2 (s); - } - else - { - const unsigned char *sn; - - sn = desc[n].sn; - snlen = desc[n].snlen; - sn_array[n].sn = xtrymalloc (snlen); - if (!sn_array[n].sn) - { - hd->error = gpg_error (gpg_err_code_from_errno (errno)); - release_sn_array (sn_array, n); - return hd->error; - } - sn_array[n].snlen = snlen; - memcpy (sn_array[n].sn, sn, snlen); - } - } - } - - - for (;;) - { - unsigned int blobflags; - - _keybox_release_blob (blob); blob = NULL; - rc = _keybox_read_blob (&blob, hd->fp); - if (rc) - break; - - if (blob_get_type (blob) == BLOBTYPE_HEADER) - continue; - - - blobflags = blob_get_blob_flags (blob); - if (!hd->ephemeral && (blobflags & 2)) - continue; /* not in ephemeral mode but blob is flagged ephemeral */ - - for (n=0; n < ndesc; n++) - { - switch (desc[n].mode) - { - case KEYDB_SEARCH_MODE_NONE: - never_reached (); - break; - case KEYDB_SEARCH_MODE_EXACT: - if (has_subject_or_alt (blob, desc[n].u.name, 0)) - goto found; - break; - case KEYDB_SEARCH_MODE_MAIL: - if (has_mail (blob, desc[n].u.name, 0)) - goto found; - break; - case KEYDB_SEARCH_MODE_MAILSUB: - if (has_mail (blob, desc[n].u.name, 1)) - goto found; - break; - case KEYDB_SEARCH_MODE_SUBSTR: - if (has_subject_or_alt (blob, desc[n].u.name, 1)) - goto found; - break; - case KEYDB_SEARCH_MODE_MAILEND: - case KEYDB_SEARCH_MODE_WORDS: - never_reached (); /* not yet implemented */ - break; - case KEYDB_SEARCH_MODE_ISSUER: - if (has_issuer (blob, desc[n].u.name)) - goto found; - break; - case KEYDB_SEARCH_MODE_ISSUER_SN: - if (has_issuer_sn (blob, desc[n].u.name, - sn_array? sn_array[n].sn : desc[n].sn, - sn_array? sn_array[n].snlen : desc[n].snlen)) - goto found; - break; - case KEYDB_SEARCH_MODE_SN: - if (has_sn (blob, sn_array? sn_array[n].sn : desc[n].sn, - sn_array? sn_array[n].snlen : desc[n].snlen)) - goto found; - break; - case KEYDB_SEARCH_MODE_SUBJECT: - if (has_subject (blob, desc[n].u.name)) - goto found; - break; - case KEYDB_SEARCH_MODE_SHORT_KID: - if (has_short_kid (blob, desc[n].u.kid)) - goto found; - break; - case KEYDB_SEARCH_MODE_LONG_KID: - if (has_long_kid (blob, desc[n].u.kid)) - goto found; - break; - case KEYDB_SEARCH_MODE_FPR: - case KEYDB_SEARCH_MODE_FPR20: - if (has_fingerprint (blob, desc[n].u.fpr)) - goto found; - break; - case KEYDB_SEARCH_MODE_FIRST: - goto found; - break; - case KEYDB_SEARCH_MODE_NEXT: - goto found; - break; - default: - rc = gpg_error (GPG_ERR_INV_VALUE); - goto found; - } - } - continue; - found: - for (n=any_skip?0:ndesc; n < ndesc; n++) - { -/* if (desc[n].skipfnc */ -/* && desc[n].skipfnc (desc[n].skipfncvalue, aki)) */ -/* break; */ - } - if (n == ndesc) - break; /* got it */ - } - - if (!rc) - { - hd->found.blob = blob; - } - else if (rc == -1) - { - _keybox_release_blob (blob); - hd->eof = 1; - } - else - { - _keybox_release_blob (blob); - hd->error = rc; - } - - if (sn_array) - release_sn_array (sn_array, ndesc); - - return rc; -} - - - - -/* - Functions to return a certificate or a keyblock. To be used after - a successful search operation. -*/ -#ifdef KEYBOX_WITH_X509 -/* - Return the last found cert. Caller must free it. - */ -int -keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *r_cert) -{ - const unsigned char *buffer; - size_t length; - size_t cert_off, cert_len; - ksba_reader_t reader = NULL; - ksba_cert_t cert = NULL; - int rc; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - if (!hd->found.blob) - return gpg_error (GPG_ERR_NOTHING_FOUND); - - if (blob_get_type (hd->found.blob) != BLOBTYPE_X509) - return gpg_error (GPG_ERR_WRONG_BLOB_TYPE); - - buffer = _keybox_get_blob_image (hd->found.blob, &length); - if (length < 40) - return gpg_error (GPG_ERR_TOO_SHORT); - cert_off = get32 (buffer+8); - cert_len = get32 (buffer+12); - if (cert_off+cert_len > length) - return gpg_error (GPG_ERR_TOO_SHORT); - - rc = ksba_reader_new (&reader); - if (rc) - return rc; - rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len); - if (rc) - { - ksba_reader_release (reader); - /* fixme: need to map the error codes */ - return gpg_error (GPG_ERR_GENERAL); - } - - rc = ksba_cert_new (&cert); - if (rc) - { - ksba_reader_release (reader); - return rc; - } - - rc = ksba_cert_read_der (cert, reader); - if (rc) - { - ksba_cert_release (cert); - ksba_reader_release (reader); - /* fixme: need to map the error codes */ - return gpg_error (GPG_ERR_GENERAL); - } - - *r_cert = cert; - ksba_reader_release (reader); - return 0; -} - -#endif /*KEYBOX_WITH_X509*/ - -/* Return the flags named WHAT at the address of VALUE. IDX is used - only for certain flags and should be 0 if not required. */ -int -keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value) -{ - const unsigned char *buffer; - size_t length; - gpg_err_code_t ec; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - if (!hd->found.blob) - return gpg_error (GPG_ERR_NOTHING_FOUND); - - buffer = _keybox_get_blob_image (hd->found.blob, &length); - ec = get_flag_from_image (buffer, length, what, value); - return ec? gpg_error (ec):0; -} - diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c deleted file mode 100644 index 16955502f..000000000 --- a/kbx/keybox-update.c +++ /dev/null @@ -1,698 +0,0 @@ -/* keybox-update.c - keybox update operations - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <unistd.h> - -#include "keybox-defs.h" - -#define EXTSEP_S "." - - -static int -create_tmp_file (const char *template, - char **r_bakfname, char **r_tmpfname, FILE **r_fp) -{ - char *bakfname, *tmpfname; - - *r_bakfname = NULL; - *r_tmpfname = NULL; - -# ifdef USE_ONLY_8DOT3 - /* Here is another Windoze bug?: - * you cant rename("pubring.kbx.tmp", "pubring.kbx"); - * but rename("pubring.kbx.tmp", "pubring.aaa"); - * works. So we replace .kbx by .bak or .tmp - */ - if (strlen (template) > 4 - && !strcmp (template+strlen(template)-4, EXTSEP_S "kbx") ) - { - bakfname = xtrymalloc (strlen (template) + 1); - if (!bakfname) - return gpg_error (gpg_err_code_from_errno (errno)); - strcpy (bakfname, template); - strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak"); - - tmpfname = xtrymalloc (strlen (template) + 1); - if (!tmpfname) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - xfree (bakfname); - return tmperr; - } - strcpy (tmpfname,template); - strcpy (tmpfname + strlen (template)-4, EXTSEP_S "tmp"); - } - else - { /* file does not end with kbx; hmmm */ - bakfname = xtrymalloc ( strlen (template) + 5); - if (!bakfname) - return gpg_error (gpg_err_code_from_errno (errno)); - strcpy (stpcpy (bakfname, template), EXTSEP_S "bak"); - - tmpfname = xtrymalloc ( strlen (template) + 5); - if (!tmpfname) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - xfree (bakfname); - return tmperr; - } - strcpy (stpcpy (tmpfname, template), EXTSEP_S "tmp"); - } -# else /* Posix file names */ - bakfname = xtrymalloc (strlen (template) + 2); - if (!bakfname) - return gpg_error (gpg_err_code_from_errno (errno)); - strcpy (stpcpy (bakfname,template),"~"); - - tmpfname = xtrymalloc ( strlen (template) + 5); - if (!tmpfname) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - xfree (bakfname); - return tmperr; - } - strcpy (stpcpy (tmpfname,template), EXTSEP_S "tmp"); -# endif /* Posix filename */ - - *r_fp = fopen (tmpfname, "wb"); - if (!*r_fp) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - xfree (tmpfname); - xfree (bakfname); - return tmperr; - } - - *r_bakfname = bakfname; - *r_tmpfname = tmpfname; - return 0; -} - - -static int -rename_tmp_file (const char *bakfname, const char *tmpfname, - const char *fname, int secret ) -{ - int rc=0; - - /* restrict the permissions for secret keyboxs */ -#ifndef HAVE_DOSISH_SYSTEM -/* if (secret && !opt.preserve_permissions) */ -/* { */ -/* if (chmod (tmpfname, S_IRUSR | S_IWUSR) ) */ -/* { */ -/* log_debug ("chmod of `%s' failed: %s\n", */ -/* tmpfname, strerror(errno) ); */ -/* return KEYBOX_Write_File; */ -/* } */ -/* } */ -#endif - - /* fixme: invalidate close caches (not used with stdio)*/ -/* iobuf_ioctl (NULL, 2, 0, (char*)tmpfname ); */ -/* iobuf_ioctl (NULL, 2, 0, (char*)bakfname ); */ -/* iobuf_ioctl (NULL, 2, 0, (char*)fname ); */ - - /* first make a backup file except for secret keyboxs */ - if (!secret) - { -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove (bakfname); -#endif - if (rename (fname, bakfname) ) - { - return gpg_error (gpg_err_code_from_errno (errno)); - } - } - - /* then rename the file */ -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove (fname); -#endif - if (rename (tmpfname, fname) ) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - if (secret) - { -/* log_info ("WARNING: 2 files with confidential" */ -/* " information exists.\n"); */ -/* log_info ("%s is the unchanged one\n", fname ); */ -/* log_info ("%s is the new one\n", tmpfname ); */ -/* log_info ("Please fix this possible security flaw\n"); */ - } - return rc; - } - - return 0; -} - - - -/* Perform insert/delete/update operation. - mode 1 = insert - 2 = delete - 3 = update -*/ -static int -blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, - int secret, off_t start_offset, unsigned int n_packets ) -{ - FILE *fp, *newfp; - int rc=0; - char *bakfname = NULL; - char *tmpfname = NULL; - char buffer[4096]; - int nread, nbytes; - - /* Open the source file. Because we do a rename, we have to check the - permissions of the file */ - if (access (fname, W_OK)) - return gpg_error (gpg_err_code_from_errno (errno)); - - fp = fopen (fname, "rb"); - if (mode == 1 && !fp && errno == ENOENT) - { - /* Insert mode but file does not exist: - Create a new keybox file. */ - newfp = fopen (fname, "wb"); - if (!newfp ) - return gpg_error (gpg_err_code_from_errno (errno)); - - rc = _keybox_write_header_blob (newfp); - if (rc) - return rc; - - rc = _keybox_write_blob (blob, newfp); - if (rc) - return rc; - - if ( fclose (newfp) ) - return gpg_error (gpg_err_code_from_errno (errno)); - -/* if (chmod( fname, S_IRUSR | S_IWUSR )) */ -/* { */ -/* log_debug ("%s: chmod failed: %s\n", fname, strerror(errno) ); */ -/* return KEYBOX_File_Error; */ -/* } */ - return 0; /* Ready. */ - } - - if (!fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - - /* Create the new file. */ - rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); - if (rc) - { - fclose(fp); - goto leave; - } - - /* prepare for insert */ - if (mode == 1) - { - /* Copy everything to the new file. */ - while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 ) - { - if (fwrite (buffer, nread, 1, newfp) != 1) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - } - if (ferror (fp)) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - } - - /* Prepare for delete or update. */ - if ( mode == 2 || mode == 3 ) - { - off_t current = 0; - - /* Copy first part to the new file. */ - while ( current < start_offset ) - { - nbytes = DIM(buffer); - if (current + nbytes > start_offset) - nbytes = start_offset - current; - nread = fread (buffer, 1, nbytes, fp); - if (!nread) - break; - current += nread; - - if (fwrite (buffer, nread, 1, newfp) != 1) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - } - if (ferror (fp)) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - - /* Skip this blob. */ - rc = _keybox_read_blob (NULL, fp); - if (rc) - return rc; - } - - /* Do an insert or update. */ - if ( mode == 1 || mode == 3 ) - { - rc = _keybox_write_blob (blob, newfp); - if (rc) - return rc; - } - - /* Copy the rest of the packet for an delete or update. */ - if (mode == 2 || mode == 3) - { - while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 ) - { - if (fwrite (buffer, nread, 1, newfp) != 1) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - } - if (ferror (fp)) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - } - - /* Close both files. */ - if (fclose(fp)) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - fclose (newfp); - goto leave; - } - if (fclose(newfp)) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - - rc = rename_tmp_file (bakfname, tmpfname, fname, secret); - - leave: - xfree(bakfname); - xfree(tmpfname); - return rc; -} - - - -#ifdef KEYBOX_WITH_X509 -int -keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, - unsigned char *sha1_digest) -{ - int rc; - const char *fname; - KEYBOXBLOB blob; - - if (!hd) - return gpg_error (GPG_ERR_INV_HANDLE); - if (!hd->kb) - return gpg_error (GPG_ERR_INV_HANDLE); - fname = hd->kb->fname; - if (!fname) - return gpg_error (GPG_ERR_INV_HANDLE); - - /* Close this one otherwise we will mess up the position for a next - search. Fixme: it would be better to adjust the position after - the write opertions. */ - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - - rc = _keybox_create_x509_blob (&blob, cert, sha1_digest, hd->ephemeral); - if (!rc) - { - rc = blob_filecopy (1, fname, blob, hd->secret, 0, 0 ); - _keybox_release_blob (blob); - /* if (!rc && !hd->secret && kb_offtbl) */ - /* { */ - /* update_offset_hash_table_from_kb (kb_offtbl, kb, 0); */ - /* } */ - } - return rc; -} - -int -keybox_update_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, - unsigned char *sha1_digest) -{ - return -1; -} - - -#endif /*KEYBOX_WITH_X509*/ - -/* Note: We assume that the keybox has been locked before the current - search was executed. This is needed so that we can depend on the - offset information of the flags. */ -int -keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value) -{ - off_t off; - const char *fname; - FILE *fp; - gpg_err_code_t ec; - size_t flag_pos, flag_size; - const unsigned char *buffer; - size_t length; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - if (!hd->found.blob) - return gpg_error (GPG_ERR_NOTHING_FOUND); - if (!hd->kb) - return gpg_error (GPG_ERR_INV_HANDLE); - if (!hd->found.blob) - return gpg_error (GPG_ERR_NOTHING_FOUND); - fname = hd->kb->fname; - if (!fname) - return gpg_error (GPG_ERR_INV_HANDLE); - - off = _keybox_get_blob_fileoffset (hd->found.blob); - if (off == (off_t)-1) - return gpg_error (GPG_ERR_GENERAL); - - buffer = _keybox_get_blob_image (hd->found.blob, &length); - ec = _keybox_get_flag_location (buffer, length, what, &flag_pos, &flag_size); - if (ec) - return gpg_error (ec); - - off += flag_pos; - - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - fp = fopen (hd->kb->fname, "r+b"); - if (!fp) - return gpg_error (gpg_err_code_from_errno (errno)); - - ec = 0; - if (fseeko (fp, off, SEEK_SET)) - ec = gpg_error (gpg_err_code_from_errno (errno)); - else - { - unsigned char tmp[4]; - - tmp[0] = value >> 24; - tmp[1] = value >> 16; - tmp[2] = value >> 8; - tmp[3] = value; - - switch (flag_size) - { - case 1: - case 2: - case 4: - if (fwrite (tmp+4-flag_size, flag_size, 1, fp) != 1) - ec = gpg_err_code_from_errno (errno); - break; - default: - ec = GPG_ERR_BUG; - break; - } - } - - if (fclose (fp)) - { - if (!ec) - ec = gpg_err_code_from_errno (errno); - } - - return gpg_error (ec); -} - - - -int -keybox_delete (KEYBOX_HANDLE hd) -{ - off_t off; - const char *fname; - FILE *fp; - int rc; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - if (!hd->found.blob) - return gpg_error (GPG_ERR_NOTHING_FOUND); - if (!hd->kb) - return gpg_error (GPG_ERR_INV_HANDLE); - fname = hd->kb->fname; - if (!fname) - return gpg_error (GPG_ERR_INV_HANDLE); - - off = _keybox_get_blob_fileoffset (hd->found.blob); - if (off == (off_t)-1) - return gpg_error (GPG_ERR_GENERAL); - off += 4; - - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - - fp = fopen (hd->kb->fname, "r+b"); - if (!fp) - return gpg_error (gpg_err_code_from_errno (errno)); - - if (fseeko (fp, off, SEEK_SET)) - rc = gpg_error (gpg_err_code_from_errno (errno)); - else if (putc (0, fp) == EOF) - rc = gpg_error (gpg_err_code_from_errno (errno)); - else - rc = 0; - - if (fclose (fp)) - { - if (!rc) - rc = gpg_error (gpg_err_code_from_errno (errno)); - } - - return rc; -} - - -/* Compress the keybox file. This should be run with the file - locked. */ -int -keybox_compress (KEYBOX_HANDLE hd) -{ - int read_rc, rc; - const char *fname; - FILE *fp, *newfp; - char *bakfname = NULL; - char *tmpfname = NULL; - int first_blob; - KEYBOXBLOB blob = NULL; - u32 cut_time; - int any_changes = 0; - int skipped_deleted; - - if (!hd) - return gpg_error (GPG_ERR_INV_HANDLE); - if (!hd->kb) - return gpg_error (GPG_ERR_INV_HANDLE); - if (hd->secret) - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); - fname = hd->kb->fname; - if (!fname) - return gpg_error (GPG_ERR_INV_HANDLE); - - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - - /* Open the source file. Because we do a rename, we have to check the - permissions of the file */ - if (access (fname, W_OK)) - return gpg_error (gpg_err_code_from_errno (errno)); - - fp = fopen (fname, "rb"); - if (!fp && errno == ENOENT) - return 0; /* Ready. File has been deleted right after the access above. */ - if (!fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - return rc; - } - - /* A quick test to see if we need to compress the file at all. We - schedule a compress run after 3 hours. */ - if ( !_keybox_read_blob (&blob, fp) ) - { - const unsigned char *buffer; - size_t length; - - buffer = _keybox_get_blob_image (blob, &length); - if (length > 4 && buffer[4] == BLOBTYPE_HEADER) - { - u32 last_maint = ((buffer[20] << 24) | (buffer[20+1] << 16) - | (buffer[20+2] << 8) | (buffer[20+3])); - - if ( (last_maint + 3*3600) > time (NULL) ) - { - fclose (fp); - _keybox_release_blob (blob); - return 0; /* Compress run not yet needed. */ - } - } - _keybox_release_blob (blob); - rewind (fp); - } - - /* Create the new file. */ - rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); - if (rc) - { - fclose(fp); - return rc;; - } - - - /* Processing loop. By reading using _keybox_read_blob we - automagically skip and blobs flagged as deleted. Thus what we - only have to do is to check all ephemeral flagged blocks whether - their time has come and write out all other blobs. */ - cut_time = time(NULL) - 86400; - first_blob = 1; - skipped_deleted = 0; - for (rc=0; !(read_rc = _keybox_read_blob2 (&blob, fp, &skipped_deleted)); - _keybox_release_blob (blob), blob = NULL ) - { - unsigned int blobflags; - const unsigned char *buffer; - size_t length, pos, size; - u32 created_at; - - if (skipped_deleted) - any_changes = 1; - buffer = _keybox_get_blob_image (blob, &length); - if (first_blob) - { - first_blob = 0; - if (length > 4 && buffer[4] == BLOBTYPE_HEADER) - { - /* Write out the blob with an updated maintenance time stamp. */ - _keybox_update_header_blob (blob); - rc = _keybox_write_blob (blob, newfp); - if (rc) - break; - continue; - } - - /* The header blob is missing. Insert it. */ - rc = _keybox_write_header_blob (newfp); - if (rc) - break; - any_changes = 1; - } - else if (length > 4 && buffer[4] == BLOBTYPE_HEADER) - { - /* Oops: There is another header record - remove it. */ - any_changes = 1; - continue; - } - - if (_keybox_get_flag_location (buffer, length, - KEYBOX_FLAG_BLOB, &pos, &size) - || size != 2) - { - rc = gpg_error (GPG_ERR_BUG); - break; - } - blobflags = ((buffer[pos] << 8) | (buffer[pos+1])); - if ((blobflags & 2)) - { - /* This is an ephemeral blob. */ - if (_keybox_get_flag_location (buffer, length, - KEYBOX_FLAG_CREATED_AT, &pos, &size) - || size != 4) - created_at = 0; /* oops. */ - else - created_at = ((buffer[pos] << 24) | (buffer[pos+1] << 16) - | (buffer[pos+2] << 8) | (buffer[pos+3])); - - if (created_at && created_at < cut_time) - { - any_changes = 1; - continue; /* Skip this blob. */ - } - } - - rc = _keybox_write_blob (blob, newfp); - if (rc) - break; - } - if (skipped_deleted) - any_changes = 1; - _keybox_release_blob (blob); blob = NULL; - if (!rc && read_rc == -1) - rc = 0; - else if (!rc) - rc = read_rc; - - /* Close both files. */ - if (fclose(fp) && !rc) - rc = gpg_error (gpg_err_code_from_errno (errno)); - if (fclose(newfp) && !rc) - rc = gpg_error (gpg_err_code_from_errno (errno)); - - /* Rename or remove the temporary file. */ - if (rc || !any_changes) - remove (tmpfname); - else - rc = rename_tmp_file (bakfname, tmpfname, fname, hd->secret); - - xfree(bakfname); - xfree(tmpfname); - return rc; -} - diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c deleted file mode 100644 index ed5d93de0..000000000 --- a/kbx/keybox-util.c +++ /dev/null @@ -1,72 +0,0 @@ -/* keybox-util.c - Utility functions for Keybox - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include "keybox-defs.h" - - -static void *(*alloc_func)(size_t n) = malloc; -static void *(*realloc_func)(void *p, size_t n) = realloc; -static void (*free_func)(void*) = free; - - - -void -keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), - void *(*new_realloc_func)(void *p, size_t n), - void (*new_free_func)(void*) ) -{ - alloc_func = new_alloc_func; - realloc_func = new_realloc_func; - free_func = new_free_func; -} - -void * -_keybox_malloc (size_t n) -{ - return alloc_func (n); -} - -void * -_keybox_realloc (void *a, size_t n) -{ - return realloc_func (a, n); -} - -void * -_keybox_calloc (size_t n, size_t m) -{ - void *p = _keybox_malloc (n*m); - if (p) - memset (p, 0, n* m); - return p; -} - -void -_keybox_free (void *p) -{ - if (p) - free_func (p); -} - diff --git a/kbx/keybox.h b/kbx/keybox.h deleted file mode 100644 index af1fc4516..000000000 --- a/kbx/keybox.h +++ /dev/null @@ -1,115 +0,0 @@ -/* keybox.h - Keybox operations - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef KEYBOX_H -#define KEYBOX_H 1 -#ifdef __cplusplus -extern "C" { -#if 0 - } -#endif -#endif - -#include "keybox-search-desc.h" - -#define KEYBOX_WITH_OPENPGP 1 -#define KEYBOX_WITH_X509 1 - - -#ifdef KEYBOX_WITH_OPENPGP -# undef KEYBOX_WITH_OPENPGP -/*#include <lib-to-handle-gpg-data-structs.h>*/ -#endif - -#ifdef KEYBOX_WITH_X509 -# include <ksba.h> -#endif - -typedef struct keybox_handle *KEYBOX_HANDLE; - - -typedef enum - { - KEYBOX_FLAG_BLOB, /* The blob flags. */ - KEYBOX_FLAG_VALIDITY, /* The validity of the entire key. */ - KEYBOX_FLAG_OWNERTRUST, /* The assigned ownertrust. */ - KEYBOX_FLAG_KEY, /* The key flags; requires a key index. */ - KEYBOX_FLAG_UID, /* The user ID flags; requires an uid index. */ - KEYBOX_FLAG_UID_VALIDITY,/* The validity of a specific uid, requires - an uid index. */ - KEYBOX_FLAG_CREATED_AT /* The date the block was created. */ - } keybox_flag_t; - - -/*-- keybox-init.c --*/ -void *keybox_register_file (const char *fname, int secret); -int keybox_is_writable (void *token); - -KEYBOX_HANDLE keybox_new (void *token, int secret); -void keybox_release (KEYBOX_HANDLE hd); -const char *keybox_get_resource_name (KEYBOX_HANDLE hd); -int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes); - - -/*-- keybox-search.c --*/ -#ifdef KEYBOX_WITH_X509 -int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert); -#endif /*KEYBOX_WITH_X509*/ -int keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value); - -int keybox_search_reset (KEYBOX_HANDLE hd); -int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc); - - -/*-- keybox-update.c --*/ -#ifdef KEYBOX_WITH_X509 -int keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, - unsigned char *sha1_digest); -int keybox_update_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, - unsigned char *sha1_digest); -#endif /*KEYBOX_WITH_X509*/ -int keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value); - -int keybox_delete (KEYBOX_HANDLE hd); -int keybox_compress (KEYBOX_HANDLE hd); - - -/*-- --*/ - -#if 0 -int keybox_lock (KEYBOX_HANDLE hd, int yes); -int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb); -int keybox_locate_writable (KEYBOX_HANDLE hd); -int keybox_search_reset (KEYBOX_HANDLE hd); -int keybox_search (KEYBOX_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc); -int keybox_rebuild_cache (void *); -#endif - - -/*-- keybox-util.c --*/ -void keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), - void *(*new_realloc_func)(void *p, size_t n), - void (*new_free_func)(void*) ); - - -#ifdef __cplusplus -} -#endif -#endif /*KEYBOX_H*/ diff --git a/kbx/mkerrors b/kbx/mkerrors deleted file mode 100755 index 5adb7bfdf..000000000 --- a/kbx/mkerrors +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh -# mkerrors - Extract error strings from assuan.h -# and create C source for assuan_strerror -# Copyright (C) 2001 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -cat <<EOF -/* Generated automatically by mkerrors */ -/* Do not edit! */ - -#include <stdio.h> -#include "keybox-defs.h" - -/** - * keybox_strerror: - * @err: Error code - * - * This function returns a textual representaion of the given - * errorcode. If this is an unknown value, a string with the value - * is returned (Beware: it is hold in a static buffer). - * - * Return value: String with the error description. - **/ -const char * -keybox_strerror (KeyboxError err) -{ - const char *s; - static char buf[25]; - - switch (err) - { -EOF - -awk ' -/KEYBOX_No_Error/ { okay=1 } -!okay {next} -/}/ { exit 0 } -/KEYBOX_[A-Za-z_]*/ { print_code($1) } - - -function print_code( s ) -{ -printf " case %s: s=\"", s ; -gsub(/_/, " ", s ); -printf "%s\"; break;\n", tolower(substr(s,8)); -} -' - -cat <<EOF - default: sprintf (buf, "ec=%d", err ); s=buf; break; - } - - return s; -} - -EOF diff --git a/m4/ChangeLog b/m4/ChangeLog deleted file mode 100644 index efcded757..000000000 --- a/m4/ChangeLog +++ /dev/null @@ -1,30 +0,0 @@ -2004-03-06 Werner Koch <wk@gnupg.org> - - * libgcrypt.m4: Updated. - -2004-02-18 Werner Koch <wk@gnupg.org> - - * gpg-error.m4, libgcrypt.m4, libassuan.m4, ksba.m4: New. - * Makefile.am: Distribute them - -2003-04-29 gettextize <bug-gnu-gettext@gnu.org> - - * codeset.m4: New file, from gettext-0.11.5. - * gettext.m4: New file, from gettext-0.11.5. - * glibc21.m4: New file, from gettext-0.11.5. - * iconv.m4: New file, from gettext-0.11.5. - * intdiv0.m4: New file, from gettext-0.11.5. - * inttypes.m4: New file, from gettext-0.11.5. - * inttypes_h.m4: New file, from gettext-0.11.5. - * inttypes-pri.m4: New file, from gettext-0.11.5. - * isc-posix.m4: New file, from gettext-0.11.5. - * lcmessage.m4: New file, from gettext-0.11.5. - * lib-ld.m4: New file, from gettext-0.11.5. - * lib-link.m4: New file, from gettext-0.11.5. - * lib-prefix.m4: New file, from gettext-0.11.5. - * progtest.m4: New file, from gettext-0.11.5. - * stdint_h.m4: New file, from gettext-0.11.5. - * uintmax_t.m4: New file, from gettext-0.11.5. - * ulonglong.m4: New file, from gettext-0.11.5. - * Makefile.am: New file. - diff --git a/m4/Makefile.am b/m4/Makefile.am deleted file mode 100644 index 0eb02f694..000000000 --- a/m4/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -EXTRA_DIST = codeset.m4 gettext.m4 glibc21.m4 iconv.m4 intdiv0.m4 inttypes.m4 inttypes_h.m4 inttypes-pri.m4 isc-posix.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 progtest.m4 stdint_h.m4 uintmax_t.m4 ulonglong.m4 - -EXTRA_DIST += gpg-error.m4 libgcrypt.m4 libassuan.m4 ksba.m4 diff --git a/m4/codeset.m4 b/m4/codeset.m4 deleted file mode 100644 index 59535ebcf..000000000 --- a/m4/codeset.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# codeset.m4 serial AM1 (gettext-0.10.40) -dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -AC_DEFUN([AM_LANGINFO_CODESET], -[ - AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, - [AC_TRY_LINK([#include <langinfo.h>], - [char* cs = nl_langinfo(CODESET);], - am_cv_langinfo_codeset=yes, - am_cv_langinfo_codeset=no) - ]) - if test $am_cv_langinfo_codeset = yes; then - AC_DEFINE(HAVE_LANGINFO_CODESET, 1, - [Define if you have <langinfo.h> and nl_langinfo(CODESET).]) - fi -]) diff --git a/m4/gettext.m4 b/m4/gettext.m4 deleted file mode 100644 index 16070b40a..000000000 --- a/m4/gettext.m4 +++ /dev/null @@ -1,415 +0,0 @@ -# gettext.m4 serial 20 (gettext-0.12) -dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. -dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. - -dnl Macro to add for using GNU gettext. - -dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). -dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The -dnl default (if it is not specified or empty) is 'no-libtool'. -dnl INTLSYMBOL should be 'external' for packages with no intl directory, -dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. -dnl If INTLSYMBOL is 'use-libtool', then a libtool library -dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, -dnl depending on --{enable,disable}-{shared,static} and on the presence of -dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library -dnl $(top_builddir)/intl/libintl.a will be created. -dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext -dnl implementations (in libc or libintl) without the ngettext() function -dnl will be ignored. If NEEDSYMBOL is specified and is -dnl 'need-formatstring-macros', then GNU gettext implementations that don't -dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored. -dnl INTLDIR is used to find the intl libraries. If empty, -dnl the value `$(top_builddir)/intl/' is used. -dnl -dnl The result of the configuration is one of three cases: -dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled -dnl and used. -dnl Catalog format: GNU --> install in $(datadir) -dnl Catalog extension: .mo after installation, .gmo in source tree -dnl 2) GNU gettext has been found in the system's C library. -dnl Catalog format: GNU --> install in $(datadir) -dnl Catalog extension: .mo after installation, .gmo in source tree -dnl 3) No internationalization, always use English msgid. -dnl Catalog format: none -dnl Catalog extension: none -dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. -dnl The use of .gmo is historical (it was needed to avoid overwriting the -dnl GNU format catalogs when building on a platform with an X/Open gettext), -dnl but we keep it in order not to force irrelevant filename changes on the -dnl maintainers. -dnl -AC_DEFUN([AM_GNU_GETTEXT], -[ - dnl Argument checking. - ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , - [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT -])])])])]) - ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , - [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT -])])])]) - define(gt_included_intl, ifelse([$1], [external], [no], [yes])) - define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], [])) - - AC_REQUIRE([AM_PO_SUBDIRS])dnl - ifelse(gt_included_intl, yes, [ - AC_REQUIRE([AM_INTL_SUBDIR])dnl - ]) - - dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - - dnl Sometimes libintl requires libiconv, so first search for libiconv. - dnl Ideally we would do this search only after the - dnl if test "$USE_NLS" = "yes"; then - dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then - dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT - dnl the configure script would need to contain the same shell code - dnl again, outside any 'if'. There are two solutions: - dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. - dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. - dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not - dnl documented, we avoid it. - ifelse(gt_included_intl, yes, , [ - AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) - ]) - - dnl Set USE_NLS. - AM_NLS - - ifelse(gt_included_intl, yes, [ - BUILD_INCLUDED_LIBINTL=no - USE_INCLUDED_LIBINTL=no - ]) - LIBINTL= - LTLIBINTL= - POSUB= - - dnl If we use NLS figure out what method - if test "$USE_NLS" = "yes"; then - gt_use_preinstalled_gnugettext=no - ifelse(gt_included_intl, yes, [ - 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) - 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 GNU gettext is available we use this. Else we have - dnl to fall back to GNU NLS library. - - dnl Add a version number to the cache macros. - define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) - define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) - define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) - - AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, - [AC_TRY_LINK([#include <libintl.h> -]ifelse([$2], [need-formatstring-macros], -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern int *_nl_domain_bindings;], - [bindtextdomain ("", ""); -return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], - gt_cv_func_gnugettext_libc=yes, - gt_cv_func_gnugettext_libc=no)]) - - if test "$gt_cv_func_gnugettext_libc" != "yes"; then - dnl Sometimes libintl requires libiconv, so first search for libiconv. - ifelse(gt_included_intl, yes, , [ - AM_ICONV_LINK - ]) - dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL - dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) - dnl because that would add "-liconv" to LIBINTL and LTLIBINTL - dnl even if libiconv doesn't exist. - AC_LIB_LINKFLAGS_BODY([intl]) - AC_CACHE_CHECK([for GNU gettext in libintl], - gt_cv_func_gnugettext_libintl, - [gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $INCINTL" - gt_save_LIBS="$LIBS" - LIBS="$LIBS $LIBINTL" - dnl Now see whether libintl exists and does not depend on libiconv. - AC_TRY_LINK([#include <libintl.h> -]ifelse([$2], [need-formatstring-macros], -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias ();], - [bindtextdomain ("", ""); -return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], - gt_cv_func_gnugettext_libintl=yes, - gt_cv_func_gnugettext_libintl=no) - dnl Now see whether libintl exists and depends on libiconv. - if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then - LIBS="$LIBS $LIBICONV" - AC_TRY_LINK([#include <libintl.h> -]ifelse([$2], [need-formatstring-macros], -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias ();], - [bindtextdomain ("", ""); -return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], - [LIBINTL="$LIBINTL $LIBICONV" - LTLIBINTL="$LTLIBINTL $LTLIBICONV" - gt_cv_func_gnugettext_libintl=yes - ]) - fi - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS"]) - fi - - dnl If an already present or preinstalled GNU gettext() is found, - dnl use it. But if this macro is used in GNU gettext, and GNU - dnl gettext is already preinstalled in libintl, we update this - dnl libintl. (Cf. the install rule in intl/Makefile.in.) - if test "$gt_cv_func_gnugettext_libc" = "yes" \ - || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ - && test "$PACKAGE" != gettext-runtime \ - && test "$PACKAGE" != gettext-tools; }; then - gt_use_preinstalled_gnugettext=yes - else - dnl Reset the values set by searching for libintl. - LIBINTL= - LTLIBINTL= - INCINTL= - fi - - ifelse(gt_included_intl, yes, [ - if test "$gt_use_preinstalled_gnugettext" != "yes"; then - dnl GNU gettext is not found in the C library. - dnl Fall back on included 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. - BUILD_INCLUDED_LIBINTL=yes - USE_INCLUDED_LIBINTL=yes - LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" - LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" - LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` - fi - - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - dnl Mark actions to use GNU gettext tools. - CATOBJEXT=.gmo - fi - ]) - - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - AC_DEFINE(ENABLE_NLS, 1, - [Define to 1 if translation of program messages to the user's native language - is requested.]) - else - USE_NLS=no - fi - fi - - AC_MSG_CHECKING([whether to use NLS]) - AC_MSG_RESULT([$USE_NLS]) - if test "$USE_NLS" = "yes"; then - AC_MSG_CHECKING([where the gettext function comes from]) - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if test "$gt_cv_func_gnugettext_libintl" = "yes"; then - gt_source="external libintl" - else - gt_source="libc" - fi - else - gt_source="included intl directory" - fi - AC_MSG_RESULT([$gt_source]) - fi - - if test "$USE_NLS" = "yes"; then - - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if test "$gt_cv_func_gnugettext_libintl" = "yes"; then - AC_MSG_CHECKING([how to link with libintl]) - AC_MSG_RESULT([$LIBINTL]) - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) - fi - - dnl For backward compatibility. Some packages may be using this. - AC_DEFINE(HAVE_GETTEXT, 1, - [Define if the GNU gettext() function is already present or preinstalled.]) - AC_DEFINE(HAVE_DCGETTEXT, 1, - [Define if the GNU dcgettext() function is already present or preinstalled.]) - fi - - dnl We need to process the po/ directory. - POSUB=po - fi - - ifelse(gt_included_intl, yes, [ - dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL - dnl to 'yes' because some of the testsuite requires it. - if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then - BUILD_INCLUDED_LIBINTL=yes - fi - - dnl Make all variables we use known to autoconf. - AC_SUBST(BUILD_INCLUDED_LIBINTL) - AC_SUBST(USE_INCLUDED_LIBINTL) - AC_SUBST(CATOBJEXT) - - dnl For backward compatibility. Some configure.ins may be using this. - nls_cv_header_intl= - nls_cv_header_libgt= - - dnl For backward compatibility. Some Makefiles may be using this. - DATADIRNAME=share - AC_SUBST(DATADIRNAME) - - dnl For backward compatibility. Some Makefiles may be using this. - INSTOBJEXT=.mo - AC_SUBST(INSTOBJEXT) - - dnl For backward compatibility. Some Makefiles may be using this. - GENCAT=gencat - AC_SUBST(GENCAT) - - dnl For backward compatibility. Some Makefiles may be using this. - if test "$USE_INCLUDED_LIBINTL" = yes; then - INTLOBJS="\$(GETTOBJS)" - fi - AC_SUBST(INTLOBJS) - - dnl Enable libtool support if the surrounding package wishes it. - INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix - AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) - ]) - - dnl For backward compatibility. Some Makefiles may be using this. - INTLLIBS="$LIBINTL" - AC_SUBST(INTLLIBS) - - dnl Make all documented variables known to autoconf. - AC_SUBST(LIBINTL) - AC_SUBST(LTLIBINTL) - AC_SUBST(POSUB) -]) - - -dnl Checks for all prerequisites of the intl subdirectory, -dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, -dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. -AC_DEFUN([AM_INTL_SUBDIR], -[ - AC_REQUIRE([AC_PROG_INSTALL])dnl - AC_REQUIRE([AM_MKINSTALLDIRS])dnl - AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl - AC_REQUIRE([AC_PROG_RANLIB])dnl - AC_REQUIRE([AC_ISC_POSIX])dnl - AC_REQUIRE([AC_HEADER_STDC])dnl - AC_REQUIRE([AC_C_CONST])dnl - AC_REQUIRE([AC_C_INLINE])dnl - AC_REQUIRE([AC_TYPE_OFF_T])dnl - AC_REQUIRE([AC_TYPE_SIZE_T])dnl - AC_REQUIRE([AC_FUNC_ALLOCA])dnl - AC_REQUIRE([AC_FUNC_MMAP])dnl - AC_REQUIRE([jm_GLIBC21])dnl - AC_REQUIRE([gt_INTDIV0])dnl - AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl - AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl - AC_REQUIRE([gt_INTTYPES_PRI])dnl - - AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ -stdlib.h string.h unistd.h sys/param.h]) - AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getc_unlocked getcwd getegid \ -geteuid getgid getuid mempcpy munmap putenv setenv setlocale stpcpy \ -strcasecmp strdup strtoul tsearch __argz_count __argz_stringify __argz_next \ -__fsetlocking]) - - AM_ICONV - AM_LANGINFO_CODESET - if test $ac_cv_header_locale_h = yes; then - AM_LC_MESSAGES - fi - - dnl intl/plural.c is generated from intl/plural.y. It requires bison, - dnl because plural.y uses bison specific features. It requires at least - dnl bison-1.26 because earlier versions generate a plural.c that doesn't - dnl compile. - dnl bison is only needed for the maintainer (who touches plural.y). But in - dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put - dnl the rule in general Makefile. Now, some people carelessly touch the - dnl files or have a broken "make" program, hence the plural.c rule will - dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not - dnl present or too old. - AC_CHECK_PROGS([INTLBISON], [bison]) - if test -z "$INTLBISON"; then - ac_verc_fail=yes - else - dnl Found it, now check the version. - AC_MSG_CHECKING([version of bison]) -changequote(<<,>>)dnl - ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` - case $ac_prog_version in - '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) -changequote([,])dnl - ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; - *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; - esac - AC_MSG_RESULT([$ac_prog_version]) - fi - if test $ac_verc_fail = yes; then - INTLBISON=: - fi -]) - - -dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) -AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) diff --git a/m4/glibc21.m4 b/m4/glibc21.m4 deleted file mode 100644 index 9c9f3db30..000000000 --- a/m4/glibc21.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# glibc21.m4 serial 2 (fileutils-4.1.3, gettext-0.10.40) -dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -# Test for the GNU C Library, version 2.1 or newer. -# From Bruno Haible. - -AC_DEFUN([jm_GLIBC21], - [ - AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, - ac_cv_gnu_library_2_1, - [AC_EGREP_CPP([Lucky GNU user], - [ -#include <features.h> -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) - Lucky GNU user - #endif -#endif - ], - ac_cv_gnu_library_2_1=yes, - ac_cv_gnu_library_2_1=no) - ] - ) - AC_SUBST(GLIBC21) - GLIBC21="$ac_cv_gnu_library_2_1" - ] -) diff --git a/m4/gpg-error.m4 b/m4/gpg-error.m4 deleted file mode 100644 index 931630b14..000000000 --- a/m4/gpg-error.m4 +++ /dev/null @@ -1,56 +0,0 @@ -dnl Autoconf macros for libgpg-error - -dnl AM_PATH_GPG_ERROR([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libgpg-error and define GPG_ERROR_CFLAGS and GPG_ERROR_LIBS -dnl -AC_DEFUN(AM_PATH_GPG_ERROR, -[ AC_ARG_WITH(gpg-error-prefix, - AC_HELP_STRING([--with-gpg-error-prefix=PFX], - [prefix where GPG Error is installed (optional)]), - gpg_error_config_prefix="$withval", gpg_error_config_prefix="") - if test x$gpg_error_config_prefix != x ; then - if test x${GPG_ERROR_CONFIG+set} != xset ; then - GPG_ERROR_CONFIG=$gpg_error_config_prefix/bin/gpg-error-config - fi - fi - - AC_PATH_PROG(GPG_ERROR_CONFIG, gpg-error-config, no) - min_gpg_error_version=ifelse([$1], ,0.0,$1) - AC_MSG_CHECKING(for GPG Error - version >= $min_gpg_error_version) - ok=no - if test "$GPG_ERROR_CONFIG" != "no" ; then - req_major=`echo $min_gpg_error_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` - req_minor=`echo $min_gpg_error_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - gpg_error_config_version=`$GPG_ERROR_CONFIG $gpg_error_config_args --version` - major=`echo $gpg_error_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $gpg_error_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -ge "$req_minor"; then - ok=yes - fi - fi - fi - fi - if test $ok = yes; then - GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG $gpg_error_config_args --cflags` - GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --libs` - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - GPG_ERROR_CFLAGS="" - GPG_ERROR_LIBS="" - AC_MSG_RESULT(no) - ifelse([$3], , :, [$3]) - fi - AC_SUBST(GPG_ERROR_CFLAGS) - AC_SUBST(GPG_ERROR_LIBS) -]) - diff --git a/m4/iconv.m4 b/m4/iconv.m4 deleted file mode 100644 index c5f357982..000000000 --- a/m4/iconv.m4 +++ /dev/null @@ -1,103 +0,0 @@ -# iconv.m4 serial AM4 (gettext-0.11.3) -dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], -[ - dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - - dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV - dnl accordingly. - AC_LIB_LINKFLAGS_BODY([iconv]) -]) - -AC_DEFUN([AM_ICONV_LINK], -[ - dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and - dnl those with the standalone portable GNU libiconv installed). - - dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV - dnl accordingly. - AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) - - dnl Add $INCICONV to CPPFLAGS before performing the following checks, - dnl because if the user has installed libiconv and not disabled its use - dnl via --without-libiconv-prefix, he wants to use it. The first - dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. - am_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) - - AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ - am_cv_func_iconv="no, consider installing GNU libiconv" - am_cv_lib_iconv=no - AC_TRY_LINK([#include <stdlib.h> -#include <iconv.h>], - [iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);], - am_cv_func_iconv=yes) - if test "$am_cv_func_iconv" != yes; then - am_save_LIBS="$LIBS" - LIBS="$LIBS $LIBICONV" - AC_TRY_LINK([#include <stdlib.h> -#include <iconv.h>], - [iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);], - am_cv_lib_iconv=yes - am_cv_func_iconv=yes) - LIBS="$am_save_LIBS" - fi - ]) - if test "$am_cv_func_iconv" = yes; then - AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) - fi - if test "$am_cv_lib_iconv" = yes; then - AC_MSG_CHECKING([how to link with libiconv]) - AC_MSG_RESULT([$LIBICONV]) - else - dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV - dnl either. - CPPFLAGS="$am_save_CPPFLAGS" - LIBICONV= - LTLIBICONV= - fi - AC_SUBST(LIBICONV) - AC_SUBST(LTLIBICONV) -]) - -AC_DEFUN([AM_ICONV], -[ - AM_ICONV_LINK - if test "$am_cv_func_iconv" = yes; then - AC_MSG_CHECKING([for iconv declaration]) - AC_CACHE_VAL(am_cv_proto_iconv, [ - AC_TRY_COMPILE([ -#include <stdlib.h> -#include <iconv.h> -extern -#ifdef __cplusplus -"C" -#endif -#if defined(__STDC__) || defined(__cplusplus) -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif -], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) - am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - AC_MSG_RESULT([$]{ac_t:- - }[$]am_cv_proto_iconv) - AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, - [Define as const if the declaration of iconv() needs const.]) - fi -]) diff --git a/m4/intdiv0.m4 b/m4/intdiv0.m4 deleted file mode 100644 index 55dddcf1c..000000000 --- a/m4/intdiv0.m4 +++ /dev/null @@ -1,72 +0,0 @@ -# intdiv0.m4 serial 1 (gettext-0.11.3) -dnl Copyright (C) 2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -AC_DEFUN([gt_INTDIV0], -[ - AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl - - AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], - gt_cv_int_divbyzero_sigfpe, - [ - AC_TRY_RUN([ -#include <stdlib.h> -#include <signal.h> - -static void -#ifdef __cplusplus -sigfpe_handler (int sig) -#else -sigfpe_handler (sig) int sig; -#endif -{ - /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ - exit (sig != SIGFPE); -} - -int x = 1; -int y = 0; -int z; -int nan; - -int main () -{ - signal (SIGFPE, sigfpe_handler); -/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ -#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) - signal (SIGTRAP, sigfpe_handler); -#endif -/* Linux/SPARC yields signal SIGILL. */ -#if defined (__sparc__) && defined (__linux__) - signal (SIGILL, sigfpe_handler); -#endif - - z = x / y; - nan = y / y; - exit (1); -} -], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no, - [ - # Guess based on the CPU. - case "$host_cpu" in - alpha* | i[34567]86 | m68k | s390*) - gt_cv_int_divbyzero_sigfpe="guessing yes";; - *) - gt_cv_int_divbyzero_sigfpe="guessing no";; - esac - ]) - ]) - case "$gt_cv_int_divbyzero_sigfpe" in - *yes) value=1;; - *) value=0;; - esac - AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value, - [Define if integer division by zero raises signal SIGFPE.]) -]) diff --git a/m4/inttypes-pri.m4 b/m4/inttypes-pri.m4 deleted file mode 100644 index fd007c312..000000000 --- a/m4/inttypes-pri.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# inttypes-pri.m4 serial 1 (gettext-0.11.4) -dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -# Define PRI_MACROS_BROKEN if <inttypes.h> exists and defines the PRI* -# macros to non-string values. This is the case on AIX 4.3.3. - -AC_DEFUN([gt_INTTYPES_PRI], -[ - AC_REQUIRE([gt_HEADER_INTTYPES_H]) - if test $gt_cv_header_inttypes_h = yes; then - AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], - gt_cv_inttypes_pri_broken, - [ - AC_TRY_COMPILE([#include <inttypes.h> -#ifdef PRId32 -char *p = PRId32; -#endif -], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes) - ]) - fi - if test "$gt_cv_inttypes_pri_broken" = yes; then - AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1, - [Define if <inttypes.h> exists and defines unusable PRI* macros.]) - fi -]) diff --git a/m4/inttypes.m4 b/m4/inttypes.m4 deleted file mode 100644 index ab370ffe0..000000000 --- a/m4/inttypes.m4 +++ /dev/null @@ -1,27 +0,0 @@ -# inttypes.m4 serial 1 (gettext-0.11.4) -dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Paul Eggert. - -# Define HAVE_INTTYPES_H if <inttypes.h> exists and doesn't clash with -# <sys/types.h>. - -AC_DEFUN([gt_HEADER_INTTYPES_H], -[ - AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h, - [ - AC_TRY_COMPILE( - [#include <sys/types.h> -#include <inttypes.h>], - [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no) - ]) - if test $gt_cv_header_inttypes_h = yes; then - AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, - [Define if <inttypes.h> exists and doesn't clash with <sys/types.h>.]) - fi -]) diff --git a/m4/inttypes_h.m4 b/m4/inttypes_h.m4 deleted file mode 100644 index f342eba39..000000000 --- a/m4/inttypes_h.m4 +++ /dev/null @@ -1,28 +0,0 @@ -# inttypes_h.m4 serial 5 (gettext-0.12) -dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Paul Eggert. - -# Define HAVE_INTTYPES_H_WITH_UINTMAX if <inttypes.h> exists, -# doesn't clash with <sys/types.h>, and declares uintmax_t. - -AC_DEFUN([jm_AC_HEADER_INTTYPES_H], -[ - AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, - [AC_TRY_COMPILE( - [#include <sys/types.h> -#include <inttypes.h>], - [uintmax_t i = (uintmax_t) -1;], - jm_ac_cv_header_inttypes_h=yes, - jm_ac_cv_header_inttypes_h=no)]) - if test $jm_ac_cv_header_inttypes_h = yes; then - AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, - [Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, - and declares uintmax_t. ]) - fi -]) diff --git a/m4/isc-posix.m4 b/m4/isc-posix.m4 deleted file mode 100644 index 1319dd1c7..000000000 --- a/m4/isc-posix.m4 +++ /dev/null @@ -1,26 +0,0 @@ -# isc-posix.m4 serial 2 (gettext-0.11.2) -dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -# This file is not needed with autoconf-2.53 and newer. Remove it in 2005. - -# This test replaces the one in autoconf. -# Currently this macro should have the same name as the autoconf macro -# because gettext's gettext.m4 (distributed in the automake package) -# still uses it. Otherwise, the use in gettext.m4 makes autoheader -# give these diagnostics: -# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX -# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX - -undefine([AC_ISC_POSIX]) - -AC_DEFUN([AC_ISC_POSIX], - [ - dnl This test replaces the obsolescent AC_ISC_POSIX kludge. - AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) - ] -) diff --git a/m4/ksba.m4 b/m4/ksba.m4 deleted file mode 100644 index c59ac8024..000000000 --- a/m4/ksba.m4 +++ /dev/null @@ -1,76 +0,0 @@ -# ksba.m4 - autoconf macro to detect ksba -# Copyright (C) 2002 g10 Code GmbH -# -# 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. - - -dnl AM_PATH_KSBA([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libksba and define KSBA_CFLAGS and KSBA_LIBS -dnl -AC_DEFUN(AM_PATH_KSBA, -[ AC_ARG_WITH(ksba-prefix, - AC_HELP_STRING([--with-ksba-prefix=PFX], - [prefix where KSBA is installed (optional)]), - ksba_config_prefix="$withval", ksba_config_prefix="") - if test x$ksba_config_prefix != x ; then - ksba_config_args="$ksba_config_args --prefix=$ksba_config_prefix" - if test x${KSBA_CONFIG+set} != xset ; then - KSBA_CONFIG=$ksba_config_prefix/bin/ksba-config - fi - fi - - AC_PATH_PROG(KSBA_CONFIG, ksba-config, no) - min_ksba_version=ifelse([$1], ,0.4.4,$1) - AC_MSG_CHECKING(for KSBA - version >= $min_ksba_version) - ok=no - if test "$KSBA_CONFIG" != "no" ; then - req_major=`echo $min_ksba_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` - req_minor=`echo $min_ksba_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - req_micro=`echo $min_ksba_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` - ksba_config_version=`$KSBA_CONFIG $ksba_config_args --version` - major=`echo $ksba_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $ksba_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - micro=`echo $ksba_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -gt "$req_minor"; then - ok=yes - else - if test "$minor" -eq "$req_minor"; then - if test "$micro" -ge "$req_micro"; then - ok=yes - fi - fi - fi - fi - fi - fi - if test $ok = yes; then - KSBA_CFLAGS=`$KSBA_CONFIG $ksba_config_args --cflags` - KSBA_LIBS=`$KSBA_CONFIG $ksba_config_args --libs` - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - KSBA_CFLAGS="" - KSBA_LIBS="" - AC_MSG_RESULT(no) - ifelse([$3], , :, [$3]) - fi - AC_SUBST(KSBA_CFLAGS) - AC_SUBST(KSBA_LIBS) -]) diff --git a/m4/lcmessage.m4 b/m4/lcmessage.m4 deleted file mode 100644 index ffd4008b8..000000000 --- a/m4/lcmessage.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# lcmessage.m4 serial 3 (gettext-0.11.3) -dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper <drepper@cygnus.com>, 1995. - -# Check whether LC_MESSAGES is available in <locale.h>. - -AC_DEFUN([AM_LC_MESSAGES], -[ - AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, - [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES], - am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) - if test $am_cv_val_LC_MESSAGES = yes; then - AC_DEFINE(HAVE_LC_MESSAGES, 1, - [Define if your <locale.h> file defines LC_MESSAGES.]) - fi -]) diff --git a/m4/lib-ld.m4 b/m4/lib-ld.m4 deleted file mode 100644 index 11d0ce773..000000000 --- a/m4/lib-ld.m4 +++ /dev/null @@ -1,110 +0,0 @@ -# lib-ld.m4 serial 2 (gettext-0.12) -dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl Subroutines of libtool.m4, -dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision -dnl with libtool.m4. - -dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. -AC_DEFUN([AC_LIB_PROG_LD_GNU], -[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, -[# I'd rather use --version here, but apparently some GNU ld's only accept -v. -if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then - acl_cv_prog_gnu_ld=yes -else - acl_cv_prog_gnu_ld=no -fi]) -with_gnu_ld=$acl_cv_prog_gnu_ld -]) - -dnl From libtool-1.4. Sets the variable LD. -AC_DEFUN([AC_LIB_PROG_LD], -[AC_ARG_WITH(gnu-ld, -[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], -test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by GCC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]* | [A-Za-z]:[\\/]*)] - [re_direlt='/[^/][^/]*/\.\./'] - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(acl_cv_path_LD, -[if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - acl_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then - test "$with_gnu_ld" != no && break - else - test "$with_gnu_ld" != yes && break - fi - fi - done - IFS="$ac_save_ifs" -else - acl_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$acl_cv_path_LD" -if test -n "$LD"; then - AC_MSG_RESULT($LD) -else - AC_MSG_RESULT(no) -fi -test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) -AC_LIB_PROG_LD_GNU -]) diff --git a/m4/lib-link.m4 b/m4/lib-link.m4 deleted file mode 100644 index eeb200d26..000000000 --- a/m4/lib-link.m4 +++ /dev/null @@ -1,551 +0,0 @@ -# lib-link.m4 serial 4 (gettext-0.12) -dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and -dnl augments the CPPFLAGS variable. -AC_DEFUN([AC_LIB_LINKFLAGS], -[ - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - define([Name],[translit([$1],[./-], [___])]) - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ - AC_LIB_LINKFLAGS_BODY([$1], [$2]) - ac_cv_lib[]Name[]_libs="$LIB[]NAME" - ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" - ac_cv_lib[]Name[]_cppflags="$INC[]NAME" - ]) - LIB[]NAME="$ac_cv_lib[]Name[]_libs" - LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" - INC[]NAME="$ac_cv_lib[]Name[]_cppflags" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) - AC_SUBST([LIB]NAME) - AC_SUBST([LTLIB]NAME) - dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the - dnl results of this search when this library appears as a dependency. - HAVE_LIB[]NAME=yes - undefine([Name]) - undefine([NAME]) -]) - -dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) -dnl searches for libname and the libraries corresponding to explicit and -dnl implicit dependencies, together with the specified include files and -dnl the ability to compile and link the specified testcode. If found, it -dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and -dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and -dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs -dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. -AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], -[ - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - define([Name],[translit([$1],[./-], [___])]) - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - - dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME - dnl accordingly. - AC_LIB_LINKFLAGS_BODY([$1], [$2]) - - dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, - dnl because if the user has installed lib[]Name and not disabled its use - dnl via --without-lib[]Name-prefix, he wants to use it. - ac_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) - - AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ - ac_save_LIBS="$LIBS" - LIBS="$LIBS $LIB[]NAME" - AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) - LIBS="$ac_save_LIBS" - ]) - if test "$ac_cv_lib[]Name" = yes; then - HAVE_LIB[]NAME=yes - AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) - AC_MSG_CHECKING([how to link with lib[]$1]) - AC_MSG_RESULT([$LIB[]NAME]) - else - HAVE_LIB[]NAME=no - dnl If $LIB[]NAME didn't lead to a usable library, we don't need - dnl $INC[]NAME either. - CPPFLAGS="$ac_save_CPPFLAGS" - LIB[]NAME= - LTLIB[]NAME= - fi - AC_SUBST([HAVE_LIB]NAME) - AC_SUBST([LIB]NAME) - AC_SUBST([LTLIB]NAME) - undefine([Name]) - undefine([NAME]) -]) - -dnl Determine the platform dependent parameters needed to use rpath: -dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, -dnl hardcode_direct, hardcode_minus_L. -AC_DEFUN([AC_LIB_RPATH], -[ - AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS - AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld - AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host - AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir - AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ - CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ - ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh - . ./conftest.sh - rm -f ./conftest.sh - acl_cv_rpath=done - ]) - wl="$acl_cv_wl" - libext="$acl_cv_libext" - shlibext="$acl_cv_shlibext" - hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" - hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" - hardcode_direct="$acl_cv_hardcode_direct" - hardcode_minus_L="$acl_cv_hardcode_minus_L" - dnl Determine whether the user wants rpath handling at all. - AC_ARG_ENABLE(rpath, - [ --disable-rpath do not hardcode runtime library paths], - :, enable_rpath=yes) -]) - -dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. -AC_DEFUN([AC_LIB_LINKFLAGS_BODY], -[ - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_LIB_ARG_WITH([lib$1-prefix], -[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib - --without-lib$1-prefix don't search for lib$1 in includedir and libdir], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi - fi -]) - dnl Search the library and its dependencies in $additional_libdir and - dnl $LDFLAGS. Using breadth-first-seach. - LIB[]NAME= - LTLIB[]NAME= - INC[]NAME= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='$1 $2' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - dnl See if it was already located by an earlier AC_LIB_LINKFLAGS - dnl or AC_LIB_HAVE_LINKFLAGS call. - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" - else - dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined - dnl that this library doesn't exist. So just drop it. - : - fi - else - dnl Search the library lib$name in $additional_libdir and $LDFLAGS - dnl and the already constructed $LIBNAME/$LTLIBNAME. - found_dir= - found_la= - found_so= - found_a= - if test $use_additional = yes; then - if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then - found_dir="$additional_libdir" - found_so="$additional_libdir/lib$name.$shlibext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - else - if test -f "$additional_libdir/lib$name.$libext"; then - found_dir="$additional_libdir" - found_a="$additional_libdir/lib$name.$libext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then - found_dir="$dir" - found_so="$dir/lib$name.$shlibext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - else - if test -f "$dir/lib$name.$libext"; then - found_dir="$dir" - found_a="$dir/lib$name.$libext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - dnl Found the library. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - dnl Linking with a shared library. We attempt to hardcode its - dnl directory into the executable's runpath, unless it's the - dnl standard /usr/lib. - if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then - dnl No hardcoding is needed. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - dnl The hardcoding into $LIBNAME is system dependent. - if test "$hardcode_direct" = yes; then - dnl Using DIR/libNAME.so during linking hardcodes DIR into the - dnl resulting binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - dnl Rely on "-L$found_dir". - dnl But don't add it if it's already contained in the LDFLAGS - dnl or the already constructed $LIBNAME - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" - fi - if test "$hardcode_minus_L" != no; then - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH - dnl here, because this doesn't fit in flags passed to the - dnl compiler. So give up. No hardcoding. This affects only - dnl very old systems. - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - dnl Linking with a static library. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" - else - dnl We shouldn't come here, but anyway it's good to have a - dnl fallback. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" - fi - fi - dnl Assume the include files are nearby. - additional_includedir= - case "$found_dir" in - */lib | */lib/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - dnl Potentially add $additional_includedir to $INCNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's /usr/local/include and we are using GCC on Linux, - dnl 3. if it's already present in $CPPFLAGS or the already - dnl constructed $INCNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INC[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $INCNAME. - INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - dnl Look for dependencies. - if test -n "$found_la"; then - dnl Read the .la file. It defines the variables - dnl dlname, library_names, old_library, dependency_libs, current, - dnl age, revision, installed, dlopen, dlpreopen, libdir. - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - dnl We use only dependency_libs. - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's /usr/local/lib and we are using GCC on Linux, - dnl 3. if it's already present in $LDFLAGS or the already - dnl constructed $LIBNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LIBNAME. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LTLIBNAME. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - dnl Handle this in the next round. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - dnl Handle this in the next round. Throw away the .la's - dnl directory; it is already contained in a preceding -L - dnl option. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - dnl Most likely an immediate library name. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" - ;; - esac - done - fi - else - dnl Didn't find the library; assume it is in the system directories - dnl known to the linker and runtime loader. (All the system - dnl directories known to the linker should also be known to the - dnl runtime loader, otherwise the system is severely misconfigured.) - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" - fi - fi - fi - done - done - if test "X$rpathdirs" != "X"; then - if test -n "$hardcode_libdir_separator"; then - dnl Weird platform: only the last -rpath option counts, the user must - dnl pass all path elements in one option. We can arrange that for a - dnl single library, but not when more than one $LIBNAMEs are used. - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" - done - dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - else - dnl The -rpath options are cumulative. - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - dnl When using libtool, the option that works for both libraries and - dnl executables is -R. The -R options are cumulative. - for found_dir in $ltrpathdirs; do - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" - done - fi -]) - -dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, -dnl unless already present in VAR. -dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes -dnl contains two or three consecutive elements that belong together. -AC_DEFUN([AC_LIB_APPENDTOVAR], -[ - for element in [$2]; do - haveit= - for x in $[$1]; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - [$1]="${[$1]}${[$1]:+ }$element" - fi - done -]) diff --git a/m4/lib-prefix.m4 b/m4/lib-prefix.m4 deleted file mode 100644 index c719bc809..000000000 --- a/m4/lib-prefix.m4 +++ /dev/null @@ -1,155 +0,0 @@ -# lib-prefix.m4 serial 2 (gettext-0.12) -dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and -dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't -dnl require excessive bracketing. -ifdef([AC_HELP_STRING], -[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], -[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) - -dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed -dnl to access previously installed libraries. The basic assumption is that -dnl a user will want packages to use other packages he previously installed -dnl with the same --prefix option. -dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate -dnl libraries, but is otherwise very convenient. -AC_DEFUN([AC_LIB_PREFIX], -[ - AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_LIB_ARG_WITH([lib-prefix], -[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib - --without-lib-prefix don't search for libraries in includedir and libdir], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi - fi -]) - if test $use_additional = yes; then - dnl Potentially add $additional_includedir to $CPPFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's already present in $CPPFLAGS, - dnl 3. if it's /usr/local/include and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - for x in $CPPFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $CPPFLAGS. - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" - fi - fi - fi - fi - dnl Potentially add $additional_libdir to $LDFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's already present in $LDFLAGS, - dnl 3. if it's /usr/local/lib and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - for x in $LDFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LDFLAGS. - LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" - fi - fi - fi - fi - fi -]) - -dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, -dnl acl_final_exec_prefix, containing the values to which $prefix and -dnl $exec_prefix will expand at the end of the configure script. -AC_DEFUN([AC_LIB_PREPARE_PREFIX], -[ - dnl Unfortunately, prefix and exec_prefix get only finally determined - dnl at the end of configure. - if test "X$prefix" = "XNONE"; then - acl_final_prefix="$ac_default_prefix" - else - acl_final_prefix="$prefix" - fi - if test "X$exec_prefix" = "XNONE"; then - acl_final_exec_prefix='${prefix}' - else - acl_final_exec_prefix="$exec_prefix" - fi - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" - prefix="$acl_save_prefix" -]) - -dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the -dnl variables prefix and exec_prefix bound to the values they will have -dnl at the end of the configure script. -AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], -[ - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - $1 - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" -]) diff --git a/m4/libassuan.m4 b/m4/libassuan.m4 deleted file mode 100644 index 2afc69737..000000000 --- a/m4/libassuan.m4 +++ /dev/null @@ -1,76 +0,0 @@ -dnl Autoconf macros for libassuan -dnl Copyright (C) 2002, 2003 Free Software Foundation, Inc. -dnl -dnl This file is free software; as a special exception the author gives -dnl unlimited permission to copy and/or distribute it, with or without -dnl modifications, as long as this notice is preserved. -dnl -dnl This file is distributed in the hope that it will be useful, but -dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - -dnl AM_PATH_LIBASSUAN([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libassuan and define LIBASSUAN_CFLAGS and LIBASSUAN_LIBS -dnl -AC_DEFUN(AM_PATH_LIBASSUAN, -[ AC_ARG_WITH(libassuan-prefix, - AC_HELP_STRING([--with-libassuan-prefix=PFX], - [prefix where LIBASSUAN is installed (optional)]), - libassuan_config_prefix="$withval", libassuan_config_prefix="") - if test x$libassuan_config_prefix != x ; then - libassuan_config_args="$libassuan_config_args --prefix=$libassuan_config_prefix" - if test x${LIBASSUAN_CONFIG+set} != xset ; then - LIBASSUAN_CONFIG=$libassuan_config_prefix/bin/libassuan-config - fi - fi - - AC_PATH_PROG(LIBASSUAN_CONFIG, libassuan-config, no) - min_libassuan_version=ifelse([$1], ,0.0.1,$1) - AC_MSG_CHECKING(for LIBASSUAN - version >= $min_libassuan_version) - ok=no - if test "$LIBASSUAN_CONFIG" != "no" ; then - req_major=`echo $min_libassuan_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` - req_minor=`echo $min_libassuan_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - req_micro=`echo $min_libassuan_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` - libassuan_config_version=`$LIBASSUAN_CONFIG $libassuan_config_args --version` - major=`echo $libassuan_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $libassuan_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - micro=`echo $libassuan_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -gt "$req_minor"; then - ok=yes - else - if test "$minor" -eq "$req_minor"; then - if test "$micro" -ge "$req_micro"; then - ok=yes - fi - fi - fi - fi - fi - fi - if test $ok = yes; then - LIBASSUAN_CFLAGS=`$LIBASSUAN_CONFIG $libassuan_config_args --cflags` - LIBASSUAN_LIBS=`$LIBASSUAN_CONFIG $libassuan_config_args --libs` - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - LIBASSUAN_CFLAGS="" - LIBASSUAN_LIBS="" - AC_MSG_RESULT(no) - ifelse([$3], , :, [$3]) - fi - AC_SUBST(LIBASSUAN_CFLAGS) - AC_SUBST(LIBASSUAN_LIBS) -]) diff --git a/m4/libgcrypt.m4 b/m4/libgcrypt.m4 deleted file mode 100644 index e5f2a43c0..000000000 --- a/m4/libgcrypt.m4 +++ /dev/null @@ -1,108 +0,0 @@ -dnl Autoconf macros for libgcrypt -dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc. -dnl -dnl This file is free software; as a special exception the author gives -dnl unlimited permission to copy and/or distribute it, with or without -dnl modifications, as long as this notice is preserved. -dnl -dnl This file is distributed in the hope that it will be useful, but -dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - -dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS. -dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed -dnl with the API version to also check the API compatibility. Example: -dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed -dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using -dnl this features allows to prevent build against newer versions of libgcrypt -dnl with a changed API. -dnl -AC_DEFUN(AM_PATH_LIBGCRYPT, -[ AC_ARG_WITH(libgcrypt-prefix, - AC_HELP_STRING([--with-libgcrypt-prefix=PFX], - [prefix where LIBGCRYPT is installed (optional)]), - libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="") - if test x$libgcrypt_config_prefix != x ; then - if test x${LIBGCRYPT_CONFIG+set} != xset ; then - LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config - fi - fi - - AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no) - tmp=ifelse([$1], ,1:1.2.0,$1) - if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then - req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` - min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` - else - req_libgcrypt_api=0 - min_libgcrypt_version="$tmp" - fi - - AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version) - ok=no - if test "$LIBGCRYPT_CONFIG" != "no" ; then - req_major=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` - req_minor=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - req_micro=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` - libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version` - major=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - micro=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -gt "$req_minor"; then - ok=yes - else - if test "$minor" -eq "$req_minor"; then - if test "$micro" -ge "$req_micro"; then - ok=yes - fi - fi - fi - fi - fi - fi - if test $ok = yes; then - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - if test $ok = yes; then - # If we have a recent libgcrypt, we should also check that the - # API is compatible - if test "$req_libgcrypt_api" -gt 0 ; then - tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0` - if test "$tmp" -gt 0 ; then - AC_MSG_CHECKING([LIBGCRYPT API version]) - if test "$req_libgcrypt_api" -eq "$tmp" ; then - AC_MSG_RESULT(okay) - else - ok=no - AC_MSG_RESULT([does not match (want=$req_libgcrypt_api got=$tmp)]) - fi - fi - fi - fi - if test $ok = yes; then - LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` - LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` - ifelse([$2], , :, [$2]) - else - LIBGCRYPT_CFLAGS="" - LIBGCRYPT_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(LIBGCRYPT_CFLAGS) - AC_SUBST(LIBGCRYPT_LIBS) -]) diff --git a/m4/nls.m4 b/m4/nls.m4 deleted file mode 100644 index 36bc49317..000000000 --- a/m4/nls.m4 +++ /dev/null @@ -1,49 +0,0 @@ -# nls.m4 serial 1 (gettext-0.12) -dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. -dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. - -AC_DEFUN([AM_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], - USE_NLS=$enableval, USE_NLS=yes) - AC_MSG_RESULT($USE_NLS) - AC_SUBST(USE_NLS) -]) - -AC_DEFUN([AM_MKINSTALLDIRS], -[ - dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly - dnl find the mkinstalldirs script in another subdir but $(top_srcdir). - dnl Try to locate it. - MKINSTALLDIRS= - if test -n "$ac_aux_dir"; then - case "$ac_aux_dir" in - /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; - *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; - esac - fi - if test -z "$MKINSTALLDIRS"; then - MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" - fi - AC_SUBST(MKINSTALLDIRS) -]) diff --git a/m4/po.m4 b/m4/po.m4 deleted file mode 100644 index 861e3dec3..000000000 --- a/m4/po.m4 +++ /dev/null @@ -1,197 +0,0 @@ -# po.m4 serial 1 (gettext-0.12) -dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. -dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. - -dnl Checks for all prerequisites of the po subdirectory. -AC_DEFUN([AM_PO_SUBDIRS], -[ - AC_REQUIRE([AC_PROG_MAKE_SET])dnl - AC_REQUIRE([AC_PROG_INSTALL])dnl - AC_REQUIRE([AM_MKINSTALLDIRS])dnl - AC_REQUIRE([AM_NLS])dnl - - dnl Perform the following tests also if --disable-nls has been given, - dnl because they are needed for "make dist" to work. - - dnl Search for GNU msgfmt in the PATH. - dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. - dnl The second test excludes FreeBSD msgfmt. - AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, - [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && - (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], - :) - AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) - - dnl Search for GNU xgettext 0.12 or newer in the PATH. - dnl The first test excludes Solaris xgettext and early GNU xgettext versions. - dnl The second test excludes FreeBSD xgettext. - AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, - [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && - (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], - :) - dnl Remove leftover from FreeBSD xgettext call. - rm -f messages.po - - dnl Search for GNU msgmerge 0.11 or newer in the PATH. - AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, - [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) - - dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. - dnl Test whether we really found GNU msgfmt. - if test "$GMSGFMT" != ":"; then - dnl If it is no GNU msgfmt we define it as : so that the - dnl Makefiles still can work. - if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && - (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - : ; - else - GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` - AC_MSG_RESULT( - [found $GMSGFMT program is not GNU msgfmt; ignore it]) - GMSGFMT=":" - fi - fi - - dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. - 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 --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && - (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - : ; - else - AC_MSG_RESULT( - [found xgettext program is not GNU xgettext; ignore it]) - XGETTEXT=":" - fi - dnl Remove leftover from FreeBSD xgettext call. - rm -f messages.po - fi - - AC_OUTPUT_COMMANDS([ - for ac_file in $CONFIG_FILES; do - # Support "outfile[:infile[:infile...]]" - case "$ac_file" in - *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - esac - # PO directories have a Makefile.in generated from Makefile.in.in. - case "$ac_file" in */Makefile.in) - # Adjust a relative srcdir. - ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` - ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" - ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` - # In autoconf-2.13 it is called $ac_given_srcdir. - # In autoconf-2.50 it is called $srcdir. - test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" - case "$ac_given_srcdir" in - .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; - /*) top_srcdir="$ac_given_srcdir" ;; - *) top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then - rm -f "$ac_dir/POTFILES" - test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" - cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" - POMAKEFILEDEPS="POTFILES.in" - # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend - # on $ac_dir but don't depend on user-specified configuration - # parameters. - if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then - # The LINGUAS file contains the set of available languages. - if test -n "$OBSOLETE_ALL_LINGUAS"; then - test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" - fi - ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` - # Hide the ALL_LINGUAS assigment from automake. - eval 'ALL_LINGUAS''=$ALL_LINGUAS_' - POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" - else - # The set of available languages was given in configure.in. - eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' - fi - case "$ac_given_srcdir" in - .) srcdirpre= ;; - *) srcdirpre='$(srcdir)/' ;; - esac - POFILES= - GMOFILES= - UPDATEPOFILES= - DUMMYPOFILES= - for lang in $ALL_LINGUAS; do - POFILES="$POFILES $srcdirpre$lang.po" - GMOFILES="$GMOFILES $srcdirpre$lang.gmo" - UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" - DUMMYPOFILES="$DUMMYPOFILES $lang.nop" - done - # CATALOGS depends on both $ac_dir and the user's LINGUAS - # environment variable. - INST_LINGUAS= - if test -n "$ALL_LINGUAS"; then - for presentlang in $ALL_LINGUAS; do - useit=no - if test "%UNSET%" != "$LINGUAS"; then - desiredlanguages="$LINGUAS" - else - desiredlanguages="$ALL_LINGUAS" - fi - for desiredlang in $desiredlanguages; do - # Use the presentlang catalog if desiredlang is - # a. equal to presentlang, or - # b. a variant of presentlang (because in this case, - # presentlang can be used as a fallback for messages - # which are not translated in the desiredlang catalog). - case "$desiredlang" in - "$presentlang"*) useit=yes;; - esac - done - if test $useit = yes; then - INST_LINGUAS="$INST_LINGUAS $presentlang" - fi - done - fi - CATALOGS= - if test -n "$INST_LINGUAS"; then - for lang in $INST_LINGUAS; do - CATALOGS="$CATALOGS $lang.gmo" - done - fi - test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" - sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" - for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do - if test -f "$f"; then - case "$f" in - *.orig | *.bak | *~) ;; - *) cat "$f" >> "$ac_dir/Makefile" ;; - esac - fi - done - fi - ;; - esac - done], - [# Capture the value of obsolete ALL_LINGUAS because we need it to compute - # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it - # from automake. - eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' - # Capture the value of LINGUAS because we need it to compute CATALOGS. - LINGUAS="${LINGUAS-%UNSET%}" - ]) -]) diff --git a/m4/progtest.m4 b/m4/progtest.m4 deleted file mode 100644 index 8fe527cec..000000000 --- a/m4/progtest.m4 +++ /dev/null @@ -1,91 +0,0 @@ -# progtest.m4 serial 3 (gettext-0.12) -dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper <drepper@cygnus.com>, 1996. - -# Search path for a program which passes the given test. - -dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, -dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) -AC_DEFUN([AM_PATH_PROG_WITH_TEST], -[ -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Find out how to test for executable files. Don't use a zero-byte file, -# as systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - ac_executable_p="test -x" -else - ac_executable_p="test -f" -fi -rm -f conf$$.file - -# Extract the first word of "$2", so it can be a program name with args. -set dummy $2; ac_word=[$]2 -AC_MSG_CHECKING([for $ac_word]) -AC_CACHE_VAL(ac_cv_path_$1, -[case "[$]$1" in - [[\\/]]* | ?:[[\\/]]*) - ac_cv_path_$1="[$]$1" # Let the user override the test with a path. - ;; - *) - ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in ifelse([$5], , $PATH, [$5]); do - IFS="$ac_save_IFS" - test -z "$ac_dir" && ac_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then - if [$3]; then - ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" - break 2 - fi - fi - done - done - IFS="$ac_save_IFS" -dnl If no 4th arg is given, leave the cache variable unset, -dnl so AC_PATH_PROGS will keep looking. -ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" -])dnl - ;; -esac])dnl -$1="$ac_cv_path_$1" -if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then - AC_MSG_RESULT([$]$1) -else - AC_MSG_RESULT(no) -fi -AC_SUBST($1)dnl -]) diff --git a/m4/stdint_h.m4 b/m4/stdint_h.m4 deleted file mode 100644 index 32ba7ae77..000000000 --- a/m4/stdint_h.m4 +++ /dev/null @@ -1,28 +0,0 @@ -# stdint_h.m4 serial 3 (gettext-0.12) -dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Paul Eggert. - -# Define HAVE_STDINT_H_WITH_UINTMAX if <stdint.h> exists, -# doesn't clash with <sys/types.h>, and declares uintmax_t. - -AC_DEFUN([jm_AC_HEADER_STDINT_H], -[ - AC_CACHE_CHECK([for stdint.h], jm_ac_cv_header_stdint_h, - [AC_TRY_COMPILE( - [#include <sys/types.h> -#include <stdint.h>], - [uintmax_t i = (uintmax_t) -1;], - jm_ac_cv_header_stdint_h=yes, - jm_ac_cv_header_stdint_h=no)]) - if test $jm_ac_cv_header_stdint_h = yes; then - AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, - [Define if <stdint.h> exists, doesn't clash with <sys/types.h>, - and declares uintmax_t. ]) - fi -]) diff --git a/m4/uintmax_t.m4 b/m4/uintmax_t.m4 deleted file mode 100644 index b5f28d440..000000000 --- a/m4/uintmax_t.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# uintmax_t.m4 serial 7 (gettext-0.12) -dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Paul Eggert. - -AC_PREREQ(2.13) - -# Define uintmax_t to 'unsigned long' or 'unsigned long long' -# if it is not already defined in <stdint.h> or <inttypes.h>. - -AC_DEFUN([jm_AC_TYPE_UINTMAX_T], -[ - AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([jm_AC_HEADER_STDINT_H]) - if test $jm_ac_cv_header_inttypes_h = no && test $jm_ac_cv_header_stdint_h = no; then - AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG]) - test $ac_cv_type_unsigned_long_long = yes \ - && ac_type='unsigned long long' \ - || ac_type='unsigned long' - AC_DEFINE_UNQUOTED(uintmax_t, $ac_type, - [Define to unsigned long or unsigned long long - if <stdint.h> and <inttypes.h> don't define.]) - else - AC_DEFINE(HAVE_UINTMAX_T, 1, - [Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>.]) - fi -]) diff --git a/m4/ulonglong.m4 b/m4/ulonglong.m4 deleted file mode 100644 index c375e474c..000000000 --- a/m4/ulonglong.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# ulonglong.m4 serial 2 (fileutils-4.0.32, gettext-0.10.40) -dnl Copyright (C) 1999-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Paul Eggert. - -AC_DEFUN([jm_AC_TYPE_UNSIGNED_LONG_LONG], -[ - AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, - [AC_TRY_LINK([unsigned long long ull = 1; int i = 63;], - [unsigned long long ullmax = (unsigned long long) -1; - return ull << i | ull >> i | ullmax / ull | ullmax % ull;], - ac_cv_type_unsigned_long_long=yes, - ac_cv_type_unsigned_long_long=no)]) - if test $ac_cv_type_unsigned_long_long = yes; then - AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, - [Define if you have the unsigned long long type.]) - fi -]) diff --git a/po/ChangeLog b/po/ChangeLog deleted file mode 100644 index 97e68c730..000000000 --- a/po/ChangeLog +++ /dev/null @@ -1,44 +0,0 @@ -2004-04-06 Werner Koch <wk@gnupg.org> - - * Makevars (DOMAIN): Init from PACKAGE_GT - -2003-12-09 Werner Koch <wk@gnupg.org> - - * Makevars (MSGID_BUGS_ADDRESS): New. - -2003-04-29 Werner Koch <wk@gnupg.org> - - * LINUGAS: NEW. - -2003-04-29 gettextize <bug-gnu-gettext@gnu.org> - - * Rules-quot: New file, from gettext-0.11.5. - * boldquot.sed: New file, from gettext-0.11.5. - * en@boldquot.header: New file, from gettext-0.11.5. - * en@quot.header: New file, from gettext-0.11.5. - * insert-header.sin: New file, from gettext-0.11.5. - * quot.sed: New file, from gettext-0.11.5. - * remove-potcdate.sin: New file, from gettext-0.11.5. - -2002-08-21 Werner Koch <wk@gnupg.org> - - * de.po: Updated the translation. - -2002-08-10 Werner Koch <wk@gnupg.org> - - * Makefile.in.in: Installed from gettext-0.10.40. - * POTFILES.in: New. - * de.po: New. - - - Copyright 2002 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. - - diff --git a/po/LINGUAS b/po/LINGUAS deleted file mode 100644 index 2d1cafec8..000000000 --- a/po/LINGUAS +++ /dev/null @@ -1,5 +0,0 @@ -# Set of available languages. -de - - - diff --git a/po/Makefile.in.in b/po/Makefile.in.in deleted file mode 100644 index 27b721aa8..000000000 --- a/po/Makefile.in.in +++ /dev/null @@ -1,353 +0,0 @@ -# Makefile for PO directory in any package using GNU gettext. -# Copyright (C) 1995-1997, 2000-2003 by Ulrich Drepper <drepper@gnu.ai.mit.edu> -# -# This file can be copied and used freely without restrictions. It can -# be used in projects which are not available under the GNU General Public -# License but which still want to provide support for the GNU gettext -# functionality. -# Please note that the actual code of GNU gettext is covered by the GNU -# General Public License and is *not* in the public domain. - -PACKAGE = @PACKAGE@ -VERSION = @VERSION@ - -SHELL = /bin/sh -@SET_MAKE@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -datadir = @datadir@ -localedir = $(datadir)/locale -gettextsrcdir = $(datadir)/gettext/po - -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -mkinstalldirs = $(SHELL) $(MKINSTALLDIRS) - -GMSGFMT = @GMSGFMT@ -MSGFMT = @MSGFMT@ -XGETTEXT = @XGETTEXT@ -MSGMERGE = msgmerge -MSGMERGE_UPDATE = @MSGMERGE@ --update -MSGINIT = msginit -MSGCONV = msgconv -MSGFILTER = msgfilter - -POFILES = @POFILES@ -GMOFILES = @GMOFILES@ -UPDATEPOFILES = @UPDATEPOFILES@ -DUMMYPOFILES = @DUMMYPOFILES@ -DISTFILES.common = Makefile.in.in remove-potcdate.sin \ -$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) -DISTFILES = $(DISTFILES.common) Makevars POTFILES.in $(DOMAIN).pot stamp-po \ -$(POFILES) $(GMOFILES) \ -$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) - -POTFILES = \ - -CATALOGS = @CATALOGS@ - -# Makevars gets inserted here. (Don't remove this line!) - -.SUFFIXES: -.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-update - -.po.mo: - @echo "$(MSGFMT) -c -o $@ $<"; \ - $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ - -.po.gmo: - @lang=`echo $* | sed -e 's,.*/,,'`; \ - test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ - echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \ - cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo - -.sin.sed: - sed -e '/^#/d' $< > t-$@ - mv t-$@ $@ - - -all: all-@USE_NLS@ - -all-yes: stamp-po -all-no: - -# stamp-po is a timestamp denoting the last time at which the CATALOGS have -# been loosely updated. Its purpose is that when a developer or translator -# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, -# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent -# invocations of "make" will do nothing. This timestamp would not be necessary -# if updating the $(CATALOGS) would always touch them; however, the rule for -# $(POFILES) has been designed to not touch files that don't need to be -# changed. -stamp-po: $(srcdir)/$(DOMAIN).pot - test -z "$(CATALOGS)" || $(MAKE) $(CATALOGS) - @echo "touch stamp-po" - @echo timestamp > stamp-poT - @mv stamp-poT stamp-po - -# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', -# otherwise packages like GCC can not be built if only parts of the source -# have been downloaded. - -# This target rebuilds $(DOMAIN).pot; it is an expensive operation. -# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. -$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed - $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ - --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ - --files-from=$(srcdir)/POTFILES.in \ - --copyright-holder='$(COPYRIGHT_HOLDER)' \ - --msgid-bugs-address='$(MSGID_BUGS_ADDRESS)' - test ! -f $(DOMAIN).po || { \ - if test -f $(srcdir)/$(DOMAIN).pot; then \ - sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ - sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ - if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ - rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ - else \ - rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ - mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ - fi; \ - else \ - mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ - fi; \ - } - -# This rule has no dependencies: we don't need to update $(DOMAIN).pot at -# every "make" invocation, only create it when it is missing. -# Only "make $(DOMAIN).pot-update" or "make dist" will force an update. -$(srcdir)/$(DOMAIN).pot: - $(MAKE) $(DOMAIN).pot-update - -# This target rebuilds a PO file if $(DOMAIN).pot has changed. -# Note that a PO file is not touched if it doesn't need to be changed. -$(POFILES): $(srcdir)/$(DOMAIN).pot - @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ - test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ - echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot"; \ - cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot - - -install: install-exec install-data -install-exec: -install-data: install-data-@USE_NLS@ - if test "$(PACKAGE)" = "gettext-tools"; then \ - $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ - for file in $(DISTFILES.common) Makevars.template; do \ - $(INSTALL_DATA) $(srcdir)/$$file \ - $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - for file in Makevars; do \ - rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - else \ - : ; \ - fi -install-data-no: all -install-data-yes: all - $(mkinstalldirs) $(DESTDIR)$(datadir) - @catalogs='$(CATALOGS)'; \ - for cat in $$catalogs; do \ - cat=`basename $$cat`; \ - lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ - dir=$(localedir)/$$lang/LC_MESSAGES; \ - $(mkinstalldirs) $(DESTDIR)$$dir; \ - if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ - $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ - echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ - for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ - if test -n "$$lc"; then \ - if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ - link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ - mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ - mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ - (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ - for file in *; do \ - if test -f $$file; then \ - ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ - fi; \ - done); \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ - else \ - if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ - :; \ - else \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ - mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ - fi; \ - fi; \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ - ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ - ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ - cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ - echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ - fi; \ - done; \ - done - -install-strip: install - -installdirs: installdirs-exec installdirs-data -installdirs-exec: -installdirs-data: installdirs-data-@USE_NLS@ - if test "$(PACKAGE)" = "gettext-tools"; then \ - $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ - else \ - : ; \ - fi -installdirs-data-no: -installdirs-data-yes: - $(mkinstalldirs) $(DESTDIR)$(datadir) - @catalogs='$(CATALOGS)'; \ - for cat in $$catalogs; do \ - cat=`basename $$cat`; \ - lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ - dir=$(localedir)/$$lang/LC_MESSAGES; \ - $(mkinstalldirs) $(DESTDIR)$$dir; \ - for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ - if test -n "$$lc"; then \ - if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ - link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ - mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ - mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ - (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ - for file in *; do \ - if test -f $$file; then \ - ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ - fi; \ - done); \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ - else \ - if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ - :; \ - else \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ - mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ - fi; \ - fi; \ - fi; \ - done; \ - done - -# Define this as empty until I found a useful application. -installcheck: - -uninstall: uninstall-exec uninstall-data -uninstall-exec: -uninstall-data: uninstall-data-@USE_NLS@ - if test "$(PACKAGE)" = "gettext-tools"; then \ - for file in $(DISTFILES.common) Makevars.template; do \ - rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - else \ - : ; \ - fi -uninstall-data-no: -uninstall-data-yes: - catalogs='$(CATALOGS)'; \ - for cat in $$catalogs; do \ - cat=`basename $$cat`; \ - lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ - for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ - done; \ - done - -check: all - -info dvi ps pdf html tags TAGS ctags CTAGS ID: - -mostlyclean: - rm -f remove-potcdate.sed - rm -f stamp-poT - rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po - rm -fr *.o - -clean: mostlyclean - -distclean: clean - rm -f Makefile Makefile.in POTFILES *.mo - -maintainer-clean: distclean - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - rm -f stamp-po $(GMOFILES) - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) -dist distdir: - $(MAKE) update-po - @$(MAKE) dist2 -# This is a separate target because 'update-po' must be executed before. -dist2: $(DISTFILES) - dists="$(DISTFILES)"; \ - if test "$(PACKAGE)" = "gettext-tools"; then \ - dists="$$dists Makevars.template"; \ - fi; \ - if test -f $(srcdir)/ChangeLog; then \ - dists="$$dists ChangeLog"; \ - fi; \ - for i in 0 1 2 3 4 5 6 7 8 9; do \ - if test -f $(srcdir)/ChangeLog.$$i; then \ - dists="$$dists ChangeLog.$$i"; \ - fi; \ - done; \ - if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ - for file in $$dists; do \ - if test -f $$file; then \ - cp -p $$file $(distdir); \ - else \ - cp -p $(srcdir)/$$file $(distdir); \ - fi; \ - done - -update-po: Makefile - $(MAKE) $(DOMAIN).pot-update - test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) - $(MAKE) update-gmo - -# General rule for updating PO files. - -.nop.po-update: - @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ - if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \ - tmpdir=`pwd`; \ - echo "$$lang:"; \ - test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ - echo "$${cdcmd}$(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ - cd $(srcdir); \ - if $(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$tmpdir/$$lang.new.po; then \ - if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ - rm -f $$tmpdir/$$lang.new.po; \ - else \ - if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ - :; \ - else \ - echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ - exit 1; \ - fi; \ - fi; \ - else \ - echo "msgmerge for $$lang.po failed!" 1>&2; \ - rm -f $$tmpdir/$$lang.new.po; \ - fi - -$(DUMMYPOFILES): - -update-gmo: Makefile $(GMOFILES) - @: - -Makefile: Makefile.in.in $(top_builddir)/config.status @POMAKEFILEDEPS@ - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ - $(SHELL) ./config.status - -force: - -# Tell versions [3.59,3.63) of GNU make not to export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/po/Makevars b/po/Makevars deleted file mode 100644 index b99cd466c..000000000 --- a/po/Makevars +++ /dev/null @@ -1,41 +0,0 @@ -# Makefile variables for PO directory in any package using GNU gettext. - -# Usually the message domain is the same as the package name. -DOMAIN = gnupg2 - -# These two variables depend on the location of this directory. -subdir = po -top_builddir = .. - -# These options get passed to xgettext. -XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ - -# This is the copyright holder that gets inserted into the header of the -# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding -# package. (Note that the msgstr strings, extracted from the package's -# sources, belong to the copyright holder of the package.) Translators are -# expected to transfer the copyright for their translations to this person -# or entity, or to disclaim their copyright. The empty string stands for -# the public domain; in this case the translators are expected to disclaim -# their copyright. -COPYRIGHT_HOLDER = Free Software Foundation, Inc. - -# This is the email address or URL to which the translators shall report -# bugs in the untranslated strings: -# - Strings which are not entire sentences, see the maintainer guidelines -# in the GNU gettext documentation, section 'Preparing Strings'. -# - Strings which use unclear terms or require additional context to be -# understood. -# - Strings which make invalid assumptions about notation of date, time or -# money. -# - Pluralisation problems. -# - Incorrect English spelling. -# - Incorrect formatting. -# It can be your email address, or a mailing list address where translators -# can write to without being subscribed, or the URL of a web page through -# which the translators can contact you. -MSGID_BUGS_ADDRESS = translations@gnupg.org - -# This is the list of locale categories, beyond LC_MESSAGES, for which the -# message catalogs shall be used. It is usually empty. -EXTRA_LOCALE_CATEGORIES = diff --git a/po/POTFILES.in b/po/POTFILES.in deleted file mode 100644 index ae54716ac..000000000 --- a/po/POTFILES.in +++ /dev/null @@ -1,36 +0,0 @@ -# List of files with translatable strings. - -agent/gpg-agent.c -agent/protect-tool.c -agent/divert-scd.c -agent/genkey.c -agent/query.c - -common/sysutils.c -common/simple-pwquery.c - -jnlib/argparse.c -jnlib/logging.c - -kbx/kbxutil.c - -scd/scdaemon.c - -sm/base64.c -sm/call-agent.c -sm/call-dirmngr.c -sm/certdump.c -sm/certlist.c -sm/certchain.c -sm/decrypt.c -sm/delete.c -sm/encrypt.c -sm/gpgsm.c -sm/import.c -sm/keydb.c -sm/keylist.c -sm/sign.c -sm/verify.c - -tools/gpgconf.c -tools/gpgconf-comp.c diff --git a/po/Rules-quot b/po/Rules-quot deleted file mode 100644 index 5f46d237d..000000000 --- a/po/Rules-quot +++ /dev/null @@ -1,42 +0,0 @@ -# Special Makefile rules for English message catalogs with quotation marks. - -DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot - -.SUFFIXES: .insert-header .po-update-en - -en@quot.po-update: en@quot.po-update-en -en@boldquot.po-update: en@boldquot.po-update-en - -.insert-header.po-update-en: - @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ - if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ - tmpdir=`pwd`; \ - echo "$$lang:"; \ - ll=`echo $$lang | sed -e 's/@.*//'`; \ - LC_ALL=C; export LC_ALL; \ - cd $(srcdir); \ - if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$ll -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \ - if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ - rm -f $$tmpdir/$$lang.new.po; \ - else \ - if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ - :; \ - else \ - echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ - exit 1; \ - fi; \ - fi; \ - else \ - echo "creation of $$lang.po failed!" 1>&2; \ - rm -f $$tmpdir/$$lang.new.po; \ - fi - -en@quot.insert-header: insert-header.sin - sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header - -en@boldquot.insert-header: insert-header.sin - sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header - -mostlyclean: mostlyclean-quot -mostlyclean-quot: - rm -f *.insert-header diff --git a/po/boldquot.sed b/po/boldquot.sed deleted file mode 100644 index 4b937aa51..000000000 --- a/po/boldquot.sed +++ /dev/null @@ -1,10 +0,0 @@ -s/"\([^"]*\)"/“\1â€/g -s/`\([^`']*\)'/‘\1’/g -s/ '\([^`']*\)' / ‘\1’ /g -s/ '\([^`']*\)'$/ ‘\1’/g -s/^'\([^`']*\)' /‘\1’ /g -s/“â€/""/g -s/“/“/g -s/â€/â€/g -s/‘/‘/g -s/’/’/g diff --git a/po/de.po b/po/de.po deleted file mode 100644 index 2cf41ddb0..000000000 --- a/po/de.po +++ /dev/null @@ -1,1193 +0,0 @@ -# German translation for GnuPG 1.9.x -# Copyright (C) 2002, 2004 Free Software Foundation, Inc. -# Werner Koch <wk@gnupg.org>, 2002. -# -# -# Note that we use "gnupg2" as the domain to avoid conflicts with -# already installed domains "gnupg" from GnuPG < 1.9. -# -msgid "" -msgstr "" -"Project-Id-Version: gnupg2 1.9.7\n" -"Report-Msgid-Bugs-To: translations@gnupg.org\n" -"POT-Creation-Date: 2004-04-29 19:50+0200\n" -"PO-Revision-Date: 2004-04-06 11:47+0200\n" -"Last-Translator: Werner Koch <wk@gnupg.org>\n" -"Language-Team: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=iso-8859-1\n" -"Content-Transfer-Encoding: 8bit\n" - -#: agent/gpg-agent.c:94 agent/protect-tool.c:92 scd/scdaemon.c:92 -msgid "" -"@Options:\n" -" " -msgstr "" -"@Optionen:\n" -" " - -#: agent/gpg-agent.c:96 scd/scdaemon.c:94 -msgid "run in server mode (foreground)" -msgstr "Im Server Modus ausführen" - -#: agent/gpg-agent.c:97 scd/scdaemon.c:95 -msgid "run in daemon mode (background)" -msgstr "Im Daemon Modus ausführen" - -#: agent/gpg-agent.c:98 kbx/kbxutil.c:73 scd/scdaemon.c:96 sm/gpgsm.c:312 -#: tools/gpgconf.c:62 -msgid "verbose" -msgstr "ausführlich" - -#: agent/gpg-agent.c:99 kbx/kbxutil.c:74 scd/scdaemon.c:97 sm/gpgsm.c:313 -msgid "be somewhat more quiet" -msgstr "etwas weniger Aussageb erzeugen" - -#: agent/gpg-agent.c:100 scd/scdaemon.c:98 -msgid "sh-style command output" -msgstr "Ausgabe für /bin/sh" - -#: agent/gpg-agent.c:101 scd/scdaemon.c:99 -msgid "csh-style command output" -msgstr "Ausgabe für /bin/csh" - -#: agent/gpg-agent.c:102 -msgid "|FILE|read options from FILE" -msgstr "|DATEI|Konfigurationsoptionen aus DATEI lesen" - -#: agent/gpg-agent.c:107 scd/scdaemon.c:106 -msgid "do not detach from the console" -msgstr "Im Vordergrund laufen lassen" - -#: agent/gpg-agent.c:108 -msgid "do not grab keyboard and mouse" -msgstr "Tastatur und Maus nicht \"grabben\"" - -#: agent/gpg-agent.c:109 scd/scdaemon.c:107 sm/gpgsm.c:315 -msgid "use a log file for the server" -msgstr "Logausgaben in eine Datei umlenken" - -#: agent/gpg-agent.c:110 -msgid "do not allow multiple connections" -msgstr "Nicht mehr als eine Verbindung erlauben" - -#: agent/gpg-agent.c:124 -msgid "ignore requests to change the TTY" -msgstr "Ignoriere Anfragen, das TTY zu wechseln" - -#: agent/gpg-agent.c:126 -msgid "ignore requests to change the X display" -msgstr "Ignoriere Anfragen, das X-Display zu wechseln" - -#: agent/gpg-agent.c:180 agent/protect-tool.c:124 scd/scdaemon.c:165 -#: sm/gpgsm.c:479 tools/gpgconf.c:85 -msgid "Please report bugs to <" -msgstr "Fehlerberichte bitte an <" - -#: agent/gpg-agent.c:180 agent/protect-tool.c:124 scd/scdaemon.c:165 -#: sm/gpgsm.c:479 tools/gpgconf.c:85 -msgid ">.\n" -msgstr ">.\n" - -#: agent/gpg-agent.c:183 -msgid "Usage: gpg-agent [options] (-h for help)" -msgstr "Gebrauch: gpg-agent [Optionen] (-h für Hilfe)" - -#: agent/gpg-agent.c:185 -msgid "" -"Syntax: gpg-agent [options] [command [args]]\n" -"Secret key management for GnuPG\n" -msgstr "" -"Syntax: gpg-agent [Optionen] [Kommando [Argumente]]\n" -"Verwaltung von geheimen Schlüssel für GnuPG\n" - -#: agent/gpg-agent.c:256 scd/scdaemon.c:239 sm/gpgsm.c:602 -#, c-format -msgid "invalid debug-level `%s' given\n" -msgstr "ungültige Debugebene `%s' angegeben\n" - -#: agent/gpg-agent.c:414 agent/protect-tool.c:1035 kbx/kbxutil.c:230 -#: scd/scdaemon.c:352 sm/gpgsm.c:725 -#, c-format -msgid "libgcrypt is too old (need %s, have %s)\n" -msgstr "" -"Die Bibliothek \"libgcrypt\" is zu alt (benötigt wird %s, vorhanden ist %s)\n" - -#: agent/gpg-agent.c:487 scd/scdaemon.c:432 sm/gpgsm.c:823 -#, c-format -msgid "NOTE: no default option file `%s'\n" -msgstr "Notiz: Voreingestellte Konfigurationsdatei `%s' fehlt\n" - -#: agent/gpg-agent.c:492 agent/gpg-agent.c:955 scd/scdaemon.c:437 -#: sm/gpgsm.c:827 -#, c-format -msgid "option file `%s': %s\n" -msgstr "Konfigurationsdatei `%s': %s\n" - -#: agent/gpg-agent.c:500 scd/scdaemon.c:445 sm/gpgsm.c:834 -#, c-format -msgid "reading options from `%s'\n" -msgstr "Optionen werden aus `%s' gelesen\n" - -#: agent/gpg-agent.c:641 scd/scdaemon.c:619 -msgid "please use the option `--daemon' to run the program in the background\n" -msgstr "" -"Bitte die Option `--daemon' nutzen um das Programm im Hintergund " -"auszuführen\n" - -#: agent/gpg-agent.c:988 agent/gpg-agent.c:1022 -#, c-format -msgid "can't create directory `%s': %s\n" -msgstr "Das Verzeichniss `%s' kann nicht erstell werden: %s\n" - -#: agent/gpg-agent.c:991 agent/gpg-agent.c:1027 -#, c-format -msgid "directory `%s' created\n" -msgstr "Verzeichniss `%s' wurde erstellt\n" - -#: agent/protect-tool.c:127 -msgid "Usage: gpg-protect-tool [options] (-h for help)\n" -msgstr "Gebrauch: gpg-protect-tool [Optionen] (-h für Hilfe)\n" - -#: agent/protect-tool.c:129 -msgid "" -"Syntax: gpg-protect-tool [options] [args]]\n" -"Secret key maintenance tool\n" -msgstr "" -"Syntax: gpg-protect-tool [Optionen] [Argumente]\n" -"Werkzeug zum Bearbeiten von geheimen Schlüsseln\n" - -#: agent/protect-tool.c:1142 -msgid "" -"Please enter the passphrase or the PIN\n" -"needed to complete this operation." -msgstr "" -"Die Eingabe des Mantras (Passphrase) bzw. der PIN\n" -"wird benötigt um diese Aktion auszuführen." - -#: agent/protect-tool.c:1145 -msgid "Passphrase:" -msgstr "Passphrase:" - -#: agent/divert-scd.c:200 -#, c-format -msgid "Please enter the PIN%s%s%s to unlock the card" -msgstr "Bitte geben Sie die PIN%s%s%s ein um die Karte zu entsperren" - -#: agent/genkey.c:108 -#, c-format -msgid "Please enter the passphrase to%0Ato protect your new key" -msgstr "" -"Bitte geben Sie das Mantra (Passphrase) ein%0Aum Ihren Schlüssel zu schützen" - -#: agent/genkey.c:110 agent/genkey.c:224 -msgid "Please re-enter this passphrase" -msgstr "Bitte geben Sie das Mantra (Passphrase) noch einmal ein:" - -#: agent/genkey.c:131 agent/genkey.c:244 -msgid "does not match - try again" -msgstr "Keine Übereinstimmung - bitte nochmal versuchen" - -#: agent/genkey.c:223 -msgid "Please enter the new passphrase" -msgstr "Bitte geben Sie das Mantra (Passphrase) ein:" - -#: agent/query.c:268 -msgid "" -"Please enter your PIN, so that the secret key can be unlocked for this " -"session" -msgstr "" -"Bitte geben Sie Ihre PIN ein, so daß der geheime Schlüssel benutzt werden " -"kann" - -#: agent/query.c:271 -msgid "" -"Please enter your passphrase, so that the secret key can be unlocked for " -"this session" -msgstr "" -"Bitte geben Sie Ihr Mantra (Passphrase) ein, so daß der geheime Schlüssel " -"benutzt werden kann" - -#: agent/query.c:326 agent/query.c:338 -msgid "PIN too long" -msgstr "Die PIN ist zu lang" - -#: agent/query.c:327 -msgid "Passphrase too long" -msgstr "Das Matra (Passphrase) ist zu lang" - -#: agent/query.c:335 -msgid "Invalid characters in PIN" -msgstr "Ungültige Zeichen in der PIN" - -#: agent/query.c:340 -msgid "PIN too short" -msgstr "Die PIN ist zu kurz" - -#: agent/query.c:352 -msgid "Bad PIN" -msgstr "Falsche PIN" - -#: agent/query.c:353 -msgid "Bad Passphrase" -msgstr "Falsches Mantra (Passphrase)" - -#: agent/query.c:392 -msgid "Passphrase" -msgstr "Mantra" - -#: common/sysutils.c:84 -#, c-format -msgid "can't disable core dumps: %s\n" -msgstr "" -"Das Erstellen eines Speicherabzugs (core-dump) kann nicht verhindert werden: " -"%s\n" - -#: common/sysutils.c:159 -#, c-format -msgid "Warning: unsafe ownership on %s \"%s\"\n" -msgstr "WARNUNG: Unsichere Besitzrechte für %s \"%s\"\n" - -#: common/sysutils.c:191 -#, c-format -msgid "Warning: unsafe permissions on %s \"%s\"\n" -msgstr "WARNUNG: Unsichere Zugriffsrechte für %s \"%s\"\n" - -#: common/simple-pwquery.c:272 -msgid "gpg-agent is not available in this session\n" -msgstr "Der gpg-agent ist nicht verfügbar\n" - -#: common/simple-pwquery.c:286 sm/call-agent.c:128 -msgid "malformed GPG_AGENT_INFO environment variable\n" -msgstr "Die Variable GPG_AGENT_INFO ist fehlerhaft\n" - -#: common/simple-pwquery.c:298 sm/call-agent.c:140 -#, c-format -msgid "gpg-agent protocol version %d is not supported\n" -msgstr "Das gpg-agent Protocol %d wird nicht unterstützt\n" - -#: common/simple-pwquery.c:320 -#, c-format -msgid "can't connect to `%s': %s\n" -msgstr "Verbindung zu `%s' kann nicht aufgebaut werden: %s\n" - -#: common/simple-pwquery.c:331 -msgid "communication problem with gpg-agent\n" -msgstr "Kommunikationsproblem mit gpg-agent\n" - -#: common/simple-pwquery.c:341 -msgid "problem setting the gpg-agent options\n" -msgstr "Beim setzen der gpg-agent Optionen ist ein problem aufgetreten\n" - -#: common/simple-pwquery.c:473 -msgid "canceled by user\n" -msgstr "Vom Benutzer abgebrochen\n" - -#: common/simple-pwquery.c:480 -msgid "problem with the agent\n" -msgstr "Problem mit dem Agenten\n" - -#: jnlib/logging.c:547 -#, c-format -msgid "you found a bug ... (%s:%d)\n" -msgstr "Sie haben einen Bug (Softwarefehler) gefunden ... (%s:%d)\n" - -#: kbx/kbxutil.c:62 sm/gpgsm.c:223 tools/gpgconf.c:53 -msgid "" -"@Commands:\n" -" " -msgstr "" -"@Kommandos:\n" -" " - -#: kbx/kbxutil.c:68 sm/gpgsm.c:258 tools/gpgconf.c:59 -msgid "" -"@\n" -"Options:\n" -" " -msgstr "" -"@\n" -"Optionen:\n" -" " - -#: kbx/kbxutil.c:70 sm/gpgsm.c:260 -msgid "create ascii armored output" -msgstr "Ausgabe mit ASCII Hülle wird erzeugt" - -#: kbx/kbxutil.c:72 sm/gpgsm.c:311 tools/gpgconf.c:61 -msgid "use as output file" -msgstr "als Ausgabedatei benutzen" - -#: kbx/kbxutil.c:75 sm/gpgsm.c:320 tools/gpgconf.c:64 -msgid "do not make any changes" -msgstr "Keine Änderungen durchführen" - -#: kbx/kbxutil.c:77 -msgid "set debugging flags" -msgstr "Debug Flags setzen" - -#: kbx/kbxutil.c:78 -msgid "enable full debugging" -msgstr "Alle Debug Flags setzen" - -#: kbx/kbxutil.c:99 -msgid "Please report bugs to " -msgstr "Bite richten sie Berichte über Bugs (Softwarefehler) an " - -#: kbx/kbxutil.c:99 -msgid ".\n" -msgstr ".\n" - -#: kbx/kbxutil.c:103 -msgid "Usage: kbxutil [options] [files] (-h for help)" -msgstr "Gebrauch: kbxutil [Optionen] [Dateien] (-h für Hilfe)" - -#: kbx/kbxutil.c:106 -msgid "" -"Syntax: kbxutil [options] [files]\n" -"list, export, import Keybox data\n" -msgstr "" -"Syntax: kbxutil [Optionen] [Dateien]\n" -"Anlistem exportieren und Importieren von KeyBox Dateien\n" - -#: scd/scdaemon.c:100 sm/gpgsm.c:332 -msgid "read options from file" -msgstr "Konfigurationsoptionen aus Datei lesen" - -#: scd/scdaemon.c:105 -msgid "|N|set OpenSC debug level to N" -msgstr "|N|Den OpenSC Debugstufe auf N setzen" - -#: scd/scdaemon.c:108 -msgid "|N|connect to reader at port N" -msgstr "|N|Verbinde mit dem Leser auf Port N" - -#: scd/scdaemon.c:109 -msgid "|NAME|use NAME as ct-API driver" -msgstr "|NAME|Benutze NAME als CT-API Treiber" - -#: scd/scdaemon.c:110 -msgid "|NAME|use NAME as PC/SC driver" -msgstr "|NAME|Benutze NAME als PC/SC Treiber" - -#: scd/scdaemon.c:113 -msgid "do not use the internal CCID driver" -msgstr "Den internen CCID Treiber nicht benutzen" - -#: scd/scdaemon.c:120 -msgid "do not use the OpenSC layer" -msgstr "Den OpenSC basierten Kartenzugriff nicht nutzen" - -#: scd/scdaemon.c:125 -msgid "allow the use of admin card commands" -msgstr "Erlaube die Benuztung von \"Admin\" Kommandos" - -#: scd/scdaemon.c:168 -msgid "Usage: scdaemon [options] (-h for help)" -msgstr "Gebrauch: scdaemon [Optionen] (-h für Hilfe)" - -#: scd/scdaemon.c:170 -msgid "" -"Syntax: scdaemon [options] [command [args]]\n" -"Smartcard daemon for GnuPG\n" -msgstr "" -"Synatx: scdaemon [Optionen] [Kommando [Argumente]]\n" -"Smartcard Daemon für GnuPG\n" - -#: sm/base64.c:315 -#, c-format -msgid "invalid radix64 character %02x skipped\n" -msgstr "Ungültiges Basis-64 Zeichen %02X wurde übergangen\n" - -#: sm/call-agent.c:88 -msgid "no running gpg-agent - starting one\n" -msgstr "Kein aktiver gpg-agent - es wird einer gestarted\n" - -#: sm/call-agent.c:151 -msgid "can't connect to the agent - trying fall back\n" -msgstr "Verbindung zum gpg-agent nicht möglich - Ersatzmethode wird versucht\n" - -#: sm/call-dirmngr.c:164 -msgid "no running dirmngr - starting one\n" -msgstr "Kein aktiver Dirmngr - es wird einer gestartet\n" - -#: sm/call-dirmngr.c:202 -msgid "malformed DIRMNGR_INFO environment variable\n" -msgstr "Die Variable DIRMNGR_INFO ist fehlerhaft\n" - -#: sm/call-dirmngr.c:214 -#, c-format -msgid "dirmngr protocol version %d is not supported\n" -msgstr "Die Dirmngr Protokollversion %d wird nicht unterstützt\n" - -#: sm/call-dirmngr.c:225 -msgid "can't connect to the dirmngr - trying fall back\n" -msgstr "" -"Verbindung zum Dirmngr kann nicht aufgebaut werden - Ersatzmethode wird " -"versucht\n" - -#: sm/certdump.c:59 sm/certdump.c:142 -msgid "none" -msgstr "keine" - -#: sm/certdump.c:151 -msgid "[none]" -msgstr "[keine]" - -#: sm/certdump.c:490 -msgid "[Error - No name]" -msgstr "[Fehler - Kein Name]" - -#: sm/certdump.c:499 -msgid "[Error - unknown encoding]" -msgstr "[Fehler - Unbekannte Kodierung]" - -#: sm/certdump.c:503 -msgid "[Error - invalid encoding]" -msgstr "[Fehler - Ungültige Kodierung]" - -#: sm/certdump.c:508 -msgid "[Error - invalid DN]" -msgstr "[Fehler - Ungültiger DN]" - -#: sm/certdump.c:652 -#, c-format -msgid "" -"Please enter the passphrase to unlock the secret key for:\n" -"\"%s\"\n" -"S/N %s, ID %08lX, created %s" -msgstr "" -"Bitte geben Sie die Passphrase an, um den \n" -"geheimen Schlüssels von\n" -"\"%s\"\n" -"S/N %s, ID %08lX, erzeugt %s\n" -"zu entsperren" - -#: sm/certlist.c:113 -msgid "no key usage specified - assuming all usages\n" -msgstr "" -"Schlüsselverwendungszweck nicht vorhanden - für alle Zwecke akzeptiert\n" - -#: sm/certlist.c:123 sm/keylist.c:224 -#, c-format -msgid "error getting key usage information: %s\n" -msgstr "Fehler beim holen der Schlüsselbenutzungsinformationen: %s\n" - -#: sm/certlist.c:133 -msgid "certificate should have not been used for certification\n" -msgstr "Das Zertifikat hätte nicht zum Zertifizieren benutzt werden sollen\n" - -#: sm/certlist.c:144 -msgid "certificate should have not been used for encryption\n" -msgstr "Das Zertifikat hatte nicht zum Verschlüsseln benutzt werden sollen\n" - -#: sm/certlist.c:145 -msgid "certificate should have not been used for signing\n" -msgstr "Das Zertifikat hatte nicht zum Signieren benutzt werden sollen\n" - -#: sm/certlist.c:146 -msgid "certificate is not usable for encryption\n" -msgstr "Das Zertifikat kann nicht zum Verschlüsseln benutzt werden\n" - -#: sm/certlist.c:147 -msgid "certificate is not usable for signing\n" -msgstr "Das Zertifikat kann nicht zum Signieren benutzt werden\n" - -#: sm/certchain.c:109 -#, c-format -msgid "critical certificate extension %s is not supported" -msgstr "Die kritische Zertifikaterweiterung %s wird nicht unterstützt" - -#: sm/certchain.c:131 -msgid "issuer certificate is not marked as a CA" -msgstr "Das Herausgeberzertifikat ist nicht für eine CA gekennzeichnet" - -#: sm/certchain.c:169 -msgid "critical marked policy without configured policies" -msgstr "kritische Richtlinie ohne konfigurierte Richtlinien" - -#: sm/certchain.c:185 sm/certchain.c:214 -msgid "note: non-critical certificate policy not allowed" -msgstr "Notiz: Die unkritische Zertifikatrichtlinie ist nicht erlaubt" - -#: sm/certchain.c:189 sm/certchain.c:218 -msgid "certificate policy not allowed" -msgstr "Die Zertifikatrichtlinie ist nicht erlaubt" - -#: sm/certchain.c:349 -msgid "looking up issuer at external location\n" -msgstr "Der Herausgeber wird von einer externen Stelle gesucht\n" - -#: sm/certchain.c:367 -#, c-format -msgid "number of issuers matching: %d\n" -msgstr "Anzahl der übereinstimmenden Heruasgeber: %d\n" - -#: sm/certchain.c:403 sm/certchain.c:561 sm/certchain.c:909 sm/decrypt.c:260 -#: sm/encrypt.c:341 sm/sign.c:324 sm/verify.c:107 -msgid "failed to allocated keyDB handle\n" -msgstr "Ein keyDB Handle konnte nicht bereitgestellt werden\n" - -#: sm/certchain.c:492 -msgid "certificate has been revoked" -msgstr "Das Zertifikat wurde widerrufen" - -#: sm/certchain.c:501 -msgid "no CRL found for certificate" -msgstr "Keine CRL für das Zertifikat gefunden" - -#: sm/certchain.c:505 -msgid "the available CRL is too old" -msgstr "Die vorhandene CRL ist zu alt" - -#: sm/certchain.c:507 -msgid "please make sure that the \"dirmngr\" is properly installed\n" -msgstr "" -"Bite vergewissern Sie sich das der \"dirmngr\" richtig installierrt ist\n" - -#: sm/certchain.c:512 -#, c-format -msgid "checking the CRL failed: %s" -msgstr "Die CRL konnte nicht geprüft werden: %s" - -#: sm/certchain.c:581 -msgid "no issuer found in certificate" -msgstr "Im Zertifikat ist kein Herausgeber enthalten" - -#: sm/certchain.c:594 -#, c-format -msgid "certificate with invalid validity: %s" -msgstr "Zertifikat mit unzulässiger Gültigkeit: %s" - -#: sm/certchain.c:610 -msgid "certificate not yet valid" -msgstr "Das Zertifikat ist noch nicht gültig" - -#: sm/certchain.c:623 -msgid "certificate has expired" -msgstr "Das Zertifikat ist abgelaufen" - -#: sm/certchain.c:660 -msgid "selfsigned certificate has a BAD signature" -msgstr "Das eigenbeglaubigte Zertifikat hat eine FALSCHE Signatur" - -#: sm/certchain.c:674 -msgid "root certificate is not marked trusted" -msgstr "Das Wurzelzertifikat ist nicht als vertrauenswürdig markiert" - -#: sm/certchain.c:680 -#, c-format -msgid "fingerprint=%s\n" -msgstr "Fingerprint=%s\n" - -#: sm/certchain.c:685 -msgid "root certificate has now been marked as trusted\n" -msgstr "Das Wurzelzertifikat wurde nun als vertrauenswürdig markiert\n" - -#: sm/certchain.c:700 -#, c-format -msgid "checking the trust list failed: %s\n" -msgstr "Fehler beim Prüfen der vertrauenswürdigen Zertifikate: %s\n" - -#: sm/certchain.c:721 sm/import.c:145 -msgid "certificate chain too long\n" -msgstr "Der Zertifikatkette ist zu lang\n" - -#: sm/certchain.c:733 -msgid "issuer certificate not found" -msgstr "Herausgeberzertifikat nicht gefunden" - -#: sm/certchain.c:766 -msgid "certificate has a BAD signature" -msgstr "Das Zertifikat hat eine FALSCHE Signatur" - -#: sm/certchain.c:789 -msgid "found another possible matching CA certificate - trying again" -msgstr "" -"Eine anderes möglicherweise passendes CA-Zertifikat gefunden - versuche " -"nochmal" - -#: sm/certchain.c:812 -#, c-format -msgid "certificate chain longer than allowed by CA (%d)" -msgstr "Die Zertifikatkette ist länger als von der CA erlaubt (%d)" - -#: sm/decrypt.c:127 -msgid "" -"WARNING: message was encrypted with a weak key in the symmetric cipher.\n" -msgstr "" -"WARNUNG: Die Nachricht wurde mich einem schwachen Schlüssel (Weak Key) " -"erzeugt\n" - -#: sm/decrypt.c:325 -msgid "(this is the RC2 algorithm)\n" -msgstr "(Dies ist der RC-2 Algorithmus)\n" - -#: sm/decrypt.c:327 -msgid "(this does not seem to be an encrypted message)\n" -msgstr "(dies is wahrscheinlich keine verschlüsselte Nachricht)\n" - -#: sm/delete.c:51 sm/delete.c:102 -#, c-format -msgid "certificate `%s' not found: %s\n" -msgstr "Zertifikat `%s' nicht gefunden: %s\n" - -#: sm/delete.c:112 sm/keydb.c:1403 sm/keydb.c:1496 -#, c-format -msgid "error locking keybox: %s\n" -msgstr "Fehler beim Sperren der Keybox: %s\n" - -#: sm/delete.c:133 -#, c-format -msgid "duplicated certificate `%s' deleted\n" -msgstr "Doppeltes Zertifikat `%s' gelöscht\n" - -#: sm/delete.c:135 -#, c-format -msgid "certificate `%s' deleted\n" -msgstr "Zertifikat `%s' gelöscht\n" - -#: sm/delete.c:165 -#, c-format -msgid "deleting certificate \"%s\" failed: %s\n" -msgstr "Fehler beim Löschen des Zertifikats \"%s\": %s\n" - -#: sm/encrypt.c:120 -msgid "weak key created - retrying\n" -msgstr "Schwacher Schlüssel - es wird erneut versucht\n" - -#: sm/encrypt.c:332 -msgid "no valid recipients given\n" -msgstr "Keine gültigen Empfänger angegeben\n" - -#: sm/gpgsm.c:225 -msgid "|[FILE]|make a signature" -msgstr "|[DATEI]|Erzeuge eine Signatur" - -#: sm/gpgsm.c:226 -msgid "|[FILE]|make a clear text signature" -msgstr "|[DATEI]|Erzeuge eine Klartextsignatur" - -#: sm/gpgsm.c:227 -msgid "make a detached signature" -msgstr "Erzeuge eine abgetrennte Signatur" - -#: sm/gpgsm.c:228 -msgid "encrypt data" -msgstr "Verschlüssele die Daten" - -#: sm/gpgsm.c:229 -msgid "encryption only with symmetric cipher" -msgstr "Verschlüsselung nur mit symmetrischem Algrithmus" - -#: sm/gpgsm.c:230 -msgid "decrypt data (default)" -msgstr "Enschlüssele die Daten" - -#: sm/gpgsm.c:231 -msgid "verify a signature" -msgstr "Überprüfen einer Signatur" - -#: sm/gpgsm.c:233 -msgid "list keys" -msgstr "Schlüssel anzeigen" - -#: sm/gpgsm.c:234 -msgid "list external keys" -msgstr "Externe Schlüssel anzeigen" - -#: sm/gpgsm.c:235 -msgid "list secret keys" -msgstr "Geheime Schlüssel anzeigen" - -#: sm/gpgsm.c:236 -msgid "list certificate chain" -msgstr "Schlüssel mit Zertifikatekette anzeigen" - -#: sm/gpgsm.c:238 -msgid "list keys and fingerprints" -msgstr "Schlüssel und Fingerprint anzeigen" - -#: sm/gpgsm.c:239 -msgid "generate a new key pair" -msgstr "Neues Schlüsselpaar erzeugen" - -#: sm/gpgsm.c:240 -msgid "remove key from the public keyring" -msgstr "Schlüssel aus dem öffentlichen Schlüsselbund löschen" - -#: sm/gpgsm.c:241 -msgid "export keys to a key server" -msgstr "Schlüssen an eine Schlüsselserver exportieren" - -#: sm/gpgsm.c:242 -msgid "import keys from a key server" -msgstr "Schlüssel von einem Schlüsselserver importieren" - -#: sm/gpgsm.c:243 -msgid "import certificates" -msgstr "Zertifikate importieren" - -#: sm/gpgsm.c:244 -msgid "export certificates" -msgstr "Zertifikate exportieren" - -#: sm/gpgsm.c:245 -msgid "register a smartcard" -msgstr "Smartcard registrieren" - -#: sm/gpgsm.c:246 -msgid "run in server mode" -msgstr "Im Server Modus ausführen" - -#: sm/gpgsm.c:247 -msgid "pass a command to the dirmngr" -msgstr "Das Kommand an den Dirmngr durchreichen" - -#: sm/gpgsm.c:249 -msgid "invoke gpg-protect-tool" -msgstr "Rufe das gpg-protect-tool auf" - -#: sm/gpgsm.c:250 -msgid "change a passphrase" -msgstr "Das Mantra (Passphrase) ändern" - -#: sm/gpgsm.c:262 -msgid "create base-64 encoded output" -msgstr "Ausgabe im Basis-64 format erzeugen" - -#: sm/gpgsm.c:264 -msgid "assume input is in PEM format" -msgstr "Eingabedaten sind im PEM Format" - -#: sm/gpgsm.c:266 -msgid "assume input is in base-64 format" -msgstr "Eingabedaten sin im Basis-64 Format" - -#: sm/gpgsm.c:268 -msgid "assume input is in binary format" -msgstr "Eingabedaten sind im Binärformat" - -#: sm/gpgsm.c:270 -msgid "|NAME|encrypt for NAME" -msgstr "|NAME|Verschlüsseln für NAME" - -#: sm/gpgsm.c:273 -msgid "never consult a CRL" -msgstr "Niemals eine CRL konsultieren" - -#: sm/gpgsm.c:278 -msgid "check validity using OCSP" -msgstr "Die Gültigkeit mittels OCSP prüfen" - -#: sm/gpgsm.c:281 -msgid "|N|number of certificates to include" -msgstr "|N|Sende N Zertifikate mit" - -#: sm/gpgsm.c:284 -msgid "|FILE|take policy information from FILE" -msgstr "|DATEI|Richtlinieninformationen DATEI entnehmen" - -#: sm/gpgsm.c:287 -msgid "do not check certificate policies" -msgstr "Zertikikatrichtlinien nicht überprüfen" - -#: sm/gpgsm.c:291 -msgid "fetch missing issuer certificates" -msgstr "Fehlende Zertifikate automatisch holen" - -#: sm/gpgsm.c:295 -msgid "|NAME|use NAME as default recipient" -msgstr "|NAME|Benutze NAME als voreingestellten Empfänger" - -#: sm/gpgsm.c:297 -msgid "use the default key as default recipient" -msgstr "Benuzte voreingestellten Schlüssel als Standardempfänger" - -#: sm/gpgsm.c:303 -msgid "use this user-id to sign or decrypt" -msgstr "Benuzte diese Benutzer ID zum Signieren oder Entschlüsseln" - -#: sm/gpgsm.c:306 -msgid "|N|set compress level N (0 disables)" -msgstr "|N|Benutze Komprimierungsstufe N" - -#: sm/gpgsm.c:308 -msgid "use canonical text mode" -msgstr "Kanonischen Textmodus benutzen" - -#: sm/gpgsm.c:314 -msgid "don't use the terminal at all" -msgstr "Das Terminal überhaupt nicht benutzen" - -#: sm/gpgsm.c:317 -msgid "force v3 signatures" -msgstr "Version 3 Signaturen erzwingen" - -#: sm/gpgsm.c:318 -msgid "always use a MDC for encryption" -msgstr "Immer das MDC Verfahren zum verschlüsseln mitbenutzen" - -#: sm/gpgsm.c:323 -msgid "batch mode: never ask" -msgstr "Stapelverarbeitungs Modus: Nie nachfragen" - -#: sm/gpgsm.c:324 -msgid "assume yes on most questions" -msgstr "\"Ja\" auf die meisten Anfragen annehmen" - -#: sm/gpgsm.c:325 -msgid "assume no on most questions" -msgstr "\"Nein\" auf die meisten Anfragen annehmen" - -#: sm/gpgsm.c:327 -msgid "add this keyring to the list of keyrings" -msgstr "Diesen Keyring in die Liste der Keyrings aufnehmen" - -#: sm/gpgsm.c:328 -msgid "add this secret keyring to the list" -msgstr "Diese geheimen Keyring in die Liste aufnehmen" - -#: sm/gpgsm.c:329 -msgid "|NAME|use NAME as default secret key" -msgstr "|NAME|Benutze NAME als voreingestellten Schlüssel" - -#: sm/gpgsm.c:330 -msgid "|HOST|use this keyserver to lookup keys" -msgstr "|HOST|Benutze HOST als Schlüsselserver" - -#: sm/gpgsm.c:331 -msgid "|NAME|set terminal charset to NAME" -msgstr "|NAME|Den Zeichensatz für das Terminal auf NAME setzen" - -#: sm/gpgsm.c:340 -msgid "|FD|write status info to this FD" -msgstr "|FD|Statusinformationen auf Dateidescriptor FD schreiben" - -#: sm/gpgsm.c:347 -msgid "|FILE|load extension module FILE" -msgstr "|DATEI|Das Erweiterungsmodul DATEI laden" - -#: sm/gpgsm.c:353 -msgid "|NAME|use cipher algorithm NAME" -msgstr "|NAME|Den Verhsclüsselungsalgrithmus NAME benutzen" - -#: sm/gpgsm.c:355 -msgid "|NAME|use message digest algorithm NAME" -msgstr "|NAME|Den Hashalgorithmus NAME benutzen" - -#: sm/gpgsm.c:357 -msgid "|N|use compress algorithm N" -msgstr "|N|Den Kompressionsalgorithmus Nummer N benutzen" - -#: sm/gpgsm.c:365 -msgid "" -"@\n" -"(See the man page for a complete listing of all commands and options)\n" -msgstr "" -"@\n" -"(Die \"man\" Seite beschreibt alle Kommands und Optionen)\n" - -#: sm/gpgsm.c:368 -msgid "" -"@\n" -"Examples:\n" -"\n" -" -se -r Bob [file] sign and encrypt for user Bob\n" -" --clearsign [file] make a clear text signature\n" -" --detach-sign [file] make a detached signature\n" -" --list-keys [names] show keys\n" -" --fingerprint [names] show fingerprints\n" -msgstr "" -"@\n" -"Beispiele:\n" -"\n" -" -se -r Bob [Datei] Signieren und verschlüsseln für Benutzer Bob\\n\n" -" --clearsign [Datei] Eine Klartextsignatur erzeugen\\n\n" -" --detach-sign [Datei] Eine abgetrennte Signatur erzeugen\\n\n" -" --list-keys [Namen] Schlüssel anzeigenn\n" -" --fingerprint [Namen] \"Fingerabdrücke\" anzeigen\\n\n" - -#: sm/gpgsm.c:482 -msgid "Usage: gpgsm [options] [files] (-h for help)" -msgstr "Gebrauch: gpgsm [Optionen] [Dateien] (-h für Hilfe)" - -#: sm/gpgsm.c:485 -msgid "" -"Syntax: gpgsm [options] [files]\n" -"sign, check, encrypt or decrypt using the S/MIME protocol\n" -"default operation depends on the input data\n" -msgstr "" -"Gebrauch: gpgsm [Optionen] [Dateien]\n" -"Signieren, prüfen, ver- und entschlüsseln mittels S/MIME protocol\n" - -#: sm/gpgsm.c:492 -msgid "" -"\n" -"Supported algorithms:\n" -msgstr "" -"\n" -"Unterstützte Algorithmen:\n" - -#: sm/gpgsm.c:573 -msgid "usage: gpgsm [options] " -msgstr "Gebrauch: gpgsm [Optionen] " - -#: sm/gpgsm.c:639 -msgid "conflicting commands\n" -msgstr "Widersprechende Kommandos\n" - -#: sm/gpgsm.c:655 -#, c-format -msgid "can't encrypt to `%s': %s\n" -msgstr "Verschlüsseln für `%s' nicht möglich: %s\n" - -#: sm/gpgsm.c:730 -#, c-format -msgid "libksba is too old (need %s, have %s)\n" -msgstr "Die Bibliothek Libksba is nicht aktuell (benötige %s, habe %s)\n" - -#: sm/gpgsm.c:1169 -msgid "WARNING: program may create a core file!\n" -msgstr "WARNUNG: Programm könnte eine core-dump-Datei schreiben!\n" - -#: sm/gpgsm.c:1181 -msgid "WARNING: running with faked system time: " -msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: " - -#: sm/gpgsm.c:1201 -msgid "selected cipher algorithm is invalid\n" -msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\n" - -#: sm/gpgsm.c:1209 -msgid "selected digest algorithm is invalid\n" -msgstr "Das ausgewählte Hashverfahren ist ungültig\n" - -#: sm/gpgsm.c:1239 -#, c-format -msgid "can't sign using `%s': %s\n" -msgstr "Signieren mit `%s' nicht möglich: %s\n" - -#: sm/gpgsm.c:1406 -msgid "this command has not yet been implemented\n" -msgstr "Diee Kommando wurde noch nicht implementiert\n" - -#: sm/gpgsm.c:1629 sm/gpgsm.c:1662 -#, c-format -msgid "can't open `%s': %s\n" -msgstr "Datei `%s' kann nicht geöffnet werden: %s\n" - -#: sm/import.c:114 -#, c-format -msgid "total number processed: %lu\n" -msgstr "gesamte verarbeitete Anzahl: %lu\n" - -#: sm/import.c:117 -#, c-format -msgid " imported: %lu" -msgstr " importiert: %lu" - -#: sm/import.c:121 -#, c-format -msgid " unchanged: %lu\n" -msgstr " nicht geändert: %lu\n" - -#: sm/import.c:123 -#, c-format -msgid " not imported: %lu\n" -msgstr " nicht importiert: %lu\n" - -#: sm/import.c:204 -msgid "error storing certificate\n" -msgstr "Fehler beim speichern des Zertifikats\n" - -#: sm/import.c:211 -msgid "basic certificate checks failed - not imported\n" -msgstr "Grundlegende Zertifikatprüfungen fehlgeschlagen - nicht importiert\n" - -#: sm/import.c:396 sm/import.c:428 -#, c-format -msgid "error importing certificate: %s\n" -msgstr "Fehler beim Importieren des Zertifikats: %s\n" - -#: sm/import.c:457 -#, c-format -msgid "error creating a pipe: %s\n" -msgstr "Fehler beim Erzeugen einer \"Pipe\": %s\n" - -#: sm/import.c:465 -#, c-format -msgid "error forking process: %s\n" -msgstr "Fehler beim \"Forken\" des Prozess: %s\n" - -#: sm/import.c:562 sm/import.c:587 -#, c-format -msgid "error creating temporary file: %s\n" -msgstr "Fehler beim Erstellen einer temporären Datei: %s\n" - -#: sm/import.c:570 -#, c-format -msgid "error writing to temporary file: %s\n" -msgstr "Fehler beim Schreiben auf eine temporäre Datei: %s\n" - -#: sm/import.c:579 -#, c-format -msgid "error reading input: %s\n" -msgstr "Fehler beim Lesen der Eingabe: %s\n" - -#: sm/import.c:649 -#, c-format -msgid "waiting for protect-tool to terminate failed: %s\n" -msgstr "" -"Das Warten auf die Beendigung des protect-tools ist fehlgeschlagen: %s\n" - -#: sm/import.c:652 -#, c-format -msgid "error running `%s': probably not installed\n" -msgstr "Feler bei Ausführung von `%s': wahrscheinlich nicht installiert\n" - -#: sm/import.c:654 -#, c-format -msgid "error running `%s': exit status %d\n" -msgstr "Fehler bei Ausführung von `%s': Endestatus %d\n" - -#: sm/import.c:657 -#, c-format -msgid "error running `%s': terminated\n" -msgstr "Fehler beim Ausführen von `%s': beendet\n" - -#: sm/keydb.c:189 -#, c-format -msgid "error creating keybox `%s': %s\n" -msgstr "Die \"Keybox\" `%s' konnte nicht erstellt werden: %s\n" - -#: sm/keydb.c:192 -msgid "you may want to start the gpg-agent first\n" -msgstr "Sie sollten zuerst den gpg-agent starten\n" - -#: sm/keydb.c:197 -#, c-format -msgid "keybox `%s' created\n" -msgstr "Die \"Keybox\" `%s' wurde erstellt\n" - -#: sm/keydb.c:220 -#, c-format -msgid "can't create lock for `%s'\n" -msgstr "Datei `%s' konnte nicht gesperrt werden\n" - -#: sm/keydb.c:1327 sm/keydb.c:1389 -msgid "failed to get the fingerprint\n" -msgstr "Kann den Fingerprint nicht ermitteln\n" - -#: sm/keydb.c:1334 sm/keydb.c:1396 -msgid "failed to allocate keyDB handle\n" -msgstr "Kann keinen KeyDB Handler bereitstellen\n" - -#: sm/keydb.c:1351 -#, c-format -msgid "problem looking for existing certificate: %s\n" -msgstr "Problem bei der Suche nach vorhandenem Zertifikat: %s\n" - -#: sm/keydb.c:1359 -#, c-format -msgid "error finding writable keyDB: %s\n" -msgstr "Fehler bei der Suche nach einer schreibbaren KeyDB: %s\n" - -#: sm/keydb.c:1367 -#, c-format -msgid "error storing certificate: %s\n" -msgstr "Fehler beim Speichern des Zertifikats: %s\n" - -#: sm/keydb.c:1411 -#, c-format -msgid "problem re-searching certificate: %s\n" -msgstr "Problem bei Wiederfinden des Zertifikats: %s\n" - -#: sm/keydb.c:1420 sm/keydb.c:1508 -#, c-format -msgid "error getting stored flags: %s\n" -msgstr "Fehler beim Holen der gespeicherten Flags: %s\n" - -#: sm/keydb.c:1429 sm/keydb.c:1519 -#, c-format -msgid "error storing flags: %s\n" -msgstr "Fehler beim Speichern der Flags: %s\n" - -#: sm/verify.c:387 -msgid "Signature made " -msgstr "Signatur erzeugt am " - -#: sm/verify.c:391 -msgid "[date not given]" -msgstr "[Datum nicht vorhanden]" - -#: sm/verify.c:392 -#, c-format -msgid " using certificate ID %08lX\n" -msgstr "mittels Zertifikat ID %08lX\n" - -#: sm/verify.c:505 -msgid "Good signature from" -msgstr "Korrekte Signatur von" - -#: sm/verify.c:506 -msgid " aka" -msgstr " alias" - -#: tools/gpgconf.c:55 -msgid "list all components" -msgstr "Liste aller Komponenten" - -#: tools/gpgconf.c:56 -msgid "|COMPONENT|list options" -msgstr "|KOMPONENTE|Zeige die Optionen an" - -#: tools/gpgconf.c:57 -msgid "|COMPONENT|change options" -msgstr "|KOMPONENTE|Ändere die Optionen" - -#: tools/gpgconf.c:63 -msgid "quiet" -msgstr "Weniger Ausgaben" - -#: tools/gpgconf.c:65 -msgid "activate changes at runtime, if possible" -msgstr "Aktiviere Änderungen zur Laufzeit; falls möglich" - -#: tools/gpgconf.c:88 -msgid "Usage: gpgconf [options] (-h for help)" -msgstr "Gebrauch: gpgconf [Optionen] (-h für Hilfe)" - -#: tools/gpgconf.c:91 -msgid "" -"Syntax: gpgconf [options]\n" -"Manage configuration options for tools of the GnuPG system\n" -msgstr "" -"Syntax: gpgconf {Optionen]\n" -"Verwalte Konfigurationsoptionen für Programme des GnuPG Systems\n" - -#: tools/gpgconf.c:180 -msgid "usage: gpgconf [options] " -msgstr "Gebrauch: gpgconf [Optionen] " - -#: tools/gpgconf.c:181 -msgid "Need one component argument" -msgstr "Benötige ein Komponenten Argument" - -#: tools/gpgconf.c:190 -msgid "Component not found" -msgstr "Komponente nicht gefunden" - -#~ msgid "Enter passphrase:" -#~ msgstr "Bitte das Mantra (Passphrase) eingeben:" - -#~ msgid "[error]" -#~ msgstr "[Fehler]" - -#~ msgid "no key usage specified - accepted for encryption\n" -#~ msgstr "" -#~ "Schlüsselverwendungszweck nicht vorhanden - wird zum Verschlüsseln " -#~ "akzeptiert\n" - -#~ msgid " skipped new keys: %lu\n" -#~ msgstr " übersprungene Schlüssel: %lu\n" diff --git a/po/en@boldquot.header b/po/en@boldquot.header deleted file mode 100644 index fedb6a06d..000000000 --- a/po/en@boldquot.header +++ /dev/null @@ -1,25 +0,0 @@ -# All this catalog "translates" are quotation characters. -# The msgids must be ASCII and therefore cannot contain real quotation -# characters, only substitutes like grave accent (0x60), apostrophe (0x27) -# and double quote (0x22). These substitutes look strange; see -# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html -# -# This catalog translates grave accent (0x60) and apostrophe (0x27) to -# left single quotation mark (U+2018) and right single quotation mark (U+2019). -# It also translates pairs of apostrophe (0x27) to -# left single quotation mark (U+2018) and right single quotation mark (U+2019) -# and pairs of quotation mark (0x22) to -# left double quotation mark (U+201C) and right double quotation mark (U+201D). -# -# When output to an UTF-8 terminal, the quotation characters appear perfectly. -# When output to an ISO-8859-1 terminal, the single quotation marks are -# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to -# grave/acute accent (by libiconv), and the double quotation marks are -# transliterated to 0x22. -# When output to an ASCII terminal, the single quotation marks are -# transliterated to apostrophes, and the double quotation marks are -# transliterated to 0x22. -# -# This catalog furthermore displays the text between the quotation marks in -# bold face, assuming the VT100/XTerm escape sequences. -# diff --git a/po/en@quot.header b/po/en@quot.header deleted file mode 100644 index a9647fc35..000000000 --- a/po/en@quot.header +++ /dev/null @@ -1,22 +0,0 @@ -# All this catalog "translates" are quotation characters. -# The msgids must be ASCII and therefore cannot contain real quotation -# characters, only substitutes like grave accent (0x60), apostrophe (0x27) -# and double quote (0x22). These substitutes look strange; see -# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html -# -# This catalog translates grave accent (0x60) and apostrophe (0x27) to -# left single quotation mark (U+2018) and right single quotation mark (U+2019). -# It also translates pairs of apostrophe (0x27) to -# left single quotation mark (U+2018) and right single quotation mark (U+2019) -# and pairs of quotation mark (0x22) to -# left double quotation mark (U+201C) and right double quotation mark (U+201D). -# -# When output to an UTF-8 terminal, the quotation characters appear perfectly. -# When output to an ISO-8859-1 terminal, the single quotation marks are -# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to -# grave/acute accent (by libiconv), and the double quotation marks are -# transliterated to 0x22. -# When output to an ASCII terminal, the single quotation marks are -# transliterated to apostrophes, and the double quotation marks are -# transliterated to 0x22. -# diff --git a/po/insert-header.sin b/po/insert-header.sin deleted file mode 100644 index b26de01f6..000000000 --- a/po/insert-header.sin +++ /dev/null @@ -1,23 +0,0 @@ -# Sed script that inserts the file called HEADER before the header entry. -# -# At each occurrence of a line starting with "msgid ", we execute the following -# commands. At the first occurrence, insert the file. At the following -# occurrences, do nothing. The distinction between the first and the following -# occurrences is achieved by looking at the hold space. -/^msgid /{ -x -# Test if the hold space is empty. -s/m/m/ -ta -# Yes it was empty. First occurrence. Read the file. -r HEADER -# Output the file's contents by reading the next line. But don't lose the -# current line while doing this. -g -N -bb -:a -# The hold space was nonempty. Following occurrences. Do nothing. -x -:b -} diff --git a/po/quot.sed b/po/quot.sed deleted file mode 100644 index 0122c4631..000000000 --- a/po/quot.sed +++ /dev/null @@ -1,6 +0,0 @@ -s/"\([^"]*\)"/“\1â€/g -s/`\([^`']*\)'/‘\1’/g -s/ '\([^`']*\)' / ‘\1’ /g -s/ '\([^`']*\)'$/ ‘\1’/g -s/^'\([^`']*\)' /‘\1’ /g -s/“â€/""/g diff --git a/po/remove-potcdate.sed b/po/remove-potcdate.sed deleted file mode 100644 index edb38d704..000000000 --- a/po/remove-potcdate.sed +++ /dev/null @@ -1,11 +0,0 @@ -/^"POT-Creation-Date: .*"$/{ -x -s/P/P/ -ta -g -d -bb -:a -x -:b -} diff --git a/po/remove-potcdate.sin b/po/remove-potcdate.sin deleted file mode 100644 index 2436c49e7..000000000 --- a/po/remove-potcdate.sin +++ /dev/null @@ -1,19 +0,0 @@ -# Sed script that remove the POT-Creation-Date line in the header entry -# from a POT file. -# -# The distinction between the first and the following occurrences of the -# pattern is achieved by looking at the hold space. -/^"POT-Creation-Date: .*"$/{ -x -# Test if the hold space is empty. -s/P/P/ -ta -# Yes it was empty. First occurrence. Remove the line. -g -d -bb -:a -# The hold space was nonempty. Following occurrences. Do nothing. -x -:b -} diff --git a/scd/ChangeLog b/scd/ChangeLog deleted file mode 100644 index e04575c75..000000000 --- a/scd/ChangeLog +++ /dev/null @@ -1,659 +0,0 @@ -2004-06-16 Werner Koch <wk@gnupg.org> - - * apdu.c (osc_get_status): Fixed type in function name. Noted by - Axel Thimm. Yes, I didn't tested it with OpenSC :-(. - -2004-04-28 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (do_setattr): Sync FORCE_CHV1. - -2004-04-27 Werner Koch <wk@gnupg.org> - - * app-common.h: Do not include ksba.h for gnupg 1. - -2004-04-26 Werner Koch <wk@gnupg.org> - - * app-common.h: New members FNC.DEINIT and APP_LOCAL. - * app.c (release_application): Call new deconstructor. - * app-openpgp.c (do_deinit): New. - (get_cached_data, flush_cache_item, flush_cache_after_error) - (flush_cache): New. - (get_one_do): Replaced arg SLOT by APP. Make used of cached data. - (verify_chv2, verify_chv3): Flush some cache item after error. - (do_change_pin): Ditto. - (do_sign): Ditto. - (do_setattr): Flush cache item. - (do_genkey): Flush the entire cache. - (compare_fingerprint): Use cached data. - - * scdaemon.c (main): Do the last change the usual way. This is so - that we can easily test for versioned config files above. - -2004-04-26 Marcus Brinkmann <marcus@g10code.de> - - * scdaemon.c (main): For now, always print default filename for - --gpgconf-list, and never /dev/null. - -2004-04-21 Werner Koch <wk@gnupg.org> - - * command.c (scd_update_reader_status_file): Send a signal back to - the client. - (option_handler): Parse the new event-signal option. - - * scdaemon.c (handle_signal): Do not use SIGUSR{1,2} anymore for - changing the verbosity. - -2004-04-20 Werner Koch <wk@gnupg.org> - - * command.c (scd_update_reader_status_file): Write status files. - - * app-help.c (app_help_read_length_of_cert): Fixed calculation of - R_CERTOFF. - - * pcsc-wrapper.c: New. - * Makefile.am (pkglib_PROGRAMS): Install it here. - * apdu.c (writen, readn): New. - (open_pcsc_reader, pcsc_send_apdu, close_pcsc_reader): Use the - pcsc-wrapper if we are using Pth. - (apdu_send_le): Reinitialize RESULTLEN. Handle SW_EOF_REACHED - like SW_SUCCESS. - -2004-04-19 Werner Koch <wk@gnupg.org> - - * ccid-driver.c (parse_ccid_descriptor): Store some of the reader - features away. New arg HANDLE - (read_device_info): New arg HANDLE. Changed caller. - (bulk_in): Handle time extension requests. - (ccid_get_atr): Setup parameters and the IFSD. - (compute_edc): New. Factored out code. - (ccid_transceive): Use default NADs when required. - -2004-04-14 Werner Koch <wk@gnupg.org> - - * scdaemon.h (server_control_s): Add member READER_SLOT. - * scdaemon.c (scd_init_default_ctrl): Initialize READER_SLOT to -1. - * command.c (open_card): Reuse an open slot. - (reset_notify): Just reset the slot if supported by the reader. - (do_reset): Factored code from above out. - (scd_command_handler): Use it for cleanup. - - * apdu.h: New pseudo stati SW_HOST_NOT_SUPPORTED, - SW_HOST_LOCKING_FAILED and SW_HOST_BUSY. - * iso7816.c (map_sw): Map it. - - * ccid-driver.c (ccid_slot_status): Add arg STATUSBITS. - * apdu.c (apdu_get_status): New. - (ct_get_status, pcsc_get_status, ocsc_get_status): New stubs. - (get_status_ccid): New. - (apdu_reset): New. - (reset_ct_reader, reset_pcsc_reader, reset_osc_reader): New stubs. - (reset_ccid_reader): New. - (apdu_enum_reader): New. - - * apdu.c (lock_slot, trylock_slot, unlock_slot): New helpers. - (new_reader_slot) [USE_GNU_PTH]: Init mutex. - (apdu_reset, apdu_get_status, apdu_send_le): Run functions - in locked mode. - - * command.c (scd_update_reader_status_file): New. - * scdaemon.c (handle_tick): Call it. - -2004-04-13 Werner Koch <wk@gnupg.org> - - * scdaemon.c: Convert to a Pth application. - (handle_signal, ticker_thread, handle_tick): New. - (main): Fire up the ticker thread in server mode. - -2004-03-23 Werner Koch <wk@gnupg.org> - - * scdaemon.c (main) <gpgconf_list>: Fixed output for pcsc_driver. - -2004-03-17 Werner Koch <wk@gnupg.org> - - * tlv.c (parse_ber_header): Do not check for tag overflow - it - does not make sense. Simplified the check for length overflow. - - * scdaemon.c (main) <gpgconf>: Fixed default value quoting. - -2004-03-16 Werner Koch <wk@gnupg.org> - - * app-dinsig.c: Implemented. Based on app-nks.c and card-dinsig.c - * app-nks.c (get_length_of_cert): Removed. - * app-help.c: New. - (app_help_read_length_of_cert): New. Code taken from above. New - optional arg R_CERTOFF. - - * card-dinsig.c: Removed. - * card.c (card_get_serial_and_stamp): Do not bind to the old and - never finsiged card-dinsig.c. - - * iso7816.c (iso7816_read_binary): Allow for an NMAX > 254. - -2004-03-11 Werner Koch <wk@gnupg.org> - - * scdaemon.h (out_of_core): Removed. Replaced callers by standard - gpg_error function. - - * apdu.c, iso7816.c, ccid-driver.c [GNUPG_SCD_MAIN_HEADER]: Allow - to include a header defined by the compiler. This helps us to - reuse the source in other software. - -2004-03-10 Werner Koch <wk@gnupg.org> - - * iso7816.c (iso7816_read_record): New arg SHORT_EF. Changed all - callers. - -2004-02-18 Werner Koch <wk@gnupg.org> - - * sc-investigate.c (main): Setup the used character set. - * scdaemon.c (main): Ditto. - - * scdaemon.c (set_debug): New. Add option --debug-level. - (main): Add option --gpgconf-list. - -2004-02-12 Werner Koch <wk@gnupg.org> - - * Makefile.am: Include cmacros.am for common flags. - -2004-01-29 Werner Koch <wk@gnupg.org> - - * command.c (reset_notify): Release the application context and - close the reader. - -2004-01-28 Werner Koch <wk@gnupg.org> - - * iso7816.c (iso7816_manage_security_env): New. - (iso7816_decipher): Add PADIND argument. - -2004-01-27 Werner Koch <wk@gnupg.org> - - * command.c (cmd_readcert, cmd_readkey): Work on a copy of LINE. - - * app-common.h (app_ctx_s): Added readcert field. - * app.c (app_readcert): New. - * tlv.c (parse_ber_header): Added; taken from libksba. - -2004-01-26 Werner Koch <wk@gnupg.org> - - * card.c (map_sc_err): Use SCD as the error source. - - * command.c (open_card): ADD arg NAME to allow requesting a - specific application. Changed all callers. - (cmd_serialno): Allow optional argument to select the desired - application. - - * app-nks.c: New. - - * scdaemon.h (opt): Add READER_PORT. - * scdaemon.c (main): Set it here. - * app.c (app_set_default_reader_port): Removed. - (select_application): Add NAME arg and figure out a - default serial number from the GDO. Add SLOT arg and remove all - reader management. - (release_application): New. - (app_write_learn_status): Output an APPTYPE status line. - * command.c (open_card): Adapt for select_application change. - * app-openpgp.c (app_select_openpgp): Removed SN and SNLEN args - and set it directly. Changed all callers. - -2004-01-25 Werner Koch <wk@gnupg.org> - - * iso7816.c (iso7816_select_application): P1 kludge for OpenPGP - card. - * app-openpgp.c (find_tlv): Factor out this function to .. - * tlv.c, tlv.h: .. new. - - * scdaemon.h: Introduced app_t and ctrl_t as the new types for APP - and CTRL. - -2004-01-21 Werner Koch <wk@gnupg.org> - - * apdu.c (apdu_send_le): Treat SW_EOF_REACHED as a warning. - -2004-01-20 Werner Koch <wk@gnupg.org> - - * iso7816.c (iso7816_read_binary): New. - (iso7816_select_file): New. - (iso7816_list_directory): New. - - * sc-investigate.c: Add option -i. - (select_app, read_line, interactive_shell): New. - -2004-01-16 Werner Koch <wk@gnupg.org> - - * apdu.h: Add SW_FILE_NOT_FOUND. - * iso7816.c (map_sw): Map it to GPG_ERR_ENOENT. - * iso7816.c (iso7816_select_file): New. - - * app-dinsig.c: New file w/o any real code yet. - * Makefile.am (scdaemon_SOURCES,sc_investigate_SOURCES): Add file. - - * sc-investigate.c: Add option --disable-ccid. - -2003-12-19 Werner Koch <wk@gnupg.org> - - * apdu.c (apdu_send_le): Send a get_response with the indicated - length and not the 64 bytes we used for testing. - - * app-openpgp.c (verify_chv2, verify_chv3, do_sign): Check the - minimum length of the passphrase, so that we don't need to - decrement the retry counter. - -2003-12-17 Werner Koch <wk@gnupg.org> - - * card-p15.c (p15_enum_keypairs): Replaced KRC by RC. - * card-dinsig.c (dinsig_enum_keypairs): Ditto. - -2003-12-16 Werner Koch <wk@gnupg.org> - - * scdaemon.c (main): Set the prefixes for assuan logging. - -2003-11-17 Werner Koch <wk@gnupg.org> - - * scdaemon.c, scdaemon.h: New options --allow-admin and --deny-admin. - * app-openpgp.c (verify_chv3): Check it here. - -2003-11-12 Werner Koch <wk@gnupg.org> - - Adjusted for API changes in Libksba. - -2003-10-30 Werner Koch <wk@gnupg.org> - - * apdu.c (close_ct_reader, close_pcsc_reader): Implemented. - (get_ccid_error_string): New. Not very useful messages, though. - -2003-10-25 Werner Koch <wk@gnupg.org> - - * ccid-driver.c (ccid_open_reader): Return an error if no USB - devices are found. - - * command.c (cmd_genkey, cmd_passwd): Fixed faulty use of - !spacep(). - - * apdu.c (apdu_open_reader): Hacks for PC/SC under Windows. - -2003-10-20 Werner Koch <wk@gnupg.org> - - * command.c (cmd_checkpin): New. - (register_commands): Add command CHECKPIN. - * app.c (app_check_pin): New. - * app-openpgp.c (check_against_given_fingerprint): New. Factored - out that code elsewhere. - (do_check_pin): New. - -2003-10-10 Werner Koch <wk@gnupg.org> - - * ccid-driver.c (ccid_close_reader): New. - - * apdu.c (close_ccid_reader, close_ct_reader, close_csc_reader) - (close_osc_reader, apdu_close_reader): New. Not all are properly - implemented yet. - -2003-10-09 Werner Koch <wk@gnupg.org> - - * ccid-driver.c (ccid_transceive): Add T=1 chaining for sending. - -2003-10-08 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (do_getattr): Support SERIALNO and AID. - -2003-10-01 Werner Koch <wk@gnupg.org> - - * ccid-driver.c: Detect GnuPG 1.3 and include appropriate files. - * apdu.c: Ditto. - * app-openpgp.c: Ditto. - * iso7816.c: Ditto. - (generate_keypair): Renamed to .. - (do_generate_keypair): .. this. - * app-common.h [GNUPG_MAJOR_VERSION]: New. - * iso7816.h [GNUPG_MAJOR_VERSION]: Include cardglue.h - -2003-09-30 Werner Koch <wk@gnupg.org> - - * command.c (cmd_getattr): New command GETATTR. - * app.c (app_setattr): New. - (do_getattr): New. - (do_learn_status): Reimplemented in terms of do_getattr. - - * app-openpgp.c (do_change_pin): Make sure CVH1 and CHV2 are - always synced. - (verify_chv2, verify_chv3): New. Factored out common code. - (do_setattr, do_sign, do_auth, do_decipher): Change the names of - the prompts to match that we have only 2 different PINs. - (app_select_openpgp): Check whether the card enforced CHV1. - (convert_sig_counter_value): New. Factor out code from - get_sig_counter. - -2003-09-28 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (dump_all_do): Use gpg_err_code and not gpg_error. - -2003-09-19 Werner Koch <wk@gnupg.org> - - * ccid-driver.c (parse_ccid_descriptor): New. - (read_device_info): New. - (ccid_open_reader): Check that the device has all required features. - -2003-09-06 Werner Koch <wk@gnupg.org> - - * scdaemon.c (main): --pcsc-driver again defaults to pcsclite. - David Corcoran was so kind to remove the GPL incompatible - advertisng clause from pcsclite. - * apdu.c (apdu_open_reader): Actually make pcsc-driver option work. - -2003-09-05 Werner Koch <wk@gnupg.org> - - * ccid-driver.c: More work, data can now actually be retrieved. - * ccid-driver.c, ccid-driver.h: Alternativley allow use under BSD - conditions. - -2003-09-02 Werner Koch <wk@gnupg.org> - - * scdaemon.c, scdaemon.h: New option --pcsc-ccid. - * ccid-driver.c, ccid-driver.h: New but far from being useful. - * Makefile.am: Add above. - * apdu.c: Add support for that ccid driver. - -2003-08-26 Timo Schulz <twoaday@freakmail.de> - - * apdu.c (new_reader_slot): Only set 'is_osc' when OpenSC - is used. - -2003-08-25 Werner Koch <wk@gnupg.org> - - * command.c (cmd_setattr): Use a copy of LINE. - (cmd_genkey): Use a copy of KEYNO. - (cmd_passwd): Use a copy of CHVNOSTR. - (cmd_pksign, cmd_pkauth, cmd_pkdecrypt): s/strdup/xtrystrdup/. - -2003-08-19 Werner Koch <wk@gnupg.org> - - * scdaemon.c, scdaemon.h: New option --pcsc-driver. - * apdu.c (apdu_open_reader): Use that option here instead of a - hardcoded one. - -2003-08-18 Werner Koch <wk@gnupg.org> - - * Makefile.am: Add OPENSC_LIBS to all programs. - - * scdaemon.c, scdaemon.h: New option --disable-opensc. - * card.c (card_open): Implement it. - * apdu.c (open_osc_reader, osc_send_apdu): New. - (apdu_open_reader) [HAVE_OPENSC]: Use the opensc driver if not - disabled. - (error_string) [HAVE_OPENSC]: Use sc_strerror. - (send_apdu) [HAVE_OPENSC]: Call osc_apdu_send. - - * card-p15.c (p15_enum_keypairs, p15_prepare_key): Adjusted for - libgpg-error. - -2003-08-14 Timo Schulz <twoaday@freakmail.de> - - * apdu.c (ct_activate_card): Change the code a little to avoid - problems with other readers. - * Always use 'dynload.h' instead of 'dlfcn.h'. - -2003-08-05 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (dump_all_do): Don't analyze constructed DOs after - an error. - -2003-08-04 Werner Koch <wk@gnupg.org> - - * app.c (app_set_default_reader_port): New. - (select_application): Use it here. - * scdaemon.c (main): and here. - * sc-copykeys.c: --reader-port does now take a string. - * sc-investigate.c, scdaemon.c: Ditto. - * apdu.c (apdu_open_reader): Ditto. Load pcsclite if no ctapi - driver is configured. Always include code for ctapi. - (new_reader_slot): Don't test for already used ports and remove - port arg. - (open_pcsc_reader, pcsc_send_apdu, pcsc_error_string): New. - (apdu_send_le): Changed RC to long to cope with PC/SC. - - * scdaemon.c, scdaemon.h: New option --ctapi-driver. - * sc-investigate.c, sc-copykeys.c: Ditto. - -2003-07-31 Werner Koch <wk@gnupg.org> - - * Makefile.am (scdaemon_LDADD): Added INTLLIBS. - -2003-07-28 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (do_setattr): Change implementation. Allow all - useful DOs. - -2003-07-27 Werner Koch <wk@gnupg.org> - - Adjusted for gcry_mpi_print and gcry_mpi_scan API change. - -2003-07-24 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (do_learn_status): Print more status information. - (app_select_openpgp): Store the card version. - (store_fpr): Add argument card_version and fix DOs for old cards. - (app_openpgp_storekey): Likewise. - -2003-07-23 Werner Koch <wk@gnupg.org> - - * command.c (cmd_pkauth): New. - (cmd_setdata): Check whether data was given at all to avoid - passing 0 to malloc. - - * app.c (app_auth): New. - * app-openpgp.c (do_auth): New. - -2003-07-22 Werner Koch <wk@gnupg.org> - - * command.c (cmd_passwd): New. - * app.c (app_change_pin): New. - * app-openpgp.c (do_change_pin): New. - * iso7816.c (iso7816_reset_retry_counter): Implemented. - - * sc-investigate.c (main): New option --gen-random. - * iso7816.c (iso7816_get_challenge): Don't create APDUs with a - length larger than 255. - -2003-07-17 Werner Koch <wk@gnupg.org> - - * command.c (cmd_random): New command RANDOM. - - * iso7816.c (map_sw): New. Use it in this file to return - meaningful error messages. Changed all public fucntions to return - a gpg_error_t. - (iso7816_change_reference_data): New. - * apdu.c (apdu_open_reader): Use faked status words for soem - system errors. - -2003-07-16 Werner Koch <wk@gnupg.org> - - * apdu.c (apdu_send_simple): Use apdu_send_le so that we can - specify not to send Le as it should be. - -2003-07-15 Werner Koch <wk@gnupg.org> - - * Makefile.am: Add sc-copykeys program. - * sc-copykeys.c: New. - * app-openpgp.c (app_openpgp_storekey): New. - (app_openpgp_cardinfo): New. - (count_bits): New. - (store_fpr): And use it here to get the actual length in bit. - -2003-07-03 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (do_setattr): Add setting of the URL. - (app_select_openpgp): Dump card data only in very verbose mode. - (do_decipher): New. - -2003-07-02 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (get_sig_counter): New. - (do_sign): Print the signature counter and enable the PIN callback. - (do_genkey): Implement the PIN callback. - -2003-07-01 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (store_fpr): Fixed fingerprint calculation. - -2003-06-26 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (find_tlv): Fixed length header parsing. - - * app.c (app_genkey): New. - * command.c (cmd_genkey): New. - -2003-06-25 Werner Koch <wk@gnupg.org> - - * command.c (percent_plus_unescape): New. - (cmd_setattr): New. - -2003-06-24 Werner Koch <wk@gnupg.org> - - * command.c (send_status_info): New. - - * app-openpgp.c (app_select_openpgp): Replace SLOT arg by APP arg - and setup the function pointers in APP on success. Changed callers. - * app.c: New. - * app-common.h: New. - * scdaemon.h (APP): New type to handle applications. - (server_control_s): Add an APP context field. - - * command.c (cmd_serialno): Handle applications. - (cmd_pksign): Ditto. - (cmd_pkdecrypt): Ditto. - (reset_notify): Ditto. - (cmd_learn): For now return error for application contexts. - (cmd_readcert): Ditto. - (cmd_readkey): Ditto. - -2003-06-04 Werner Koch <wk@gnupg.org> - - * card.c (map_sc_err): Renamed gpg_make_err to gpg_err_make. - - Renamed error codes from INVALID to INV and removed _ERROR suffixes. - -2003-06-03 Werner Koch <wk@gnupg.org> - - Changed all error codes in all files to the new libgpg-error scheme. - - * scdaemon.h: Include gpg-error.h and errno.h - * card.c (map_sc_err): Use unknown for the error source. - * Makefile.am: Link with libgpg-error - -2003-05-14 Werner Koch <wk@gnupg.org> - - * atr.c, atr.h: New. - * sc-investigate.c: Dump the ATR in a human readable format. - -2003-05-08 Werner Koch <wk@gnupg.org> - - * scdaemon.h (DBG_CARD_IO_VALUE): New. - - * sc-investigate.c: New. - * scdaemon.c (main): Removed --print-atr option. - - * iso7816.c, iso7816.h, app-openpgp.c: New. - -2003-04-29 Werner Koch <wk@gnupg.org> - - * scdaemon.c: New options --print-atr and --reader-port - * apdu.c, apdu.h: New - - * card.c, card-p15.c, card-dinsig.c: Allow build without OpenSC. - - * Makefile.am (LDFLAGS): Removed. - - * command.c (register_commands): Adjusted for new Assuan semantics. - -2002-08-21 Werner Koch <wk@gnupg.org> - - * scdaemon.c (main): New option --daemon so that the program is - not accidently started in the background. - -2002-08-16 Werner Koch <wk@gnupg.org> - - * scdaemon.c: Include i18n.h. - - * card-common.h (struct p15_private_s): Forward declaration. Add - it to card_ctx_s. - * card.c (card_close): Make sure private data is released. - (card_enum_certs): New. - * card-p15.c (p15_release_private_data): New. - (init_private_data): New to work around an OpenSC weirdness. - (p15_enum_keypairs): Do an OpenSC get_objects only once. - (p15_enum_certs): New. - (card_p15_bind): Bind new function. - * command.c (cmd_learn): Return information about the certificates. - -2002-08-09 Werner Koch <wk@gnupg.org> - - * card.c (card_get_serial_and_stamp): Use the tokeinfo serial - number as a fallback. Add a special prefix for serial numbers. - -2002-07-30 Werner Koch <wk@gnupg.org> - - Changes to cope with OpenSC 0.7.0: - - * card.c: Removed the check for the packed opensc version. - Changed include file names of opensc. - (map_sc_err): Adjusted error codes for new opensc version. - * card-p15.c: Changed include filename of opensc. - * card-dinsig.c: Ditto. - - * card-p15.c (p15_decipher): Add flags argument to OpenSC call. - -2002-07-24 Werner Koch <wk@gnupg.org> - - * card.c (find_simple_tlv, find_iccsn): New. - (card_get_serial_and_stamp): Improved serial number parser. - -2002-06-27 Werner Koch <wk@gnupg.org> - - * scdaemon.c (main): Use GNUPG_DEFAULT_HOMEDIR constant. - -2002-06-15 Werner Koch <wk@gnupg.org> - - * card-dinsig.c: Documented some stuff from the DIN norm. - -2002-04-15 Werner Koch <wk@gnupg.org> - - * command.c (cmd_pksign, cmd_pkdecrypt): Use a copy of the key ID. - -2002-04-12 Werner Koch <wk@gnupg.org> - - * scdaemon.c: New option --debug-sc N. - * card.c (card_open): set it here. - - * card-p15.c (p15_prepare_key): Factored out common code from ... - (p15_sign, p15_decipher): here and made the decryption work the - regular way. - -2002-04-10 Werner Koch <wk@gnupg.org> - - * card.c (card_open): Return immediately when no reader is available. - -2002-03-27 Werner Koch <wk@gnupg.org> - - * card.c (card_open, card_close): Adjusted for changes in OpenSC. - -2002-03-10 Werner Koch <wk@gnupg.org> - - * card-p15.c, card-dinsig.c, card-common.h: New. - * card.c: Factored most code out to the new modules, so that we - can better support different types of card applications. - -2002-01-26 Werner Koch <wk@gnupg.org> - - * scdaemon.c scdaemon.h, command.c: New. Based on the code from - the gpg-agent. - - Copyright 2002 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. diff --git a/scd/Makefile.am b/scd/Makefile.am deleted file mode 100644 index c3c603d28..000000000 --- a/scd/Makefile.am +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (C) 2002, 2003 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -bin_PROGRAMS = scdaemon sc-investigate sc-copykeys -pkglib_PROGRAMS = pcsc-wrapper - -AM_CPPFLAGS = -I$(top_srcdir)/intl -I$(top_srcdir)/common - -include $(top_srcdir)/am/cmacros.am - -AM_CFLAGS = $(OPENSC_CFLAGS) $(LIBGCRYPT_CFLAGS) \ - $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) - - -card_apps = app-openpgp.c app-nks.c app-dinsig.c - -scdaemon_SOURCES = \ - scdaemon.c scdaemon.h \ - command.c card.c \ - card-common.h \ - card-p15.c \ - apdu.c apdu.h \ - ccid-driver.c ccid-driver.h \ - iso7816.c iso7816.h \ - tlv.c tlv.h \ - app.c app-common.h app-help.c $(card_apps) - - -scdaemon_LDADD = ../jnlib/libjnlib.a ../common/libcommon.a \ - $(OPENSC_LIBS) $(LIBGCRYPT_LIBS) $(PTH_LIBS) \ - $(KSBA_LIBS) $(LIBASSUAN_LIBS) \ - $(LIBUSB_LIBS) -lgpg-error @INTLLIBS@ -ldl - -sc_investigate_SOURCES = \ - sc-investigate.c scdaemon.h \ - apdu.c apdu.h \ - ccid-driver.c ccid-driver.h \ - iso7816.c iso7816.h \ - tlv.c tlv.h \ - atr.c atr.h \ - app.c app-common.h app-help.c $(card_apps) - -sc_investigate_LDADD = \ - ../jnlib/libjnlib.a ../common/libcommon.a \ - $(OPENSC_LIBS) $(LIBGCRYPT_LIBS) $(PTH_LIBS) \ - $(KSBA_LIBS) $(LIBUSB_LIBS) \ - @INTLLIBS@ -lgpg-error -ldl - - -sc_copykeys_SOURCES = \ - sc-copykeys.c scdaemon.h \ - apdu.c apdu.h \ - ccid-driver.c ccid-driver.h \ - iso7816.c iso7816.h \ - tlv.c tlv.h \ - atr.c atr.h \ - app.c app-common.h app-help.c $(card_apps) - -sc_copykeys_LDADD = \ - ../jnlib/libjnlib.a ../common/libcommon.a \ - ../common/libsimple-pwquery.a \ - $(OPENSC_LIBS) $(LIBGCRYPT_LIBS) $(PTH_LIBS) \ - $(KSBA_LIBS) $(LIBUSB_LIBS) \ - -lgpg-error @INTLLIBS@ -ldl - -pcsc_wrapper_SOURCES = pcsc-wrapper.c -pcsc_wrapper_LDADD = -ldl -pcsc_wrapper_CFLAGS = \ No newline at end of file diff --git a/scd/apdu.c b/scd/apdu.c deleted file mode 100644 index 9742be760..000000000 --- a/scd/apdu.c +++ /dev/null @@ -1,1981 +0,0 @@ -/* apdu.c - ISO 7816 APDU functions and low level I/O - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#ifdef USE_GNU_PTH -# include <pth.h> -# include <unistd.h> -# include <fcntl.h> -#endif -#ifdef HAVE_OPENSC -# include <opensc/opensc.h> -#endif - -#if defined(GNUPG_SCD_MAIN_HEADER) -#include GNUPG_SCD_MAIN_HEADER -#elif GNUPG_MAJOR_VERSION == 1 -/* This is used with GnuPG version < 1.9. The code has been source - copied from the current GnuPG >= 1.9 and is maintained over - there. */ -#include "options.h" -#include "errors.h" -#include "memory.h" -#include "util.h" -#include "i18n.h" -#include "cardglue.h" -#else /* GNUPG_MAJOR_VERSION != 1 */ -#include "scdaemon.h" -#endif /* GNUPG_MAJOR_VERSION != 1 */ - -#include "apdu.h" -#include "dynload.h" -#include "ccid-driver.h" - -#ifdef USE_GNU_PTH -#define NEED_PCSC_WRAPPER 1 -#endif - - -#define MAX_READER 4 /* Number of readers we support concurrently. */ -#define CARD_CONNECT_TIMEOUT 1 /* Number of seconds to wait for - insertion of the card (1 = don't wait). */ - - -#ifdef _WIN32 -#define DLSTDCALL __stdcall -#else -#define DLSTDCALL -#endif - -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - - -/* A structure to collect information pertaining to one reader - slot. */ -struct reader_table_s { - int used; /* True if slot is used. */ - unsigned short port; /* Port number: 0 = unused, 1 - dev/tty */ - int is_ccid; /* Uses the internal CCID driver. */ - struct { - ccid_driver_t handle; - } ccid; - int is_ctapi; /* This is a ctAPI driver. */ - struct { - unsigned long context; - unsigned long card; - unsigned long protocol; -#ifdef NEED_PCSC_WRAPPER - int req_fd; - int rsp_fd; - pid_t pid; -#endif /*NEED_PCSC_WRAPPER*/ - } pcsc; -#ifdef HAVE_OPENSC - int is_osc; /* We are using the OpenSC driver layer. */ - struct { - struct sc_context *ctx; - struct sc_card *scard; - } osc; -#endif /*HAVE_OPENSC*/ - int status; - unsigned char atr[33]; - size_t atrlen; - unsigned int change_counter; -#ifdef USE_GNU_PTH - int lock_initialized; - pth_mutex_t lock; -#endif -}; -typedef struct reader_table_s *reader_table_t; - -/* A global table to keep track of active readers. */ -static struct reader_table_s reader_table[MAX_READER]; - - -/* ct API function pointer. */ -static char (* DLSTDCALL CT_init) (unsigned short ctn, unsigned short Pn); -static char (* DLSTDCALL CT_data) (unsigned short ctn, unsigned char *dad, - unsigned char *sad, unsigned short lc, - unsigned char *cmd, unsigned short *lr, - unsigned char *rsp); -static char (* DLSTDCALL CT_close) (unsigned short ctn); - -/* PC/SC constants and function pointer. */ -#define PCSC_SCOPE_USER 0 -#define PCSC_SCOPE_TERMINAL 1 -#define PCSC_SCOPE_SYSTEM 2 -#define PCSC_SCOPE_GLOBAL 3 - -#define PCSC_PROTOCOL_T0 1 -#define PCSC_PROTOCOL_T1 2 -#define PCSC_PROTOCOL_RAW 4 - -#define PCSC_SHARE_EXCLUSIVE 1 -#define PCSC_SHARE_SHARED 2 -#define PCSC_SHARE_DIRECT 3 - -#define PCSC_LEAVE_CARD 0 -#define PCSC_RESET_CARD 1 -#define PCSC_UNPOWER_CARD 2 -#define PCSC_EJECT_CARD 3 - -struct pcsc_io_request_s { - unsigned long protocol; - unsigned long pci_len; -}; - -typedef struct pcsc_io_request_s *pcsc_io_request_t; - -long (* DLSTDCALL pcsc_establish_context) (unsigned long scope, - const void *reserved1, - const void *reserved2, - unsigned long *r_context); -long (* DLSTDCALL pcsc_release_context) (unsigned long context); -long (* DLSTDCALL pcsc_list_readers) (unsigned long context, - const char *groups, - char *readers, unsigned long*readerslen); -long (* DLSTDCALL pcsc_connect) (unsigned long context, - const char *reader, - unsigned long share_mode, - unsigned long preferred_protocols, - unsigned long *r_card, - unsigned long *r_active_protocol); -long (* DLSTDCALL pcsc_disconnect) (unsigned long card, - unsigned long disposition); -long (* DLSTDCALL pcsc_status) (unsigned long card, - char *reader, unsigned long *readerlen, - unsigned long *r_state, - unsigned long *r_protocol, - unsigned char *atr, unsigned long *atrlen); -long (* DLSTDCALL pcsc_begin_transaction) (unsigned long card); -long (* DLSTDCALL pcsc_end_transaction) (unsigned long card); -long (* DLSTDCALL pcsc_transmit) (unsigned long card, - const pcsc_io_request_t send_pci, - const unsigned char *send_buffer, - unsigned long send_len, - pcsc_io_request_t recv_pci, - unsigned char *recv_buffer, - unsigned long *recv_len); -long (* DLSTDCALL pcsc_set_timeout) (unsigned long context, - unsigned long timeout); - - - - - -/* - Helper - */ - - -/* Find an unused reader slot for PORTSTR and put it into the reader - table. Return -1 on error or the index into the reader table. */ -static int -new_reader_slot (void) -{ - int i, reader = -1; - - for (i=0; i < MAX_READER; i++) - { - if (!reader_table[i].used && reader == -1) - reader = i; - } - if (reader == -1) - { - log_error ("new_reader_slot: out of slots\n"); - return -1; - } -#ifdef USE_GNU_PTH - if (!reader_table[reader].lock_initialized) - { - if (!pth_mutex_init (&reader_table[reader].lock)) - { - log_error ("error initializing mutex: %s\n", strerror (errno)); - return -1; - } - reader_table[reader].lock_initialized = 1; - } -#endif /*USE_GNU_PTH*/ - reader_table[reader].used = 1; - reader_table[reader].is_ccid = 0; - reader_table[reader].is_ctapi = 0; -#ifdef HAVE_OPENSC - reader_table[reader].is_osc = 0; -#endif -#ifdef NEED_PCSC_WRAPPER - reader_table[reader].pcsc.req_fd = -1; - reader_table[reader].pcsc.rsp_fd = -1; - reader_table[reader].pcsc.pid = (pid_t)(-1); -#endif - return reader; -} - - -static void -dump_reader_status (int reader) -{ - if (reader_table[reader].is_ccid) - log_info ("reader slot %d: using ccid driver\n", reader); - else if (reader_table[reader].is_ctapi) - { - log_info ("reader slot %d: %s\n", reader, - reader_table[reader].status == 1? "Processor ICC present" : - reader_table[reader].status == 0? "Memory ICC present" : - "ICC not present" ); - } - else - { - log_info ("reader slot %d: active protocol:", reader); - if ((reader_table[reader].pcsc.protocol & PCSC_PROTOCOL_T0)) - log_printf (" T0"); - else if ((reader_table[reader].pcsc.protocol & PCSC_PROTOCOL_T1)) - log_printf (" T1"); - else if ((reader_table[reader].pcsc.protocol & PCSC_PROTOCOL_RAW)) - log_printf (" raw"); - log_printf ("\n"); - } - - if (reader_table[reader].status != -1) - { - log_info ("reader %d: ATR=", reader); - log_printhex ("", reader_table[reader].atr, - reader_table[reader].atrlen); - } -} - - - -/* - ct API Interface - */ - -static const char * -ct_error_string (long err) -{ - switch (err) - { - case 0: return "okay"; - case -1: return "invalid data"; - case -8: return "ct error"; - case -10: return "transmission error"; - case -11: return "memory allocation error"; - case -128: return "HTSI error"; - default: return "unknown CT-API error"; - } -} - -/* Wait for the card in READER and activate it. Return -1 on error or - 0 on success. */ -static int -ct_activate_card (int reader) -{ - int rc, count; - - for (count = 0; count < CARD_CONNECT_TIMEOUT; count++) - { - unsigned char dad[1], sad[1], cmd[11], buf[256]; - unsigned short buflen; - - if (count) - ; /* FIXME: we should use a more reliable timer than sleep. */ - - /* Check whether card has been inserted. */ - dad[0] = 1; /* Destination address: CT. */ - sad[0] = 2; /* Source address: Host. */ - - cmd[0] = 0x20; /* Class byte. */ - cmd[1] = 0x13; /* Request status. */ - cmd[2] = 0x00; /* From kernel. */ - cmd[3] = 0x80; /* Return card's DO. */ - cmd[4] = 0x00; - - buflen = DIM(buf); - - rc = CT_data (reader, dad, sad, 5, cmd, &buflen, buf); - if (rc || buflen < 2 || buf[buflen-2] != 0x90) - { - log_error ("ct_activate_card: can't get status of reader %d: %s\n", - reader, ct_error_string (rc)); - return -1; - } - - /* Connected, now activate the card. */ - dad[0] = 1; /* Destination address: CT. */ - sad[0] = 2; /* Source address: Host. */ - - cmd[0] = 0x20; /* Class byte. */ - cmd[1] = 0x12; /* Request ICC. */ - cmd[2] = 0x01; /* From first interface. */ - cmd[3] = 0x01; /* Return card's ATR. */ - cmd[4] = 0x00; - - buflen = DIM(buf); - - rc = CT_data (reader, dad, sad, 5, cmd, &buflen, buf); - if (rc || buflen < 2 || buf[buflen-2] != 0x90) - { - log_error ("ct_activate_card(%d): activation failed: %s\n", - reader, ct_error_string (rc)); - if (!rc) - log_printhex (" received data:", buf, buflen); - return -1; - } - - /* Store the type and the ATR. */ - if (buflen - 2 > DIM (reader_table[0].atr)) - { - log_error ("ct_activate_card(%d): ATR too long\n", reader); - return -1; - } - - reader_table[reader].status = buf[buflen - 1]; - memcpy (reader_table[reader].atr, buf, buflen - 2); - reader_table[reader].atrlen = buflen - 2; - return 0; - } - - log_info ("ct_activate_card(%d): timeout waiting for card\n", reader); - return -1; -} - - -/* Open a reader and return an internal handle for it. PORT is a - non-negative value with the port number of the reader. USB readers - do have port numbers starting at 32769. */ -static int -open_ct_reader (int port) -{ - int rc, reader; - - if (port < 0 || port > 0xffff) - { - log_error ("open_ct_reader: invalid port %d requested\n", port); - return -1; - } - reader = new_reader_slot (); - if (reader == -1) - return reader; - reader_table[reader].port = port; - - rc = CT_init (reader, (unsigned short)port); - if (rc) - { - log_error ("apdu_open_ct_reader failed on port %d: %s\n", - port, ct_error_string (rc)); - reader_table[reader].used = 0; - return -1; - } - - rc = ct_activate_card (reader); - if (rc) - { - reader_table[reader].used = 0; - return -1; - } - - reader_table[reader].is_ctapi = 1; - dump_reader_status (reader); - return reader; -} - -static int -close_ct_reader (int slot) -{ - CT_close (slot); - reader_table[slot].used = 0; - return 0; -} - -static int -reset_ct_reader (int slot) -{ - return SW_HOST_NOT_SUPPORTED; -} - - -static int -ct_get_status (int slot, unsigned int *status) -{ - return SW_HOST_NOT_SUPPORTED; -} - -/* Actually send the APDU of length APDULEN to SLOT and return a - maximum of *BUFLEN data in BUFFER, the actual retruned size will be - set to BUFLEN. Returns: CT API error code. */ -static int -ct_send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) -{ - int rc; - unsigned char dad[1], sad[1]; - unsigned short ctbuflen; - - dad[0] = 0; /* Destination address: Card. */ - sad[0] = 2; /* Source address: Host. */ - ctbuflen = *buflen; - if (DBG_CARD_IO) - log_printhex (" CT_data:", apdu, apdulen); - rc = CT_data (slot, dad, sad, apdulen, apdu, &ctbuflen, buffer); - *buflen = ctbuflen; - - /* FIXME: map the errorcodes to GNUPG ones, so that they can be - shared between CTAPI and PCSC. */ - return rc; -} - - - -#ifdef NEED_PCSC_WRAPPER -static int -writen (int fd, const void *buf, size_t nbytes) -{ - size_t nleft = nbytes; - int nwritten; - -/* log_printhex (" writen:", buf, nbytes); */ - - while (nleft > 0) - { -#ifdef USE_GNU_PTH - nwritten = pth_write (fd, buf, nleft); -#else - nwritten = write (fd, buf, nleft); -#endif - if (nwritten < 0 && errno == EINTR) - continue; - if (nwritten < 0) - return -1; - nleft -= nwritten; - buf = (const char*)buf + nwritten; - } - return 0; -} - -/* Read up to BUFLEN bytes from FD and return the number of bytes - actually read in NREAD. Returns -1 on error or 0 on success. */ -static int -readn (int fd, void *buf, size_t buflen, size_t *nread) -{ - size_t nleft = buflen; - int n; -/* void *orig_buf = buf; */ - - while (nleft > 0) - { -#ifdef USE_GNU_PTH - n = pth_read (fd, buf, nleft); -#else - n = read (fd, buf, nleft); -#endif - if (n < 0 && errno == EINTR) - continue; - if (n < 0) - return -1; /* read error. */ - if (!n) - break; /* EOF */ - nleft -= n; - buf = (char*)buf + n; - } - if (nread) - *nread = buflen - nleft; - -/* log_printhex (" readn:", orig_buf, *nread); */ - - return 0; -} -#endif /*NEED_PCSC_WRAPPER*/ - -static const char * -pcsc_error_string (long err) -{ - const char *s; - - if (!err) - return "okay"; - if ((err & 0x80100000) != 0x80100000) - return "invalid PC/SC error code"; - err &= 0xffff; - switch (err) - { - case 0x0002: s = "cancelled"; break; - case 0x000e: s = "can't dispose"; break; - case 0x0008: s = "insufficient buffer"; break; - case 0x0015: s = "invalid ATR"; break; - case 0x0003: s = "invalid handle"; break; - case 0x0004: s = "invalid parameter"; break; - case 0x0005: s = "invalid target"; break; - case 0x0011: s = "invalid value"; break; - case 0x0006: s = "no memory"; break; - case 0x0013: s = "comm error"; break; - case 0x0001: s = "internal error"; break; - case 0x0014: s = "unknown error"; break; - case 0x0007: s = "waited too long"; break; - case 0x0009: s = "unknown reader"; break; - case 0x000a: s = "timeout"; break; - case 0x000b: s = "sharing violation"; break; - case 0x000c: s = "no smartcard"; break; - case 0x000d: s = "unknown card"; break; - case 0x000f: s = "proto mismatch"; break; - case 0x0010: s = "not ready"; break; - case 0x0012: s = "system cancelled"; break; - case 0x0016: s = "not transacted"; break; - case 0x0017: s = "reader unavailable"; break; - case 0x0065: s = "unsupported card"; break; - case 0x0066: s = "unresponsive card"; break; - case 0x0067: s = "unpowered card"; break; - case 0x0068: s = "reset card"; break; - case 0x0069: s = "removed card"; break; - case 0x006a: s = "inserted card"; break; - case 0x001f: s = "unsupported feature"; break; - case 0x0019: s = "PCI too small"; break; - case 0x001a: s = "reader unsupported"; break; - case 0x001b: s = "duplicate reader"; break; - case 0x001c: s = "card unsupported"; break; - case 0x001d: s = "no service"; break; - case 0x001e: s = "service stopped"; break; - default: s = "unknown PC/SC error code"; break; - } - return s; -} - -/* - PC/SC Interface - */ - -static int -open_pcsc_reader (const char *portstr) -{ -#ifdef NEED_PCSC_WRAPPER -/* Open the PC/SC reader using the pcsc_wrapper program. This is - needed to cope with different thread models and other peculiarities - of libpcsclite. */ - int slot; - reader_table_t slotp; - int fd, rp[2], wp[2]; - int n, i; - pid_t pid; - size_t len; - unsigned char msgbuf[9]; - int err; - - slot = new_reader_slot (); - if (slot == -1) - return -1; - slotp = reader_table + slot; - - /* Fire up the pcsc wrapper. We don't use any fork/exec code from - the common directy but implement it direclty so that this file - may still be source copied. */ - - if (pipe (rp) == -1) - { - log_error ("error creating a pipe: %s\n", strerror (errno)); - slotp->used = 0; - return -1; - } - if (pipe (wp) == -1) - { - log_error ("error creating a pipe: %s\n", strerror (errno)); - close (rp[0]); - close (rp[1]); - slotp->used = 0; - return -1; - } - - pid = fork (); - if (pid == -1) - { - log_error ("error forking process: %s\n", strerror (errno)); - close (rp[0]); - close (rp[1]); - close (wp[0]); - close (wp[1]); - slotp->used = 0; - return -1; - } - slotp->pcsc.pid = pid; - - if (!pid) - { /* - === Child === - */ - - /* Double fork. */ - pid = fork (); - if (pid == -1) - _exit (31); - if (pid) - _exit (0); /* Immediate exit this parent, so that the child - gets cleaned up by the init process. */ - - /* Connect our pipes. */ - if (wp[0] != 0 && dup2 (wp[0], 0) == -1) - log_fatal ("dup2 stdin failed: %s\n", strerror (errno)); - if (rp[1] != 1 && dup2 (rp[1], 1) == -1) - log_fatal ("dup2 stdout failed: %s\n", strerror (errno)); - - /* Send stderr to the bit bucket. */ - fd = open ("/dev/null", O_WRONLY); - if (fd == -1) - log_fatal ("can't open `/dev/null': %s", strerror (errno)); - if (fd != 2 && dup2 (fd, 2) == -1) - log_fatal ("dup2 stderr failed: %s\n", strerror (errno)); - - /* Close all other files. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; - for (i=3; i < n; i++) - close(i); - errno = 0; - - execl (GNUPG_LIBDIR "/pcsc-wrapper", - "pcsc-wrapper", - "--", - "1", /* API version */ - opt.pcsc_driver, /* Name of the PC/SC library. */ - NULL); - _exit (31); - } - - /* - === Parent === - */ - close (wp[0]); - close (rp[1]); - slotp->pcsc.req_fd = wp[1]; - slotp->pcsc.rsp_fd = rp[0]; - - /* Wait for the intermediate child to terminate. */ - while ( (i=pth_waitpid (pid, NULL, 0)) == -1 && errno == EINTR) - ; - - /* Now send the open request. */ - msgbuf[0] = 0x01; /* OPEN command. */ - len = portstr? strlen (portstr):0; - msgbuf[1] = (len >> 24); - msgbuf[2] = (len >> 16); - msgbuf[3] = (len >> 8); - msgbuf[4] = (len ); - if ( writen (slotp->pcsc.req_fd, msgbuf, 5) - || (portstr && writen (slotp->pcsc.req_fd, portstr, len))) - { - log_error ("error sending PC/SC OPEN request: %s\n", - strerror (errno)); - goto command_failed; - } - /* Read the response. */ - if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9) - { - log_error ("error receiving PC/SC OPEN response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; - if (msgbuf[0] != 0x81 || len < 4) - { - log_error ("invalid response header from PC/SC received\n"); - goto command_failed; - } - len -= 4; /* Already read the error code. */ - if (len > DIM (slotp->atr)) - { - log_error ("PC/SC returned a too large ATR (len=%x)\n", len); - goto command_failed; - } - err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; - if (err) - { - log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err)); - goto command_failed; - } - n = len; - if ((i=readn (slotp->pcsc.rsp_fd, slotp->atr, n, &len)) || len != n) - { - log_error ("error receiving PC/SC OPEN response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - slotp->atrlen = len; - - dump_reader_status (slot); - return slot; - - command_failed: - close (slotp->pcsc.req_fd); - close (slotp->pcsc.rsp_fd); - slotp->pcsc.req_fd = -1; - slotp->pcsc.rsp_fd = -1; - kill (slotp->pcsc.pid, SIGTERM); - slotp->pcsc.pid = (pid_t)(-1); - slotp->used = 0; - return -1; -#else /*!NEED_PCSC_WRAPPER */ - long err; - int slot; - char *list = NULL; - unsigned long nreader, listlen, atrlen; - char *p; - unsigned long card_state, card_protocol; - - slot = new_reader_slot (); - if (slot == -1) - return -1; - - err = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL, - &reader_table[slot].pcsc.context); - if (err) - { - log_error ("pcsc_establish_context failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - reader_table[slot].used = 0; - return -1; - } - - err = pcsc_list_readers (reader_table[slot].pcsc.context, - NULL, NULL, &nreader); - if (!err) - { - list = xtrymalloc (nreader+1); /* Better add 1 for safety reasons. */ - if (!list) - { - log_error ("error allocating memory for reader list\n"); - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - return -1; - } - err = pcsc_list_readers (reader_table[slot].pcsc.context, - NULL, list, &nreader); - } - if (err) - { - log_error ("pcsc_list_readers failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - xfree (list); - return -1; - } - - listlen = nreader; - p = list; - while (nreader) - { - if (!*p && !p[1]) - break; - log_info ("detected reader `%s'\n", p); - if (nreader < (strlen (p)+1)) - { - log_error ("invalid response from pcsc_list_readers\n"); - break; - } - nreader -= strlen (p)+1; - p += strlen (p) + 1; - } - - err = pcsc_connect (reader_table[slot].pcsc.context, - portstr? portstr : list, - PCSC_SHARE_EXCLUSIVE, - PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1, - &reader_table[slot].pcsc.card, - &reader_table[slot].pcsc.protocol); - if (err) - { - log_error ("pcsc_connect failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - xfree (list); - return -1; - } - - atrlen = 32; - /* (We need to pass a dummy buffer. We use LIST because it ought to - be large enough.) */ - err = pcsc_status (reader_table[slot].pcsc.card, - list, &listlen, - &card_state, &card_protocol, - reader_table[slot].atr, &atrlen); - xfree (list); - if (err) - { - log_error ("pcsc_status failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - return -1; - } - if (atrlen >= DIM (reader_table[0].atr)) - log_bug ("ATR returned by pcsc_status is too large\n"); - reader_table[slot].atrlen = atrlen; -/* log_debug ("state from pcsc_status: 0x%lx\n", card_state); */ -/* log_debug ("protocol from pcsc_status: 0x%lx\n", card_protocol); */ - - dump_reader_status (slot); - return slot; -#endif /*!NEED_PCSC_WRAPPER */ -} - - -static int -pcsc_get_status (int slot, unsigned int *status) -{ - return SW_HOST_NOT_SUPPORTED; -} - -/* Actually send the APDU of length APDULEN to SLOT and return a - maximum of *BUFLEN data in BUFFER, the actual returned size will be - set to BUFLEN. Returns: CT API error code. */ -static int -pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) -{ -#ifdef NEED_PCSC_WRAPPER - long err; - reader_table_t slotp; - size_t len, full_len; - int i, n; - unsigned char msgbuf[9]; - - if (DBG_CARD_IO) - log_printhex (" PCSC_data:", apdu, apdulen); - - slotp = reader_table + slot; - - if (slotp->pcsc.req_fd == -1 - || slotp->pcsc.rsp_fd == -1 - || slotp->pcsc.pid == (pid_t)(-1) ) - { - log_error ("pcsc_send_apdu: pcsc-wrapper not running\n"); - return -1; - } - - msgbuf[0] = 0x03; /* TRANSMIT command. */ - len = apdulen; - msgbuf[1] = (len >> 24); - msgbuf[2] = (len >> 16); - msgbuf[3] = (len >> 8); - msgbuf[4] = (len ); - if ( writen (slotp->pcsc.req_fd, msgbuf, 5) - || writen (slotp->pcsc.req_fd, apdu, len)) - { - log_error ("error sending PC/SC TRANSMIT request: %s\n", - strerror (errno)); - goto command_failed; - } - - /* Read the response. */ - if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9) - { - log_error ("error receiving PC/SC TRANSMIT response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; - if (msgbuf[0] != 0x81 || len < 4) - { - log_error ("invalid response header from PC/SC received\n"); - goto command_failed; - } - len -= 4; /* Already read the error code. */ - err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; - if (err) - { - log_error ("pcsc_transmit failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - return -1; - } - - full_len = len; - - n = *buflen < len ? *buflen : len; - if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len)) || len != n) - { - log_error ("error receiving PC/SC TRANSMIT response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - *buflen = n; - - full_len -= len; - if (full_len) - { - log_error ("pcsc_send_apdu: provided buffer too short - truncated\n"); - err = -1; - } - /* We need to read any rest of the response, to keep the - protocol runnng. */ - while (full_len) - { - unsigned char dummybuf[128]; - - n = full_len < DIM (dummybuf) ? full_len : DIM (dummybuf); - if ((i=readn (slotp->pcsc.rsp_fd, dummybuf, n, &len)) || len != n) - { - log_error ("error receiving PC/SC TRANSMIT response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - full_len -= n; - } - - return err; - - command_failed: - close (slotp->pcsc.req_fd); - close (slotp->pcsc.rsp_fd); - slotp->pcsc.req_fd = -1; - slotp->pcsc.rsp_fd = -1; - kill (slotp->pcsc.pid, SIGTERM); - slotp->pcsc.pid = (pid_t)(-1); - slotp->used = 0; - return -1; - -#else /*!NEED_PCSC_WRAPPER*/ - - long err; - struct pcsc_io_request_s send_pci; - unsigned long recv_len; - - if (DBG_CARD_IO) - log_printhex (" PCSC_data:", apdu, apdulen); - - if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_T1)) - send_pci.protocol = PCSC_PROTOCOL_T1; - else - send_pci.protocol = PCSC_PROTOCOL_T0; - send_pci.pci_len = sizeof send_pci; - recv_len = *buflen; - err = pcsc_transmit (reader_table[slot].pcsc.card, - &send_pci, apdu, apdulen, - NULL, buffer, &recv_len); - *buflen = recv_len; - if (err) - log_error ("pcsc_transmit failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - - return err? -1:0; /* FIXME: Return appropriate error code. */ -#endif /*!NEED_PCSC_WRAPPER*/ -} - - -static int -close_pcsc_reader (int slot) -{ -#ifdef NEED_PCSC_WRAPPER - long err; - reader_table_t slotp; - size_t len; - int i; - unsigned char msgbuf[9]; - - slotp = reader_table + slot; - - if (slotp->pcsc.req_fd == -1 - || slotp->pcsc.rsp_fd == -1 - || slotp->pcsc.pid == (pid_t)(-1) ) - { - log_error ("close_pcsc_reader: pcsc-wrapper not running\n"); - return 0; - } - - msgbuf[0] = 0x02; /* CLOSE command. */ - len = 0; - msgbuf[1] = (len >> 24); - msgbuf[2] = (len >> 16); - msgbuf[3] = (len >> 8); - msgbuf[4] = (len ); - if ( writen (slotp->pcsc.req_fd, msgbuf, 5) ) - { - log_error ("error sending PC/SC CLOSE request: %s\n", - strerror (errno)); - goto command_failed; - } - - /* Read the response. */ - if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9) - { - log_error ("error receiving PC/SC CLOSE response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; - if (msgbuf[0] != 0x81 || len < 4) - { - log_error ("invalid response header from PC/SC received\n"); - goto command_failed; - } - len -= 4; /* Already read the error code. */ - err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; - if (err) - log_error ("pcsc_close failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - - /* We will the wrapper in any case - errors are merely - informational. */ - - command_failed: - close (slotp->pcsc.req_fd); - close (slotp->pcsc.rsp_fd); - slotp->pcsc.req_fd = -1; - slotp->pcsc.rsp_fd = -1; - kill (slotp->pcsc.pid, SIGTERM); - slotp->pcsc.pid = (pid_t)(-1); - slotp->used = 0; - return 0; - -#else /*!NEED_PCSC_WRAPPER*/ - - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - return 0; -#endif /*!NEED_PCSC_WRAPPER*/ -} - -static int -reset_pcsc_reader (int slot) -{ - return SW_HOST_NOT_SUPPORTED; -} - - - - - -#ifdef HAVE_LIBUSB -/* - Internal CCID driver interface. - */ - -static const char * -get_ccid_error_string (long err) -{ - if (!err) - return "okay"; - else - return "unknown CCID error"; -} - -static int -open_ccid_reader (void) -{ - int err; - int slot; - reader_table_t slotp; - - slot = new_reader_slot (); - if (slot == -1) - return -1; - slotp = reader_table + slot; - - err = ccid_open_reader (&slotp->ccid.handle, 0); - if (err) - { - slotp->used = 0; - return -1; - } - - err = ccid_get_atr (slotp->ccid.handle, - slotp->atr, sizeof slotp->atr, &slotp->atrlen); - if (err) - { - slotp->used = 0; - return -1; - } - - slotp->is_ccid = 1; - - dump_reader_status (slot); - return slot; -} - -static int -close_ccid_reader (int slot) -{ - ccid_close_reader (reader_table[slot].ccid.handle); - reader_table[slot].used = 0; - return 0; -} - - -static int -reset_ccid_reader (int slot) -{ - int err; - reader_table_t slotp = reader_table + slot; - unsigned char atr[33]; - size_t atrlen; - - err = ccid_get_atr (slotp->ccid.handle, atr, sizeof atr, &atrlen); - if (err) - return -1; - /* If the reset was successful, update the ATR. */ - assert (sizeof slotp->atr >= sizeof atr); - slotp->atrlen = atrlen; - memcpy (slotp->atr, atr, atrlen); - dump_reader_status (slot); - return 0; -} - - -static int -get_status_ccid (int slot, unsigned int *status) -{ - int rc; - int bits; - - rc = ccid_slot_status (reader_table[slot].ccid.handle, &bits); - if (rc) - return -1; - - if (bits == 0) - *status = 1|2|4; - else if (bits == 1) - *status = 2; - else - *status = 0; - - return 0; -} - - -/* Actually send the APDU of length APDULEN to SLOT and return a - maximum of *BUFLEN data in BUFFER, the actual returned size will be - set to BUFLEN. Returns: Internal CCID driver error code. */ -static int -send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) -{ - long err; - size_t maxbuflen; - - if (DBG_CARD_IO) - log_printhex (" APDU_data:", apdu, apdulen); - - maxbuflen = *buflen; - err = ccid_transceive (reader_table[slot].ccid.handle, - apdu, apdulen, - buffer, maxbuflen, buflen); - if (err) - log_error ("ccid_transceive failed: (0x%lx)\n", - err); - - return err? -1:0; /* FIXME: Return appropriate error code. */ -} - -#endif /* HAVE_LIBUSB */ - - - -#ifdef HAVE_OPENSC -/* - OpenSC Interface. - - This uses the OpenSC primitives to send APDUs. We need this - because we can't mix OpenSC and native (i.e. ctAPI or PC/SC) - access to a card for resource conflict reasons. - */ - -static int -open_osc_reader (int portno) -{ - int err; - int slot; - reader_table_t slotp; - - slot = new_reader_slot (); - if (slot == -1) - return -1; - slotp = reader_table + slot; - - err = sc_establish_context (&slotp->osc.ctx, "scdaemon"); - if (err) - { - log_error ("failed to establish SC context: %s\n", sc_strerror (err)); - slotp->used = 0; - return -1; - } - if (portno < 0 || portno >= slotp->osc.ctx->reader_count) - { - log_error ("no card reader available\n"); - sc_release_context (slotp->osc.ctx); - slotp->used = 0; - return -1; - } - - /* Redirect to our logging facility. */ - slotp->osc.ctx->error_file = log_get_stream (); - slotp->osc.ctx->debug = opt.debug_sc; - slotp->osc.ctx->debug_file = log_get_stream (); - - if (sc_detect_card_presence (slotp->osc.ctx->reader[portno], 0) != 1) - { - log_error ("no card present\n"); - sc_release_context (slotp->osc.ctx); - slotp->used = 0; - return -1; - } - - /* We want the standard ISO driver. */ - /*FIXME: OpenSC does not like "iso7816", so we use EMV for now. */ - err = sc_set_card_driver(slotp->osc.ctx, "emv"); - if (err) - { - log_error ("failed to select the iso7816 driver: %s\n", - sc_strerror (err)); - sc_release_context (slotp->osc.ctx); - slotp->used = 0; - return -1; - } - - /* Now connect the card and hope that OpenSC won't try to be too - smart. */ - err = sc_connect_card (slotp->osc.ctx->reader[portno], 0, - &slotp->osc.scard); - if (err) - { - log_error ("failed to connect card in reader %d: %s\n", - portno, sc_strerror (err)); - sc_release_context (slotp->osc.ctx); - slotp->used = 0; - return -1; - } - if (opt.verbose) - log_info ("connected to card in opensc reader %d using driver `%s'\n", - portno, slotp->osc.scard->driver->name); - - err = sc_lock (slotp->osc.scard); - if (err) - { - log_error ("can't lock card in reader %d: %s\n", - portno, sc_strerror (err)); - sc_disconnect_card (slotp->osc.scard, 0); - sc_release_context (slotp->osc.ctx); - slotp->used = 0; - return -1; - } - - if (slotp->osc.scard->atr_len >= DIM (slotp->atr)) - log_bug ("ATR returned by opensc is too large\n"); - slotp->atrlen = slotp->osc.scard->atr_len; - memcpy (slotp->atr, slotp->osc.scard->atr, slotp->atrlen); - - slotp->is_osc = 1; - - dump_reader_status (slot); - return slot; -} - - -static int -close_osc_reader (int slot) -{ - /* FIXME: Implement. */ - reader_table[slot].used = 0; - return 0; -} - -static int -reset_osc_reader (int slot) -{ - return SW_HOST_NOT_SUPPORTED; -} - - -static int -osc_get_status (int slot, unsigned int *status) -{ - return SW_HOST_NOT_SUPPORTED; -} - - -/* Actually send the APDU of length APDULEN to SLOT and return a - maximum of *BUFLEN data in BUFFER, the actual returned size will be - set to BUFLEN. Returns: OpenSC error code. */ -static int -osc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) -{ - long err; - struct sc_apdu a; - unsigned char data[SC_MAX_APDU_BUFFER_SIZE]; - unsigned char result[SC_MAX_APDU_BUFFER_SIZE]; - - if (DBG_CARD_IO) - log_printhex (" APDU_data:", apdu, apdulen); - - if (apdulen < 4) - { - log_error ("osc_send_apdu: APDU is too short\n"); - return SC_ERROR_CMD_TOO_SHORT; - } - - memset(&a, 0, sizeof a); - a.cla = *apdu++; - a.ins = *apdu++; - a.p1 = *apdu++; - a.p2 = *apdu++; - apdulen -= 4; - - if (!apdulen) - a.cse = SC_APDU_CASE_1; - else if (apdulen == 1) - { - a.le = *apdu? *apdu : 256; - apdu++; apdulen--; - a.cse = SC_APDU_CASE_2_SHORT; - } - else - { - a.lc = *apdu++; apdulen--; - if (apdulen < a.lc) - { - log_error ("osc_send_apdu: APDU shorter than specified in Lc\n"); - return SC_ERROR_CMD_TOO_SHORT; - - } - memcpy(data, apdu, a.lc); - apdu += a.lc; apdulen -= a.lc; - - a.data = data; - a.datalen = a.lc; - - if (!apdulen) - a.cse = SC_APDU_CASE_3_SHORT; - else - { - a.le = *apdu? *apdu : 256; - apdu++; apdulen--; - if (apdulen) - { - log_error ("osc_send_apdu: APDU larger than specified\n"); - return SC_ERROR_CMD_TOO_LONG; - } - a.cse = SC_APDU_CASE_4_SHORT; - } - } - - a.resp = result; - a.resplen = DIM(result); - - err = sc_transmit_apdu (reader_table[slot].osc.scard, &a); - if (err) - { - log_error ("sc_apdu_transmit failed: %s\n", sc_strerror (err)); - return err; - } - - if (*buflen < 2 || a.resplen > *buflen - 2) - { - log_error ("osc_send_apdu: provided buffer too short to store result\n"); - return SC_ERROR_BUFFER_TOO_SMALL; - } - memcpy (buffer, a.resp, a.resplen); - buffer[a.resplen] = a.sw1; - buffer[a.resplen+1] = a.sw2; - *buflen = a.resplen + 2; - return 0; -} - -#endif /* HAVE_OPENSC */ - - - -/* - Driver Access - */ - - -static int -lock_slot (int slot) -{ -#ifdef USE_GNU_PTH - if (!pth_mutex_acquire (&reader_table[slot].lock, 0, NULL)) - { - log_error ("failed to acquire apdu lock: %s\n", strerror (errno)); - return SW_HOST_LOCKING_FAILED; - } -#endif /*USE_GNU_PTH*/ - return 0; -} - -static int -trylock_slot (int slot) -{ -#ifdef USE_GNU_PTH - if (!pth_mutex_acquire (&reader_table[slot].lock, TRUE, NULL)) - { - if (errno == EBUSY) - return SW_HOST_BUSY; - log_error ("failed to acquire apdu lock: %s\n", strerror (errno)); - return SW_HOST_LOCKING_FAILED; - } -#endif /*USE_GNU_PTH*/ - return 0; -} - -static void -unlock_slot (int slot) -{ -#ifdef USE_GNU_PTH - if (!pth_mutex_release (&reader_table[slot].lock)) - log_error ("failed to release apdu lock: %s\n", strerror (errno)); -#endif /*USE_GNU_PTH*/ -} - - -/* Open the reader and return an internal slot number or -1 on - error. If PORTSTR is NULL we default to a suitable port (for ctAPI: - the first USB reader. For PC/SC the first listed reader). If - OpenSC support is compiled in, we first try to use OpenSC. */ -int -apdu_open_reader (const char *portstr) -{ - static int pcsc_api_loaded, ct_api_loaded; - -#ifdef HAVE_LIBUSB - if (!opt.disable_ccid) - { - int slot; - - slot = open_ccid_reader (); - if (slot != -1) - return slot; /* got one */ - } -#endif /* HAVE_LIBUSB */ - -#ifdef HAVE_OPENSC - if (!opt.disable_opensc) - { - int port = portstr? atoi (portstr) : 0; - - return open_osc_reader (port); - } -#endif /* HAVE_OPENSC */ - - - if (opt.ctapi_driver && *opt.ctapi_driver) - { - int port = portstr? atoi (portstr) : 32768; - - if (!ct_api_loaded) - { - void *handle; - - handle = dlopen (opt.ctapi_driver, RTLD_LAZY); - if (!handle) - { - log_error ("apdu_open_reader: failed to open driver: %s\n", - dlerror ()); - return -1; - } - CT_init = dlsym (handle, "CT_init"); - CT_data = dlsym (handle, "CT_data"); - CT_close = dlsym (handle, "CT_close"); - if (!CT_init || !CT_data || !CT_close) - { - log_error ("apdu_open_reader: invalid CT-API driver\n"); - dlclose (handle); - return -1; - } - ct_api_loaded = 1; - } - return open_ct_reader (port); - } - - - /* No ctAPI configured, so lets try the PC/SC API */ - if (!pcsc_api_loaded) - { -#ifndef NEED_PCSC_WRAPPER - void *handle; - - handle = dlopen (opt.pcsc_driver, RTLD_LAZY); - if (!handle) - { - log_error ("apdu_open_reader: failed to open driver `%s': %s\n", - opt.pcsc_driver, dlerror ()); - return -1; - } - - pcsc_establish_context = dlsym (handle, "SCardEstablishContext"); - pcsc_release_context = dlsym (handle, "SCardReleaseContext"); - pcsc_list_readers = dlsym (handle, "SCardListReaders"); -#ifdef _WIN32 - if (!pcsc_list_readers) - pcsc_list_readers = dlsym (handle, "SCardListReadersA"); -#endif - pcsc_connect = dlsym (handle, "SCardConnect"); -#ifdef _WIN32 - if (!pcsc_connect) - pcsc_connect = dlsym (handle, "SCardConnectA"); -#endif - pcsc_disconnect = dlsym (handle, "SCardDisconnect"); - pcsc_status = dlsym (handle, "SCardStatus"); -#ifdef _WIN32 - if (!pcsc_status) - pcsc_status = dlsym (handle, "SCardStatusA"); -#endif - pcsc_begin_transaction = dlsym (handle, "SCardBeginTransaction"); - pcsc_end_transaction = dlsym (handle, "SCardEndTransaction"); - pcsc_transmit = dlsym (handle, "SCardTransmit"); - pcsc_set_timeout = dlsym (handle, "SCardSetTimeout"); - - if (!pcsc_establish_context - || !pcsc_release_context - || !pcsc_list_readers - || !pcsc_connect - || !pcsc_disconnect - || !pcsc_status - || !pcsc_begin_transaction - || !pcsc_end_transaction - || !pcsc_transmit - /* || !pcsc_set_timeout */) - { - /* Note that set_timeout is currently not used and also not - available under Windows. */ - log_error ("apdu_open_reader: invalid PC/SC driver " - "(%d%d%d%d%d%d%d%d%d%d)\n", - !!pcsc_establish_context, - !!pcsc_release_context, - !!pcsc_list_readers, - !!pcsc_connect, - !!pcsc_disconnect, - !!pcsc_status, - !!pcsc_begin_transaction, - !!pcsc_end_transaction, - !!pcsc_transmit, - !!pcsc_set_timeout ); - dlclose (handle); - return -1; - } -#endif /*!NEED_PCSC_WRAPPER*/ - pcsc_api_loaded = 1; - } - - return open_pcsc_reader (portstr); -} - - -int -apdu_close_reader (int slot) -{ - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; - if (reader_table[slot].is_ctapi) - return close_ct_reader (slot); -#ifdef HAVE_LIBUSB - else if (reader_table[slot].is_ccid) - return close_ccid_reader (slot); -#endif -#ifdef HAVE_OPENSC - else if (reader_table[slot].is_osc) - return close_osc_reader (slot); -#endif - else - return close_pcsc_reader (slot); -} - -/* Enumerate all readers and return information on whether this reader - is in use. The caller should start with SLOT set to 0 and - increment it with each call until an error is returned. */ -int -apdu_enum_reader (int slot, int *used) -{ - if (slot < 0 || slot >= MAX_READER) - return SW_HOST_NO_DRIVER; - *used = reader_table[slot].used; - return 0; -} - -/* Do a reset for the card in reader at SLOT. */ -int -apdu_reset (int slot) -{ - int sw; - - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; - - if ((sw = lock_slot (slot))) - return sw; - - if (reader_table[slot].is_ctapi) - sw = reset_ct_reader (slot); -#ifdef HAVE_LIBUSB - else if (reader_table[slot].is_ccid) - sw = reset_ccid_reader (slot); -#endif -#ifdef HAVE_OPENSC - else if (reader_table[slot].is_osc) - sw = reset_osc_reader (slot); -#endif - else - sw = reset_pcsc_reader (slot); - - unlock_slot (slot); - return sw; -} - - -unsigned char * -apdu_get_atr (int slot, size_t *atrlen) -{ - char *buf; - - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return NULL; - - buf = xtrymalloc (reader_table[slot].atrlen); - if (!buf) - return NULL; - memcpy (buf, reader_table[slot].atr, reader_table[slot].atrlen); - *atrlen = reader_table[slot].atrlen; - return buf; -} - - - -static const char * -error_string (int slot, long rc) -{ - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return "[invalid slot]"; - if (reader_table[slot].is_ctapi) - return ct_error_string (rc); -#ifdef HAVE_LIBUSB - else if (reader_table[slot].is_ccid) - return get_ccid_error_string (rc); -#endif -#ifdef HAVE_OPENSC - else if (reader_table[slot].is_osc) - return sc_strerror (rc); -#endif - else - return pcsc_error_string (rc); -} - - -/* Retrieve the status for SLOT. The function does obnly wait fot the - card to become available if HANG is set to true. On success the - bits in STATUS will be set to - - bit 0 = card present and usable - bit 1 = card present - bit 2 = card active - bit 3 = card access locked [not yet implemented] - - For must application, tetsing bit 0 is sufficient. - - CHANGED will receive the value of the counter tracking the number - of card insertions. This value may be used to detect a card - change. -*/ -int -apdu_get_status (int slot, int hang, - unsigned int *status, unsigned int *changed) -{ - int sw; - unsigned int s; - - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; - - if ((sw = hang? lock_slot (slot) : trylock_slot (slot))) - return sw; - - if (reader_table[slot].is_ctapi) - sw = ct_get_status (slot, &s); -#ifdef HAVE_LIBUSB - else if (reader_table[slot].is_ccid) - sw = get_status_ccid (slot, &s); -#endif -#ifdef HAVE_OPENSC - else if (reader_table[slot].is_osc) - sw = osc_get_status (slot, &s); -#endif - else - sw = pcsc_get_status (slot, &s); - - unlock_slot (slot); - - if (sw) - return sw; - - if (status) - *status = s; - if (changed) - *changed = reader_table[slot].change_counter; - return 0; -} - - -/* Dispatcher for the actual send_apdu function. Note, that this - function should be called in locked state. */ -static int -send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) -{ - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; - if (reader_table[slot].is_ctapi) - return ct_send_apdu (slot, apdu, apdulen, buffer, buflen); -#ifdef HAVE_LIBUSB - else if (reader_table[slot].is_ccid) - return send_apdu_ccid (slot, apdu, apdulen, buffer, buflen); -#endif -#ifdef HAVE_OPENSC - else if (reader_table[slot].is_osc) - return osc_send_apdu (slot, apdu, apdulen, buffer, buflen); -#endif - else - return pcsc_send_apdu (slot, apdu, apdulen, buffer, buflen); -} - -/* Send an APDU to the card in SLOT. The APDU is created from all - given parameters: CLASS, INS, P0, P1, LC, DATA, LE. A value of -1 - for LC won't sent this field and the data field; in this case DATA - must also be passed as NULL. The return value is the status word - or -1 for an invalid SLOT or other non card related error. If - RETBUF is not NULL, it will receive an allocated buffer with the - returned data. The length of that data will be put into - *RETBUFLEN. The caller is reponsible for releasing the buffer even - in case of errors. */ -int -apdu_send_le(int slot, int class, int ins, int p0, int p1, - int lc, const char *data, int le, - unsigned char **retbuf, size_t *retbuflen) -{ -#define RESULTLEN 256 - unsigned char result[RESULTLEN+10]; /* 10 extra in case of bugs in - the driver. */ - size_t resultlen; - unsigned char apdu[5+256+1]; - size_t apdulen; - int sw; - long rc; /* we need a long here due to PC/SC. */ - - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; - - if (DBG_CARD_IO) - log_debug ("send apdu: c=%02X i=%02X p0=%02X p1=%02X lc=%d le=%d\n", - class, ins, p0, p1, lc, le); - - if (lc != -1 && (lc > 255 || lc < 0)) - return SW_WRONG_LENGTH; - if (le != -1 && (le > 256 || le < 1)) - return SW_WRONG_LENGTH; - if ((!data && lc != -1) || (data && lc == -1)) - return SW_HOST_INV_VALUE; - - if ((sw = lock_slot (slot))) - return sw; - - apdulen = 0; - apdu[apdulen++] = class; - apdu[apdulen++] = ins; - apdu[apdulen++] = p0; - apdu[apdulen++] = p1; - if (lc != -1) - { - apdu[apdulen++] = lc; - memcpy (apdu+apdulen, data, lc); - apdulen += lc; - } - if (le != -1) - apdu[apdulen++] = le; /* Truncation is okay becuase 0 means 256. */ - assert (sizeof (apdu) >= apdulen); - /* As safeguard don't pass any garbage from the stack to the driver. */ - memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); - resultlen = RESULTLEN; - rc = send_apdu (slot, apdu, apdulen, result, &resultlen); - if (rc || resultlen < 2) - { - log_error ("apdu_send_simple(%d) failed: %s\n", - slot, error_string (slot, rc)); - unlock_slot (slot); - return SW_HOST_INCOMPLETE_CARD_RESPONSE; - } - sw = (result[resultlen-2] << 8) | result[resultlen-1]; - /* store away the returned data but strip the statusword. */ - resultlen -= 2; - if (DBG_CARD_IO) - { - log_debug (" response: sw=%04X datalen=%d\n", sw, resultlen); - if ( !retbuf && (sw == SW_SUCCESS || (sw & 0xff00) == SW_MORE_DATA)) - log_printhex (" dump: ", result, resultlen); - } - - if (sw == SW_SUCCESS || sw == SW_EOF_REACHED) - { - if (retbuf) - { - *retbuf = xtrymalloc (resultlen? resultlen : 1); - if (!*retbuf) - { - unlock_slot (slot); - return SW_HOST_OUT_OF_CORE; - } - *retbuflen = resultlen; - memcpy (*retbuf, result, resultlen); - } - } - else if ((sw & 0xff00) == SW_MORE_DATA) - { - unsigned char *p = NULL, *tmp; - size_t bufsize = 4096; - - /* It is likely that we need to return much more data, so we - start off with a large buffer. */ - if (retbuf) - { - *retbuf = p = xtrymalloc (bufsize); - if (!*retbuf) - { - unlock_slot (slot); - return SW_HOST_OUT_OF_CORE; - } - assert (resultlen < bufsize); - memcpy (p, result, resultlen); - p += resultlen; - } - - do - { - int len = (sw & 0x00ff); - - if (DBG_CARD_IO) - log_debug ("apdu_send_simple(%d): %d more bytes available\n", - slot, len); - apdulen = 0; - apdu[apdulen++] = class; - apdu[apdulen++] = 0xC0; - apdu[apdulen++] = 0; - apdu[apdulen++] = 0; - apdu[apdulen++] = len; - memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); - resultlen = RESULTLEN; - rc = send_apdu (slot, apdu, apdulen, result, &resultlen); - if (rc || resultlen < 2) - { - log_error ("apdu_send_simple(%d) for get response failed: %s\n", - slot, error_string (slot, rc)); - unlock_slot (slot); - return SW_HOST_INCOMPLETE_CARD_RESPONSE; - } - sw = (result[resultlen-2] << 8) | result[resultlen-1]; - resultlen -= 2; - if (DBG_CARD_IO) - { - log_debug (" more: sw=%04X datalen=%d\n", sw, resultlen); - if (!retbuf && (sw==SW_SUCCESS || (sw&0xff00)==SW_MORE_DATA)) - log_printhex (" dump: ", result, resultlen); - } - - if ((sw & 0xff00) == SW_MORE_DATA - || sw == SW_SUCCESS - || sw == SW_EOF_REACHED ) - { - if (retbuf && resultlen) - { - if (p - *retbuf + resultlen > bufsize) - { - bufsize += resultlen > 4096? resultlen: 4096; - tmp = xtryrealloc (*retbuf, bufsize); - if (!tmp) - { - unlock_slot (slot); - return SW_HOST_OUT_OF_CORE; - } - p = tmp + (p - *retbuf); - *retbuf = tmp; - } - memcpy (p, result, resultlen); - p += resultlen; - } - } - else - log_info ("apdu_send_simple(%d) " - "got unexpected status %04X from get response\n", - slot, sw); - } - while ((sw & 0xff00) == SW_MORE_DATA); - - if (retbuf) - { - *retbuflen = p - *retbuf; - tmp = xtryrealloc (*retbuf, *retbuflen); - if (tmp) - *retbuf = tmp; - } - } - - unlock_slot (slot); - - if (DBG_CARD_IO && retbuf && sw == SW_SUCCESS) - log_printhex (" dump: ", *retbuf, *retbuflen); - - return sw; -#undef RESULTLEN -} - -/* Send an APDU to the card in SLOT. The APDU is created from all - given parameters: CLASS, INS, P0, P1, LC, DATA. A value of -1 for - LC won't sent this field and the data field; in this case DATA must - also be passed as NULL. The return value is the status word or -1 - for an invalid SLOT or other non card related error. If RETBUF is - not NULL, it will receive an allocated buffer with the returned - data. The length of that data will be put into *RETBUFLEN. The - caller is reponsible for releasing the buffer even in case of - errors. */ -int -apdu_send (int slot, int class, int ins, int p0, int p1, - int lc, const char *data, unsigned char **retbuf, size_t *retbuflen) -{ - return apdu_send_le (slot, class, ins, p0, p1, lc, data, 256, - retbuf, retbuflen); -} - -/* Send an APDU to the card in SLOT. The APDU is created from all - given parameters: CLASS, INS, P0, P1, LC, DATA. A value of -1 for - LC won't sent this field and the data field; in this case DATA must - also be passed as NULL. The return value is the status word or -1 - for an invalid SLOT or other non card related error. No data will be - returned. */ -int -apdu_send_simple (int slot, int class, int ins, int p0, int p1, - int lc, const char *data) -{ - return apdu_send_le (slot, class, ins, p0, p1, lc, data, -1, NULL, NULL); -} - - - - diff --git a/scd/apdu.h b/scd/apdu.h deleted file mode 100644 index f74bab7fe..000000000 --- a/scd/apdu.h +++ /dev/null @@ -1,85 +0,0 @@ -/* apdu.h - ISO 7816 APDU functions and low level I/O - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef APDU_H -#define APDU_H - -/* ISO 7816 values for the statusword are defined here because they - should not be visible to the users of the actual ISO command - API. */ -enum { - SW_MORE_DATA = 0x6100, /* Note: that the low byte must be - masked of.*/ - SW_EOF_REACHED = 0x6282, - SW_EEPROM_FAILURE = 0x6581, - SW_WRONG_LENGTH = 0x6700, - SW_CHV_WRONG = 0x6982, - SW_CHV_BLOCKED = 0x6983, - SW_USE_CONDITIONS = 0x6985, - SW_BAD_PARAMETER = 0x6a80, /* (in the data field) */ - SW_NOT_SUPPORTED = 0x6a81, - SW_FILE_NOT_FOUND = 0x6a82, - SW_RECORD_NOT_FOUND = 0x6a83, - SW_REF_NOT_FOUND = 0x6a88, - SW_BAD_P0_P1 = 0x6b00, - SW_INS_NOT_SUP = 0x6d00, - SW_CLA_NOT_SUP = 0x6e00, - SW_SUCCESS = 0x9000, - - /* The follwoing statuswords are no real ones but used to map host - OS errors into status words. A status word is 16 bit so that - those values can't be issued by a card. */ - SW_HOST_OUT_OF_CORE = 0x10001, /* No way yet to differentiate - between errnos on a failed malloc. */ - SW_HOST_INV_VALUE = 0x10002, - SW_HOST_INCOMPLETE_CARD_RESPONSE = 0x10003, - SW_HOST_NO_DRIVER = 0x10004, - SW_HOST_NOT_SUPPORTED = 0x10005, - SW_HOST_LOCKING_FAILED= 0x10006, - SW_HOST_BUSY = 0x10007 -}; - - - -/* Note , that apdu_open_reader returns no status word but -1 on error. */ -int apdu_open_reader (const char *portstr); -int apdu_close_reader (int slot); -int apdu_enum_reader (int slot, int *used); -unsigned char *apdu_get_atr (int slot, size_t *atrlen); - - -/* The apdu send functions do return status words. */ -int apdu_reset (int slot); -int apdu_get_status (int slot, int hang, - unsigned int *status, unsigned int *changed); -int apdu_send_simple (int slot, int class, int ins, int p0, int p1, - int lc, const char *data); -int apdu_send (int slot, int class, int ins, int p0, int p1, - int lc, const char *data, - unsigned char **retbuf, size_t *retbuflen); -int apdu_send_le (int slot, int class, int ins, int p0, int p1, - int lc, const char *data, int le, - unsigned char **retbuf, size_t *retbuflen); - - -#endif /*APDU_H*/ - - - diff --git a/scd/app-common.h b/scd/app-common.h deleted file mode 100644 index c61bcca60..000000000 --- a/scd/app-common.h +++ /dev/null @@ -1,170 +0,0 @@ -/* app-common.h - Common declarations for all card applications - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_SCD_APP_COMMON_H -#define GNUPG_SCD_APP_COMMON_H - -#if GNUPG_MAJOR_VERSION != 1 -#include <ksba.h> -#endif - -struct app_local_s; /* Defined by all app-*.c. */ - -struct app_ctx_s { - int initialized; /* The application has been initialied and the - function pointers may be used. Note that for - unsupported operations the particular - function pointer is set to NULL */ - int slot; /* Used reader. */ - unsigned char *serialno; /* Serialnumber in raw form, allocated. */ - size_t serialnolen; /* Length in octets of serialnumber. */ - const char *apptype; - unsigned int card_version; - int did_chv1; - int force_chv1; /* True if the card does not cache CHV1. */ - int did_chv2; - int did_chv3; - struct app_local_s *app_local; /* Local to the application. */ - struct { - void (*deinit) (app_t app); - int (*learn_status) (app_t app, ctrl_t ctrl); - int (*readcert) (app_t app, const char *certid, - unsigned char **cert, size_t *certlen); - int (*getattr) (app_t app, ctrl_t ctrl, const char *name); - int (*setattr) (app_t app, const char *name, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const unsigned char *value, size_t valuelen); - int (*sign) (app_t app, - const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ); - int (*auth) (app_t app, const char *keyidstr, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen); - int (*decipher) (app_t app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen); - int (*genkey) (app_t app, ctrl_t ctrl, - const char *keynostr, unsigned int flags, - int (*pincb)(void*, const char *, char **), - void *pincb_arg); - int (*change_pin) (app_t app, ctrl_t ctrl, - const char *chvnostr, int reset_mode, - int (*pincb)(void*, const char *, char **), - void *pincb_arg); - int (*check_pin) (app_t app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg); - } fnc; - -}; - -#if GNUPG_MAJOR_VERSION == 1 -int app_select_openpgp (app_t app); -int app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp); -#else -/*-- app-help.c --*/ -gpg_error_t app_help_get_keygrip_string (ksba_cert_t cert, char *hexkeygrip); -size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff); - - -/*-- app.c --*/ -app_t select_application (ctrl_t ctrl, int slot, const char *name); -void release_application (app_t app); -int app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp); -int app_write_learn_status (app_t app, ctrl_t ctrl); -int app_readcert (app_t app, const char *certid, - unsigned char **cert, size_t *certlen); -int app_getattr (app_t app, ctrl_t ctrl, const char *name); -int app_setattr (app_t app, const char *name, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const unsigned char *value, size_t valuelen); -int app_sign (app_t app, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ); -int app_auth (app_t app, const char *keyidstr, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen); -int app_decipher (app_t app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ); -int app_genkey (app_t app, ctrl_t ctrl, - const char *keynostr, unsigned int flags, - int (*pincb)(void*, const char *, char **), - void *pincb_arg); -int app_get_challenge (app_t app, size_t nbytes, unsigned char *buffer); -int app_change_pin (app_t app, ctrl_t ctrl, - const char *chvnostr, int reset_mode, - int (*pincb)(void*, const char *, char **), - void *pincb_arg); -int app_check_pin (app_t app, const char *keyidstr, - int (*pincb)(void*, const char *, char **), - void *pincb_arg); - - -/*-- app-openpgp.c --*/ -int app_select_openpgp (app_t app); - -int app_openpgp_cardinfo (app_t app, - char **serialno, - char **disp_name, - char **pubkey_url, - unsigned char **fpr1, - unsigned char **fpr2, - unsigned char **fpr3); -int app_openpgp_storekey (app_t app, int keyno, - unsigned char *template, size_t template_len, - time_t created_at, - const unsigned char *m, size_t mlen, - const unsigned char *e, size_t elen, - int (*pincb)(void*, const char *, char **), - void *pincb_arg); -int app_openpgp_readkey (app_t app, int keyno, - unsigned char **m, size_t *mlen, - unsigned char **e, size_t *elen); -/*-- app-nks.c --*/ -int app_select_nks (app_t app); - -/*-- app-dinsig.c --*/ -int app_select_dinsig (app_t app); - - -#endif - - - -#endif /*GNUPG_SCD_APP_COMMON_H*/ - - - diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c deleted file mode 100644 index 38fbc79ee..000000000 --- a/scd/app-dinsig.c +++ /dev/null @@ -1,427 +0,0 @@ -/* app-dinsig.c - The DINSIG (DIN V 66291-1) card application. - * Copyright (C) 2002, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -/* The German signature law and its bylaw (SigG and SigV) is currently - used with an interface specification described in DIN V 66291-1. - The AID to be used is: 'D27600006601'. - - The file IDs for certificates utilize the generic format: - Cxyz - C being the hex digit 'C' (12). - x being the service indicator: - '0' := SigG conform digital signature. - '1' := entity authentication. - '2' := key encipherment. - '3' := data encipherment. - '4' := key agreement. - other values are reserved for future use. - y being the security environment number using '0' for cards - not supporting a SE number. - z being the certificate type: - '0' := C.CH (base certificate of card holder) or C.ICC. - '1' .. '7' := C.CH (business or professional certificate - of card holder. - '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA). - 'E' := C.RCA (self certified certificate of the Root-CA). - 'F' := reserved. - - The file IDs used by default are: - '1F00' EF.SSD (security service descriptor). [o,o] - '2F02' EF.GDO (global data objects) [m,m] - 'A000' EF.PROT (signature log). Cyclic file with 20 records of 53 byte. - Read and update after user authentication. [o,o] - 'B000' EF.PK.RCA.DS (public keys of Root-CA). Size is 512b or size - of keys. [m (unless a 'C00E' is present),m] - 'B001' EF.PK.CA.DS (public keys of CAs). Size is 512b or size - of keys. [o,o] - 'C00n' EF.C.CH.DS (digital signature certificate of card holder) - with n := 0 .. 7. Size is 2k or size of cert. Read and - update allowed after user authentication. [m,m] - 'C00m' EF.C.CA.DS (digital signature certificate of CA) - with m := 8 .. E. Size is 1k or size of cert. Read always - allowed, update after user authentication. [o,o] - 'C100' EF.C.ICC.AUT (AUT certificate of ICC) [o,m] - 'C108' EF.C.CA.AUT (AUT certificate of CA) [o,m] - 'D000' EF.DM (display message) [-,m] - - The letters in brackets indicate optional or mandatory files: The - first for card terminals under full control and the second for - "business" card terminals. -*/ - - - - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <time.h> - -#include "scdaemon.h" - -#include "iso7816.h" -#include "app-common.h" -#include "tlv.h" - - -static int -do_learn_status (app_t app, ctrl_t ctrl) -{ - gpg_error_t err; - char ct_buf[100], id_buf[100]; - char hexkeygrip[41]; - size_t len, certoff; - unsigned char *der; - size_t derlen; - ksba_cert_t cert; - int fid; - - /* Return the certificate of the card holder. */ - fid = 0xC000; - len = app_help_read_length_of_cert (app->slot, fid, &certoff); - if (!len) - return 0; /* Card has not been personalized. */ - - sprintf (ct_buf, "%d", 101); - sprintf (id_buf, "DINSIG.%04X", fid); - send_status_info (ctrl, "CERTINFO", - ct_buf, strlen (ct_buf), - id_buf, strlen (id_buf), - NULL, (size_t)0); - - /* Now we need to read the certificate, so that we can get the - public key out of it. */ - err = iso7816_read_binary (app->slot, certoff, len-certoff, &der, &derlen); - if (err) - { - log_info ("error reading entire certificate from FID 0x%04X: %s\n", - fid, gpg_strerror (err)); - return 0; - } - - err = ksba_cert_new (&cert); - if (err) - { - xfree (der); - return err; - } - err = ksba_cert_init_from_mem (cert, der, derlen); - xfree (der); der = NULL; - if (err) - { - log_error ("failed to parse the certificate at FID 0x%04X: %s\n", - fid, gpg_strerror (err)); - ksba_cert_release (cert); - return err; - } - err = app_help_get_keygrip_string (cert, hexkeygrip); - if (err) - { - log_error ("failed to calculate the keygrip for FID 0x%04X\n", fid); - ksba_cert_release (cert); - return gpg_error (GPG_ERR_CARD); - } - ksba_cert_release (cert); - - sprintf (id_buf, "DINSIG.%04X", fid); - send_status_info (ctrl, "KEYPAIRINFO", - hexkeygrip, 40, - id_buf, strlen (id_buf), - NULL, (size_t)0); - return 0; -} - - - - -/* Read the certificate with id CERTID (as returned by learn_status in - the CERTINFO status lines) and return it in the freshly allocated - buffer put into CERT and the length of the certificate put into - CERTLEN. - - FIXME: This needs some cleanups and caching with do_learn_status. -*/ -static int -do_readcert (app_t app, const char *certid, - unsigned char **cert, size_t *certlen) -{ - int fid; - gpg_error_t err; - unsigned char *buffer; - const unsigned char *p; - size_t buflen, n; - int class, tag, constructed, ndef; - size_t totobjlen, objlen, hdrlen; - int rootca = 0; - - *cert = NULL; - *certlen = 0; - if (strncmp (certid, "DINSIG.", 7) ) - return gpg_error (GPG_ERR_INV_ID); - certid += 7; - if (!hexdigitp (certid) || !hexdigitp (certid+1) - || !hexdigitp (certid+2) || !hexdigitp (certid+3) - || certid[4]) - return gpg_error (GPG_ERR_INV_ID); - fid = xtoi_4 (certid); - if (fid != 0xC000 ) - return gpg_error (GPG_ERR_NOT_FOUND); - - /* Read the entire file. fixme: This could be optimized by first - reading the header to figure out how long the certificate - actually is. */ - err = iso7816_select_file (app->slot, fid, 0, NULL, NULL); - if (err) - { - log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err)); - return err; - } - - err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen); - if (err) - { - log_error ("error reading certificate from FID 0x%04X: %s\n", - fid, gpg_strerror (err)); - return err; - } - - if (!buflen || *buffer == 0xff) - { - log_info ("no certificate contained in FID 0x%04X\n", fid); - err = gpg_error (GPG_ERR_NOT_FOUND); - goto leave; - } - - /* Now figure something out about the object. */ - p = buffer; - n = buflen; - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - goto leave; - if ( class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed ) - ; - else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed ) - rootca = 1; - else - return gpg_error (GPG_ERR_INV_OBJ); - totobjlen = objlen + hdrlen; - assert (totobjlen <= buflen); - - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - goto leave; - - if (rootca) - ; - else if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed) - { - const unsigned char *save_p; - - /* The certificate seems to be contained in a userCertificate - container. Skip this and assume the following sequence is - the certificate. */ - if (n < objlen) - { - err = gpg_error (GPG_ERR_INV_OBJ); - goto leave; - } - p += objlen; - n -= objlen; - save_p = p; - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - goto leave; - if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) ) - return gpg_error (GPG_ERR_INV_OBJ); - totobjlen = objlen + hdrlen; - assert (save_p + totobjlen <= buffer + buflen); - memmove (buffer, save_p, totobjlen); - } - - *cert = buffer; - buffer = NULL; - *certlen = totobjlen; - - leave: - xfree (buffer); - return err; -} - - -/* Verify the PIN if required. */ -static int -verify_pin (app_t app, - int (pincb)(void*, const char *, char **), - void *pincb_arg) -{ - if (!app->did_chv1 || app->force_chv1 ) - { - char *pinvalue; - int rc; - - rc = pincb (pincb_arg, "PIN", &pinvalue); - if (rc) - { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); - return rc; - } - - /* We require the PIN to be at least 6 and at max 8 bytes. - According to the specs, this should all be ASCII but we don't - check this. */ - if (strlen (pinvalue) < 6) - { - log_error ("PIN is too short; minimum length is 6\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - else if (strlen (pinvalue) > 8) - { - log_error ("PIN is too large; maximum length is 8\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - - rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); - if (rc) - { - log_error ("verify PIN failed\n"); - xfree (pinvalue); - return rc; - } - app->did_chv1 = 1; - xfree (pinvalue); - } - - return 0; -} - - - -/* Create the signature and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; - that callback should return the PIN in an allocated buffer and - store that in the 3rd argument. */ -static int -do_sign (app_t app, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, - 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; - static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, - 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; - int rc; - int fid; - unsigned char data[35]; /* Must be large enough for a SHA-1 digest - + the largest OID _prefix above. */ - - if (!keyidstr || !*keyidstr) - return gpg_error (GPG_ERR_INV_VALUE); - if (indatalen != 20 && indatalen != 16 && indatalen != 35) - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check that the provided ID is vaid. This is not really needed - but we do it to to enforce correct usage by the caller. */ - if (strncmp (keyidstr, "DINSIG.", 7) ) - return gpg_error (GPG_ERR_INV_ID); - keyidstr += 7; - if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1) - || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3) - || keyidstr[4]) - return gpg_error (GPG_ERR_INV_ID); - fid = xtoi_4 (keyidstr); - if (fid != 0xC000) - return gpg_error (GPG_ERR_NOT_FOUND); - - /* Prepare the DER object from INDATA. */ - if (indatalen == 35) - { - /* Alright, the caller was so kind to send us an already - prepared DER object. Check that it is what we want and that - it matches the hash algorithm. */ - if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15)) - ; - else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata, rmd160_prefix,15)) - ; - else - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - memcpy (data, indata, indatalen); - } - else - { - if (hashalgo == GCRY_MD_SHA1) - memcpy (data, sha1_prefix, 15); - else if (hashalgo == GCRY_MD_RMD160) - memcpy (data, rmd160_prefix, 15); - else - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - memcpy (data+15, indata, indatalen); - } - - rc = verify_pin (app, pincb, pincb_arg); - if (!rc) - rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen); - return rc; -} - - - -/* Select the DINSIG application on the card in SLOT. This function - must be used before any other DINSIG application functions. */ -int -app_select_dinsig (APP app) -{ - static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 }; - int slot = app->slot; - int rc; - - rc = iso7816_select_application (slot, aid, sizeof aid); - if (!rc) - { - app->apptype = "DINSIG"; - - app->fnc.learn_status = do_learn_status; - app->fnc.readcert = do_readcert; - app->fnc.getattr = NULL; - app->fnc.setattr = NULL; - app->fnc.genkey = NULL; - app->fnc.sign = do_sign; - app->fnc.auth = NULL; - app->fnc.decipher = NULL; - app->fnc.change_pin = NULL; - app->fnc.check_pin = NULL; - - app->force_chv1 = 1; - } - - return rc; -} diff --git a/scd/app-help.c b/scd/app-help.c deleted file mode 100644 index 1c3c52b15..000000000 --- a/scd/app-help.c +++ /dev/null @@ -1,162 +0,0 @@ -/* app-help.c - Application helper functions - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "scdaemon.h" -#include "app-common.h" -#include "iso7816.h" -#include "tlv.h" - -/* Return the KEYGRIP for the certificate CERT as an hex encoded - string in the user provided buffer HEXKEYGRIP which must be of at - least 41 bytes. */ -gpg_error_t -app_help_get_keygrip_string (ksba_cert_t cert, char *hexkeygrip) -{ - gpg_error_t err; - gcry_sexp_t s_pkey; - ksba_sexp_t p; - size_t n; - unsigned char array[20]; - int i; - - p = ksba_cert_get_public_key (cert); - if (!p) - return gpg_error (GPG_ERR_BUG); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - return gpg_error (GPG_ERR_INV_SEXP); - err = gcry_sexp_sscan (&s_pkey, NULL, p, n); - xfree (p); - if (err) - return err; /* Can't parse that S-expression. */ - if (!gcry_pk_get_keygrip (s_pkey, array)) - { - gcry_sexp_release (s_pkey); - return gpg_error (GPG_ERR_GENERAL); /* Failed to calculate the keygrip.*/ - } - gcry_sexp_release (s_pkey); - - for (i=0; i < 20; i++) - sprintf (hexkeygrip+i*2, "%02X", array[i]); - - return 0; -} - - - -/* Given the SLOT and the File ID FID, return the length of the - certificate contained in that file. Returns 0 if the file does not - exists or does not contain a certificate. If R_CERTOFF is not - NULL, the length the header will be stored at this address; thus to - parse the X.509 certificate a read should start at that offset. - - On success the file is still selected. -*/ -size_t -app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff) -{ - gpg_error_t err; - unsigned char *buffer; - const unsigned char *p; - size_t buflen, n; - int class, tag, constructed, ndef; - size_t resultlen, objlen, hdrlen; - - err = iso7816_select_file (slot, fid, 0, NULL, NULL); - if (err) - { - log_info ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err)); - return 0; - } - - err = iso7816_read_binary (slot, 0, 32, &buffer, &buflen); - if (err) - { - log_info ("error reading certificate from FID 0x%04X: %s\n", - fid, gpg_strerror (err)); - return 0; - } - - if (!buflen || *buffer == 0xff) - { - log_info ("no certificate contained in FID 0x%04X\n", fid); - xfree (buffer); - return 0; - } - - p = buffer; - n = buflen; - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - { - log_info ("error parsing certificate in FID 0x%04X: %s\n", - fid, gpg_strerror (err)); - xfree (buffer); - return 0; - } - - /* All certificates should commence with a SEQUENCE except for the - special ROOT CA which are enclosed in a SET. */ - if ( !(class == CLASS_UNIVERSAL && constructed - && (tag == TAG_SEQUENCE || tag == TAG_SET))) - { - log_info ("contents of FID 0x%04X does not look like a certificate\n", - fid); - return 0; - } - - resultlen = objlen + hdrlen; - if (r_certoff) - { - /* The callers want the offset to the actual certificate. */ - *r_certoff = hdrlen; - - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - return 0; - - if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed) - { - /* The certificate seems to be contained in a - userCertificate container. Assume the following sequence - is the certificate. */ - *r_certoff += hdrlen + objlen; - if (*r_certoff > resultlen) - { - *r_certoff = 0; - return 0; /* That should never happen. */ - } - } - else - *r_certoff = 0; - } - - return resultlen; -} - - diff --git a/scd/app-nks.c b/scd/app-nks.c deleted file mode 100644 index e69b59879..000000000 --- a/scd/app-nks.c +++ /dev/null @@ -1,515 +0,0 @@ -/* app-nks.c - The Telesec NKS 2.0 card application. - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <time.h> - -#include "scdaemon.h" - -#include "iso7816.h" -#include "app-common.h" -#include "tlv.h" - -static struct { - int fid; /* File ID. */ - int certtype; /* Type of certificate or 0 if it is not a certificate. */ - int iskeypair; /* If true has the FID of the correspoding certificate. */ - int issignkey; /* True if file is a key usable for signing. */ - int isenckey; /* True if file is a key usable for decryption. */ -} filelist[] = { - { 0x4531, 0, 0xC000, 1, 0 }, - { 0xC000, 101 }, - { 0x4331, 100 }, - { 0x4332, 100 }, - { 0xB000, 110 }, - { 0x45B1, 0, 0xC200, 0, 1 }, - { 0xC200, 101 }, - { 0x43B1, 100 }, - { 0x43B2, 100 }, - { 0, 0 } -}; - - - -/* Read the file with FID, assume it contains a public key and return - its keygrip in the caller provided 41 byte buffer R_GRIPSTR. */ -static gpg_error_t -keygripstr_from_pk_file (int slot, int fid, char *r_gripstr) -{ - gpg_error_t err; - unsigned char grip[20]; - unsigned char *buffer[2]; - size_t buflen[2]; - gcry_sexp_t sexp; - int i; - - err = iso7816_select_file (slot, fid, 0, NULL, NULL); - if (err) - return err; - err = iso7816_read_record (slot, 1, 1, 0, &buffer[0], &buflen[0]); - if (err) - return err; - err = iso7816_read_record (slot, 2, 1, 0, &buffer[1], &buflen[1]); - if (err) - { - xfree (buffer[0]); - return err; - } - - for (i=0; i < 2; i++) - { - /* Check that the value appears like an integer encoded as - Simple-TLV. We don't check the tag because the tests cards I - have use 1 for both, the modulus and the exponent - the - example in the documentation gives 2 for the exponent. */ - if (buflen[i] < 3) - err = gpg_error (GPG_ERR_TOO_SHORT); - else if (buffer[i][1] != buflen[i]-2 ) - err = gpg_error (GPG_ERR_INV_OBJ); - } - - if (!err) - err = gcry_sexp_build (&sexp, NULL, - "(public-key (rsa (n %b) (e %b)))", - (int)buflen[0]-2, buffer[0]+2, - (int)buflen[1]-2, buffer[1]+2); - - xfree (buffer[0]); - xfree (buffer[1]); - if (err) - return err; - - if (!gcry_pk_get_keygrip (sexp, grip)) - { - err = gpg_error (GPG_ERR_INTERNAL); /* i.e. RSA not supported by - libgcrypt. */ - } - else - { - for (i=0; i < 20; i++) - sprintf (r_gripstr+i*2, "%02X", grip[i]); - } - gcry_sexp_release (sexp); - return err; -} - - - -static int -do_learn_status (APP app, CTRL ctrl) -{ - gpg_error_t err; - char ct_buf[100], id_buf[100]; - int i; - - /* Output information about all useful objects. */ - for (i=0; filelist[i].fid; i++) - { - if (filelist[i].certtype) - { - size_t len; - - len = app_help_read_length_of_cert (app->slot, - filelist[i].fid, NULL); - if (len) - { - /* FIXME: We should store the length in the application's - context so that a following readcert does only need to - read that many bytes. */ - sprintf (ct_buf, "%d", filelist[i].certtype); - sprintf (id_buf, "NKS-DF01.%04X", filelist[i].fid); - send_status_info (ctrl, "CERTINFO", - ct_buf, strlen (ct_buf), - id_buf, strlen (id_buf), - NULL, (size_t)0); - } - } - else if (filelist[i].iskeypair) - { - char gripstr[40+1]; - - err = keygripstr_from_pk_file (app->slot, filelist[i].fid, gripstr); - if (err) - log_error ("can't get keygrip from FID 0x%04X: %s\n", - filelist[i].fid, gpg_strerror (err)); - else - { - sprintf (id_buf, "NKS-DF01.%04X", filelist[i].fid); - send_status_info (ctrl, "KEYPAIRINFO", - gripstr, 40, - id_buf, strlen (id_buf), - NULL, (size_t)0); - } - } - } - - return 0; -} - - - - -/* Read the certificate with id CERTID (as returned by learn_status in - the CERTINFO status lines) and return it in the freshly allocated - buffer put into CERT and the length of the certificate put into - CERTLEN. */ -static int -do_readcert (app_t app, const char *certid, - unsigned char **cert, size_t *certlen) -{ - int i, fid; - gpg_error_t err; - unsigned char *buffer; - const unsigned char *p; - size_t buflen, n; - int class, tag, constructed, ndef; - size_t totobjlen, objlen, hdrlen; - int rootca = 0; - - *cert = NULL; - *certlen = 0; - if (strncmp (certid, "NKS-DF01.", 9) ) - return gpg_error (GPG_ERR_INV_ID); - certid += 9; - if (!hexdigitp (certid) || !hexdigitp (certid+1) - || !hexdigitp (certid+2) || !hexdigitp (certid+3) - || certid[4]) - return gpg_error (GPG_ERR_INV_ID); - fid = xtoi_4 (certid); - for (i=0; filelist[i].fid; i++) - if ((filelist[i].certtype || filelist[i].iskeypair) - && filelist[i].fid == fid) - break; - if (!filelist[i].fid) - return gpg_error (GPG_ERR_NOT_FOUND); - - /* If the requested objects is a plain public key, redirect it to - the corresponding certificate. The whole system is a bit messy - becuase we sometime use the key directly or let the caller - retrieve the key from the certificate. The valid point behind - that is to support not-yet stored certificates. */ - if (filelist[i].iskeypair) - fid = filelist[i].iskeypair; - - - /* Read the entire file. fixme: This could be optimized by first - reading the header to figure out how long the certificate - actually is. */ - err = iso7816_select_file (app->slot, fid, 0, NULL, NULL); - if (err) - { - log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err)); - return err; - } - - err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen); - if (err) - { - log_error ("error reading certificate from FID 0x%04X: %s\n", - fid, gpg_strerror (err)); - return err; - } - - if (!buflen || *buffer == 0xff) - { - log_info ("no certificate contained in FID 0x%04X\n", fid); - err = gpg_error (GPG_ERR_NOT_FOUND); - goto leave; - } - - /* Now figure something out about the object. */ - p = buffer; - n = buflen; - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - goto leave; - if ( class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed ) - ; - else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed ) - rootca = 1; - else - return gpg_error (GPG_ERR_INV_OBJ); - totobjlen = objlen + hdrlen; - assert (totobjlen <= buflen); - - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - goto leave; - - if (rootca) - ; - else if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed) - { - const unsigned char *save_p; - - /* The certificate seems to be contained in a userCertificate - container. Skip this and assume the following sequence is - the certificate. */ - if (n < objlen) - { - err = gpg_error (GPG_ERR_INV_OBJ); - goto leave; - } - p += objlen; - n -= objlen; - save_p = p; - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - goto leave; - if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) ) - return gpg_error (GPG_ERR_INV_OBJ); - totobjlen = objlen + hdrlen; - assert (save_p + totobjlen <= buffer + buflen); - memmove (buffer, save_p, totobjlen); - } - - *cert = buffer; - buffer = NULL; - *certlen = totobjlen; - - leave: - xfree (buffer); - return err; -} - - -/* Verify the PIN if required. */ -static int -verify_pin (app_t app, - int (pincb)(void*, const char *, char **), - void *pincb_arg) -{ - /* Note that force_chv1 is never set but we do it here anyway so - that other applications may euse 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 ) - { - char *pinvalue; - int rc; - - rc = pincb (pincb_arg, "PIN", &pinvalue); - if (rc) - { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); - return rc; - } - - /* The follwoing limits are due to TCOS but also defined in the - NKS specs. */ - if (strlen (pinvalue) < 6) - { - log_error ("PIN is too short; minimum length is 6\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - else if (strlen (pinvalue) > 16) - { - log_error ("PIN is too large; maximum length is 16\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - - /* Also it is possible to use a local PIN, we use the gloabl - PIN for this application. */ - rc = iso7816_verify (app->slot, 0, pinvalue, strlen (pinvalue)); - if (rc) - { - log_error ("verify PIN failed\n"); - xfree (pinvalue); - return rc; - } - app->did_chv1 = 1; - xfree (pinvalue); - } - - return 0; -} - - - -/* Create the signature and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; - that callback should return the PIN in an allocated buffer and - store that in the 3rd argument. */ -static int -do_sign (app_t app, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, - 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; - static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, - 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; - int rc, i; - int fid; - unsigned char data[35]; /* Must be large enough for a SHA-1 digest - + the largest OID _prefix above. */ - - if (!keyidstr || !*keyidstr) - return gpg_error (GPG_ERR_INV_VALUE); - if (indatalen != 20 && indatalen != 16 && indatalen != 35) - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check that the provided ID is vaid. 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); - keyidstr += 9; - if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1) - || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3) - || keyidstr[4]) - return gpg_error (GPG_ERR_INV_ID); - fid = xtoi_4 (keyidstr); - for (i=0; filelist[i].fid; i++) - if (filelist[i].iskeypair && filelist[i].fid == fid) - break; - if (!filelist[i].fid) - return gpg_error (GPG_ERR_NOT_FOUND); - if (!filelist[i].issignkey) - return gpg_error (GPG_ERR_INV_ID); - - /* Prepare the DER object from INDATA. */ - if (indatalen == 35) - { - /* Alright, the caller was so kind to send us an already - prepared DER object. Check that it is waht we want and that - it matches the hash algorithm. */ - if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15)) - ; - else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata, rmd160_prefix,15)) - ; - else - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - memcpy (data, indata, indatalen); - } - else - { - if (hashalgo == GCRY_MD_SHA1) - memcpy (data, sha1_prefix, 15); - else if (hashalgo == GCRY_MD_RMD160) - memcpy (data, rmd160_prefix, 15); - else - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - memcpy (data+15, indata, indatalen); - } - - rc = verify_pin (app, pincb, pincb_arg); - if (!rc) - rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen); - return rc; -} - - - - -/* Decrypt the data in INDATA and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; it - should return the PIN in an allocated buffer and put it into PIN. */ -static int -do_decipher (app_t app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - static const unsigned char mse_parm[] = { - 0x80, 1, 0x10, /* Select algorithm RSA. */ - 0x84, 1, 0x81 /* Select locak secret key 1 for descryption. */ - }; - int rc, i; - int fid; - - if (!keyidstr || !*keyidstr || !indatalen) - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check that the provided ID is vaid. 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); - keyidstr += 9; - if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1) - || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3) - || keyidstr[4]) - return gpg_error (GPG_ERR_INV_ID); - fid = xtoi_4 (keyidstr); - for (i=0; filelist[i].fid; i++) - if (filelist[i].iskeypair && filelist[i].fid == fid) - break; - if (!filelist[i].fid) - return gpg_error (GPG_ERR_NOT_FOUND); - if (!filelist[i].isenckey) - return gpg_error (GPG_ERR_INV_ID); - - /* Do the TCOS specific MSE. */ - rc = iso7816_manage_security_env (app->slot, - 0xC1, 0xB8, - mse_parm, sizeof mse_parm); - if (!rc) - rc = verify_pin (app, pincb, pincb_arg); - if (!rc) - rc = iso7816_decipher (app->slot, indata, indatalen, 0x81, - outdata, outdatalen); - return rc; -} - - - -/* Select the NKS 2.0 application on the card in SLOT. */ -int -app_select_nks (APP app) -{ - static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x03, 0x01, 0x02 }; - int slot = app->slot; - int rc; - - rc = iso7816_select_application (slot, aid, sizeof aid); - if (!rc) - { - app->apptype = "NKS"; - - app->fnc.learn_status = do_learn_status; - app->fnc.readcert = do_readcert; - app->fnc.getattr = NULL; - app->fnc.setattr = NULL; - app->fnc.genkey = NULL; - app->fnc.sign = do_sign; - app->fnc.auth = NULL; - app->fnc.decipher = do_decipher; - app->fnc.change_pin = NULL; - app->fnc.check_pin = NULL; - } - - return rc; -} - - diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c deleted file mode 100644 index f40951941..000000000 --- a/scd/app-openpgp.c +++ /dev/null @@ -1,1640 +0,0 @@ -/* app-openpgp.c - The OpenPGP card application. - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <time.h> - -#if GNUPG_MAJOR_VERSION == 1 -/* This is used with GnuPG version < 1.9. The code has been source - copied from the current GnuPG >= 1.9 and is maintained over - there. */ -#include "options.h" -#include "errors.h" -#include "memory.h" -#include "util.h" -#include "i18n.h" -#include "cardglue.h" -#else /* GNUPG_MAJOR_VERSION != 1 */ -#include "scdaemon.h" -#endif /* GNUPG_MAJOR_VERSION != 1 */ - -#include "iso7816.h" -#include "app-common.h" -#include "tlv.h" - - -static struct { - int tag; - int constructed; - int get_from; /* Constructed DO with this DO or 0 for direct access. */ - int binary; - int dont_cache; - int flush_on_error; - char *desc; -} data_objects[] = { - { 0x005E, 0, 0, 1, 0, 0, "Login Data" }, - { 0x5F50, 0, 0, 0, 0, 0, "URL" }, - { 0x0065, 1, 0, 1, 0, 0, "Cardholder Related Data"}, - { 0x005B, 0, 0x65, 0, 0, 0, "Name" }, - { 0x5F2D, 0, 0x65, 0, 0, 0, "Language preferences" }, - { 0x5F35, 0, 0x65, 0, 0, 0, "Sex" }, - { 0x006E, 1, 0, 1, 0, 0, "Application Related Data" }, - { 0x004F, 0, 0x6E, 1, 0, 0, "AID" }, - { 0x0073, 1, 0, 1, 0, 0, "Discretionary Data Objects" }, - { 0x0047, 0, 0x6E, 1, 0, 0, "Card Capabilities" }, - { 0x00C0, 0, 0x6E, 1, 0, 0, "Extended Card Capabilities" }, - { 0x00C1, 0, 0x6E, 1, 0, 0, "Algorithm Attributes Signature" }, - { 0x00C2, 0, 0x6E, 1, 0, 0, "Algorithm Attributes Decryption" }, - { 0x00C3, 0, 0x6E, 1, 0, 0, "Algorithm Attributes Authentication" }, - { 0x00C4, 0, 0x6E, 1, 0, 1, "CHV Status Bytes" }, - { 0x00C5, 0, 0x6E, 1, 0, 0, "Fingerprints" }, - { 0x00C6, 0, 0x6E, 1, 0, 0, "CA Fingerprints" }, - { 0x007A, 1, 0, 1, 0, 0, "Security Support Template" }, - { 0x0093, 0, 0x7A, 1, 1, 0, "Digital Signature Counter" }, - { 0 } -}; - - -struct cache_s { - struct cache_s *next; - int tag; - size_t length; - unsigned char data[1]; -}; - -struct app_local_s { - struct cache_s *cache; -}; - - -static unsigned long convert_sig_counter_value (const unsigned char *value, - size_t valuelen); -static unsigned long get_sig_counter (APP app); - -/* Deconstructor. */ -static void -do_deinit (app_t app) -{ - if (app && app->app_local) - { - struct cache_s *c, *c2; - - for (c = app->app_local->cache; c; c = c2) - { - c2 = c->next; - xfree (c); - } - xfree (app->app_local); - app->app_local = NULL; - } -} - - -/* Wrapper around iso7816_get_data which first tries to get the data - from the cache. */ -static gpg_error_t -get_cached_data (app_t app, int tag, - unsigned char **result, size_t *resultlen) -{ - gpg_error_t err; - int i; - unsigned char *p; - size_t len; - struct cache_s *c; - - - *result = NULL; - *resultlen = 0; - - if (app->app_local) - { - for (c=app->app_local->cache; c; c = c->next) - if (c->tag == tag) - { - p = xtrymalloc (c->length); - if (!p) - return gpg_error (gpg_err_code_from_errno (errno)); - memcpy (p, c->data, c->length); - *resultlen = c->length; - *result = p; - return 0; - } - } - - err = iso7816_get_data (app->slot, tag, &p, &len); - if (err) - return err; - *result = p; - *resultlen = len; - - /* Check whether we should cache this object. */ - for (i=0; data_objects[i].tag; i++) - if (data_objects[i].tag == tag) - { - if (data_objects[i].dont_cache) - return 0; - break; - } - - /* No, cache it. */ - if (!app->app_local) - app->app_local = xtrycalloc (1, sizeof *app->app_local); - - /* Note that we can safely ignore out of core errors. */ - if (app->app_local) - { - for (c=app->app_local->cache; c; c = c->next) - assert (c->tag != tag); - - c = xtrymalloc (sizeof *c + len); - if (c) - { - memcpy (c->data, p, len); - c->length = len; - c->tag = tag; - c->next = app->app_local->cache; - app->app_local->cache = c; - } - } - - return 0; -} - -/* Remove DO at TAG from the cache. */ -static void -flush_cache_item (app_t app, int tag) -{ - struct cache_s *c, *cprev; - int i; - - if (!app->app_local) - return; - - for (c=app->app_local->cache, cprev=NULL; c ; cprev=c, c = c->next) - if (c->tag == tag) - { - if (cprev) - cprev->next = c->next; - else - app->app_local->cache = c->next; - xfree (c); - - for (c=app->app_local->cache; c ; c = c->next) - assert (c->tag != tag); /* Oops: duplicated entry. */ - return; - } - - /* Try again if we have an outer tag. */ - for (i=0; data_objects[i].tag; i++) - if (data_objects[i].tag == tag && data_objects[i].get_from - && data_objects[i].get_from != tag) - flush_cache_item (app, data_objects[i].get_from); -} - -/* Flush all entries from the cache which might be out of sync after - an error. */ -static void -flush_cache_after_error (app_t app) -{ - int i; - - for (i=0; data_objects[i].tag; i++) - if (data_objects[i].flush_on_error) - flush_cache_item (app, data_objects[i].tag); -} - - -/* Flush the entire cache. */ -static void -flush_cache (app_t app) -{ - if (app && app->app_local) - { - struct cache_s *c, *c2; - - for (c = app->app_local->cache; c; c = c2) - { - c2 = c->next; - xfree (c); - } - app->app_local->cache = NULL; - } -} - - -/* Get the DO identified by TAG from the card in SLOT and return a - buffer with its content in RESULT and NBYTES. The return value is - NULL if not found or a pointer which must be used to release the - buffer holding value. */ -static void * -get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes) -{ - int rc, i; - unsigned char *buffer; - size_t buflen; - unsigned char *value; - size_t valuelen; - - *result = NULL; - *nbytes = 0; - for (i=0; data_objects[i].tag && data_objects[i].tag != tag; i++) - ; - - value = NULL; - rc = -1; - if (data_objects[i].tag && data_objects[i].get_from) - { - rc = get_cached_data (app, data_objects[i].get_from, - &buffer, &buflen); - if (!rc) - { - const unsigned char *s; - - s = find_tlv (buffer, buflen, tag, &valuelen); - if (!s) - value = NULL; /* not found */ - else if (valuelen > buflen - (s - buffer)) - { - log_error ("warning: constructed DO too short\n"); - value = NULL; - xfree (buffer); buffer = NULL; - } - else - value = buffer + (s - buffer); - } - } - - if (!value) /* Not in a constructed DO, try simple. */ - { - rc = get_cached_data (app, tag, &buffer, &buflen); - if (!rc) - { - value = buffer; - valuelen = buflen; - } - } - - if (!rc) - { - *nbytes = valuelen; - *result = value; - return buffer; - } - return NULL; -} - - -static void -dump_all_do (int slot) -{ - int rc, i, j; - unsigned char *buffer; - size_t buflen; - - for (i=0; data_objects[i].tag; i++) - { - if (data_objects[i].get_from) - continue; - - rc = iso7816_get_data (slot, data_objects[i].tag, &buffer, &buflen); - if (gpg_err_code (rc) == GPG_ERR_NO_OBJ) - ; - else if (rc) - log_info ("DO `%s' not available: %s\n", - data_objects[i].desc, gpg_strerror (rc)); - else - { - if (data_objects[i].binary) - { - log_info ("DO `%s': ", data_objects[i].desc); - log_printhex ("", buffer, buflen); - } - else - log_info ("DO `%s': `%.*s'\n", - data_objects[i].desc, - (int)buflen, buffer); /* FIXME: sanitize */ - - if (data_objects[i].constructed) - { - for (j=0; data_objects[j].tag; j++) - { - const unsigned char *value; - size_t valuelen; - - if (j==i || data_objects[i].tag != data_objects[j].get_from) - continue; - value = find_tlv (buffer, buflen, - data_objects[j].tag, &valuelen); - if (!value) - ; /* not found */ - else if (valuelen > buflen - (value - buffer)) - log_error ("warning: constructed DO too short\n"); - else - { - if (data_objects[j].binary) - { - log_info ("DO `%s': ", data_objects[j].desc); - log_printhex ("", value, valuelen); - } - else - log_info ("DO `%s': `%.*s'\n", - data_objects[j].desc, - (int)valuelen, value); /* FIXME: sanitize */ - } - } - } - } - xfree (buffer); buffer = NULL; - } -} - - -/* Count the number of bits, assuming the A represents an unsigned big - integer of length LEN bytes. */ -static unsigned int -count_bits (const unsigned char *a, size_t len) -{ - unsigned int n = len * 8; - int i; - - for (; len && !*a; len--, a++, n -=8) - ; - if (len) - { - for (i=7; i && !(*a & (1<<i)); i--) - n--; - } - return n; -} - -/* Note, that FPR must be at least 20 bytes. */ -static int -store_fpr (int slot, int keynumber, u32 timestamp, - const unsigned char *m, size_t mlen, - const unsigned char *e, size_t elen, - unsigned char *fpr, unsigned int card_version) -{ - unsigned int n, nbits; - unsigned char *buffer, *p; - int rc; - - for (; mlen && !*m; mlen--, m++) /* strip leading zeroes */ - ; - for (; elen && !*e; elen--, e++) /* strip leading zeroes */ - ; - - n = 6 + 2 + mlen + 2 + elen; - p = buffer = xtrymalloc (3 + n); - if (!buffer) - return gpg_error (gpg_err_code_from_errno (errno)); - - *p++ = 0x99; /* ctb */ - *p++ = n >> 8; /* 2 byte length header */ - *p++ = n; - *p++ = 4; /* key packet version */ - *p++ = timestamp >> 24; - *p++ = timestamp >> 16; - *p++ = timestamp >> 8; - *p++ = timestamp; - *p++ = 1; /* RSA */ - nbits = count_bits (m, mlen); - *p++ = nbits >> 8; - *p++ = nbits; - memcpy (p, m, mlen); p += mlen; - nbits = count_bits (e, elen); - *p++ = nbits >> 8; - *p++ = nbits; - memcpy (p, e, elen); p += elen; - - log_printhex ("fprbuf:", buffer, n+3); - gcry_md_hash_buffer (GCRY_MD_SHA1, fpr, buffer, n+3); - - xfree (buffer); - - rc = iso7816_put_data (slot, (card_version > 0x0007? 0xC7 : 0xC6) - + keynumber, fpr, 20); - if (rc) - log_error ("failed to store the fingerprint: %s\n",gpg_strerror (rc)); - - return rc; -} - - -static void -send_fpr_if_not_null (CTRL ctrl, const char *keyword, - int number, const unsigned char *fpr) -{ - int i; - char buf[41]; - char numbuf[25]; - - for (i=0; i < 20 && !fpr[i]; i++) - ; - if (i==20) - return; /* All zero. */ - for (i=0; i< 20; i++) - sprintf (buf+2*i, "%02X", fpr[i]); - if (number == -1) - *numbuf = 0; /* Don't print the key number */ - else - sprintf (numbuf, "%d", number); - send_status_info (ctrl, keyword, - numbuf, (size_t)strlen(numbuf), - buf, (size_t)strlen (buf), NULL, 0); -} - -static void -send_key_data (CTRL ctrl, const char *name, - const unsigned char *a, size_t alen) -{ - char *p, *buf = xmalloc (alen*2+1); - - for (p=buf; alen; a++, alen--, p += 2) - sprintf (p, "%02X", *a); - - send_status_info (ctrl, "KEY-DATA", - name, (size_t)strlen(name), - buf, (size_t)strlen (buf), - NULL, 0); - xfree (buf); -} - -/* Implement the GETATTR command. This is similar to the LEARN - command but returns just one value via the status interface. */ -static int -do_getattr (APP app, CTRL ctrl, const char *name) -{ - static struct { - const char *name; - int tag; - int special; - } table[] = { - { "DISP-NAME", 0x005B }, - { "LOGIN-DATA", 0x005E }, - { "DISP-LANG", 0x5F2D }, - { "DISP-SEX", 0x5F35 }, - { "PUBKEY-URL", 0x5F50 }, - { "KEY-FPR", 0x00C5, 3 }, - { "CA-FPR", 0x00C6, 3 }, - { "CHV-STATUS", 0x00C4, 1 }, - { "SIG-COUNTER", 0x0093, 2 }, - { "SERIALNO", 0x004F, -1 }, - { "AID", 0x004F }, - { NULL, 0 } - }; - int idx, i; - void *relptr; - unsigned char *value; - size_t valuelen; - - for (idx=0; table[idx].name && strcmp (table[idx].name, name); idx++) - ; - if (!table[idx].name) - return gpg_error (GPG_ERR_INV_NAME); - - if (table[idx].special == -1) - { - /* The serial number is very special. We could have used the - AID DO to retrieve it, but we have it already in the app - context and the stamp argument is required anyway which we - can't by other means. The AID DO is available anyway but not - hex formatted. */ - char *serial; - time_t stamp; - char tmp[50]; - - if (!app_get_serial_and_stamp (app, &serial, &stamp)) - { - sprintf (tmp, "%lu", (unsigned long)stamp); - send_status_info (ctrl, "SERIALNO", - serial, strlen (serial), - tmp, strlen (tmp), - NULL, 0); - xfree (serial); - } - return 0; - } - - relptr = get_one_do (app, table[idx].tag, &value, &valuelen); - if (relptr) - { - if (table[idx].special == 1) - { - char numbuf[7*23]; - - for (i=0,*numbuf=0; i < valuelen && i < 7; i++) - sprintf (numbuf+strlen (numbuf), " %d", value[i]); - send_status_info (ctrl, table[idx].name, - numbuf, strlen (numbuf), NULL, 0); - } - else if (table[idx].special == 2) - { - char numbuf[50]; - - sprintf (numbuf, "%lu", convert_sig_counter_value (value, valuelen)); - send_status_info (ctrl, table[idx].name, - numbuf, strlen (numbuf), NULL, 0); - } - else if (table[idx].special == 3) - { - if (valuelen >= 60) - for (i=0; i < 3; i++) - send_fpr_if_not_null (ctrl, "KEY-FPR", i+1, value+i*20); - } - else - send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0); - - xfree (relptr); - } - return 0; -} - - -static int -do_learn_status (APP app, CTRL ctrl) -{ - do_getattr (app, ctrl, "DISP-NAME"); - do_getattr (app, ctrl, "DISP-LANG"); - do_getattr (app, ctrl, "DISP-SEX"); - do_getattr (app, ctrl, "PUBKEY-URL"); - do_getattr (app, ctrl, "LOGIN-DATA"); - do_getattr (app, ctrl, "KEY-FPR"); - do_getattr (app, ctrl, "CA-FPR"); - do_getattr (app, ctrl, "CHV-STATUS"); - do_getattr (app, ctrl, "SIG-COUNTER"); - - return 0; -} - - -/* Verify CHV2 if required. Depending on the configuration of the - card CHV1 will also be verified. */ -static int -verify_chv2 (app_t app, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc = 0; - - if (!app->did_chv2) - { - char *pinvalue; - - rc = pincb (pincb_arg, "PIN", &pinvalue); - if (rc) - { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); - return rc; - } - - if (strlen (pinvalue) < 6) - { - log_error ("prassphrase (CHV2) is too short; minimum length is 6\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - - rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue)); - if (rc) - { - log_error ("verify CHV2 failed: %s\n", gpg_strerror (rc)); - xfree (pinvalue); - flush_cache_after_error (app); - return rc; - } - app->did_chv2 = 1; - - if (!app->did_chv1 && !app->force_chv1) - { - rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); - if (gpg_err_code (rc) == GPG_ERR_BAD_PIN) - rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); - if (rc) - { - log_error ("verify CHV1 failed: %s\n", gpg_strerror (rc)); - xfree (pinvalue); - flush_cache_after_error (app); - return rc; - } - app->did_chv1 = 1; - } - xfree (pinvalue); - } - return rc; -} - -/* Verify CHV3 if required. */ -static int -verify_chv3 (APP app, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc = 0; - - if (!opt.allow_admin) - { - log_info ("access to admin commands is not configured\n"); - return gpg_error (GPG_ERR_EACCES); - } - - if (!app->did_chv3) - { - char *pinvalue; - - rc = pincb (pincb_arg, "Admin PIN", &pinvalue); - if (rc) - { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); - return rc; - } - - if (strlen (pinvalue) < 6) - { - log_error ("prassphrase (CHV3) is too short; minimum length is 6\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - - rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue)); - xfree (pinvalue); - if (rc) - { - log_error ("verify CHV3 failed: %s\n", gpg_strerror (rc)); - flush_cache_after_error (app); - return rc; - } - app->did_chv3 = 1; - } - return rc; -} - - -/* Handle the SETATTR operation. All arguments are already basically - checked. */ -static int -do_setattr (APP app, const char *name, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const unsigned char *value, size_t valuelen) -{ - gpg_error_t rc; - int idx; - static struct { - const char *name; - int tag; - int special; - } table[] = { - { "DISP-NAME", 0x005B }, - { "LOGIN-DATA", 0x005E }, - { "DISP-LANG", 0x5F2D }, - { "DISP-SEX", 0x5F35 }, - { "PUBKEY-URL", 0x5F50 }, - { "CHV-STATUS-1", 0x00C4, 1 }, - { "CA-FPR-1", 0x00CA }, - { "CA-FPR-2", 0x00CB }, - { "CA-FPR-3", 0x00CC }, - { NULL, 0 } - }; - - - for (idx=0; table[idx].name && strcmp (table[idx].name, name); idx++) - ; - if (!table[idx].name) - return gpg_error (GPG_ERR_INV_NAME); - - rc = verify_chv3 (app, pincb, pincb_arg); - if (rc) - return rc; - - /* Flush the cache before writing it, so that the next get operation - will reread the data from the card and thus get synced in case of - errors (e.g. data truncated by the card). */ - flush_cache_item (app, table[idx].tag); - rc = iso7816_put_data (app->slot, table[idx].tag, value, valuelen); - if (rc) - log_error ("failed to set `%s': %s\n", table[idx].name, gpg_strerror (rc)); - - if (table[idx].special == 1) - app->force_chv1 = (valuelen && *value == 0); - - return rc; -} - - -/* Handle the PASSWD command. */ -static int -do_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc = 0; - int chvno = atoi (chvnostr); - char *pinvalue; - - if (reset_mode && chvno == 3) - { - rc = gpg_error (GPG_ERR_INV_ID); - goto leave; - } - else if (reset_mode || chvno == 3) - { - /* we always require that the PIN is entered. */ - app->did_chv3 = 0; - rc = verify_chv3 (app, pincb, pincb_arg); - if (rc) - goto leave; - } - else if (chvno == 1 || chvno == 2) - { - /* CHV1 and CVH2 should always have the same value, thus we - enforce it here. */ - int save_force = app->force_chv1; - - app->force_chv1 = 0; - app->did_chv1 = 0; - app->did_chv2 = 0; - rc = verify_chv2 (app, pincb, pincb_arg); - app->force_chv1 = save_force; - if (rc) - goto leave; - } - else - { - rc = gpg_error (GPG_ERR_INV_ID); - goto leave; - } - - if (chvno == 3) - app->did_chv3 = 0; - else - app->did_chv1 = app->did_chv2 = 0; - - rc = pincb (pincb_arg, chvno == 3? "New Admin PIN" : "New PIN", &pinvalue); - if (rc) - { - log_error ("error getting new PIN: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (reset_mode) - { - rc = iso7816_reset_retry_counter (app->slot, 0x81, - pinvalue, strlen (pinvalue)); - if (!rc) - rc = iso7816_reset_retry_counter (app->slot, 0x82, - pinvalue, strlen (pinvalue)); - } - else - { - if (chvno == 1 || chvno == 2) - { - rc = iso7816_change_reference_data (app->slot, 0x81, NULL, 0, - pinvalue, strlen (pinvalue)); - if (!rc) - rc = iso7816_change_reference_data (app->slot, 0x82, NULL, 0, - pinvalue, strlen (pinvalue)); - } - else - rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, NULL, 0, - pinvalue, strlen (pinvalue)); - } - xfree (pinvalue); - if (rc) - flush_cache_after_error (app); - - leave: - return rc; -} - - - -/* Handle the GENKEY command. */ -static int -do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc; - int i; - char numbuf[30]; - unsigned char fprbuf[20]; - const unsigned char *fpr; - const unsigned char *keydata, *m, *e; - unsigned char *buffer; - size_t buflen, keydatalen, n, mlen, elen; - time_t created_at; - int keyno = atoi (keynostr); - int force = (flags & 1); - time_t start_at; - - if (keyno < 1 || keyno > 3) - return gpg_error (GPG_ERR_INV_ID); - keyno--; - - /* We flush the cache to increase the traffic before a key - generation. This _might_ help a card to gather more entropy. */ - flush_cache (app); - - rc = iso7816_get_data (app->slot, 0x006E, &buffer, &buflen); - if (rc) - { - log_error ("error reading application data\n"); - return gpg_error (GPG_ERR_GENERAL); - } - fpr = find_tlv (buffer, buflen, 0x00C5, &n); - if (!fpr || n != 60) - { - rc = gpg_error (GPG_ERR_GENERAL); - log_error ("error reading fingerprint DO\n"); - goto leave; - } - fpr += 20*keyno; - for (i=0; i < 20 && !fpr[i]; i++) - ; - if (i!=20 && !force) - { - rc = gpg_error (GPG_ERR_EEXIST); - log_error ("key already exists\n"); - goto leave; - } - else if (i!=20) - log_info ("existing key will be replaced\n"); - else - log_info ("generating new key\n"); - - - rc = verify_chv3 (app, pincb, pincb_arg); - if (rc) - goto leave; - - xfree (buffer); buffer = NULL; - -#if 1 - log_info ("please wait while key is being generated ...\n"); - start_at = time (NULL); - rc = iso7816_generate_keypair -#else -#warning key generation temporary replaced by reading an existing key. - rc = iso7816_read_public_key -#endif - (app->slot, - keyno == 0? "\xB6" : - keyno == 1? "\xB8" : "\xA4", - 2, - &buffer, &buflen); - if (rc) - { - rc = gpg_error (GPG_ERR_CARD); - log_error ("generating key failed\n"); - goto leave; - } - log_info ("key generation completed (%d seconds)\n", - (int)(time (NULL) - start_at)); - keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen); - if (!keydata) - { - rc = gpg_error (GPG_ERR_CARD); - log_error ("response does not contain the public key data\n"); - goto leave; - } - - m = find_tlv (keydata, keydatalen, 0x0081, &mlen); - if (!m) - { - rc = gpg_error (GPG_ERR_CARD); - log_error ("response does not contain the RSA modulus\n"); - goto leave; - } -/* log_printhex ("RSA n:", m, mlen); */ - send_key_data (ctrl, "n", m, mlen); - - e = find_tlv (keydata, keydatalen, 0x0082, &elen); - if (!e) - { - rc = gpg_error (GPG_ERR_CARD); - log_error ("response does not contain the RSA public exponent\n"); - goto leave; - } -/* log_printhex ("RSA e:", e, elen); */ - send_key_data (ctrl, "e", e, elen); - - created_at = gnupg_get_time (); - sprintf (numbuf, "%lu", (unsigned long)created_at); - send_status_info (ctrl, "KEY-CREATED-AT", - numbuf, (size_t)strlen(numbuf), NULL, 0); - - rc = store_fpr (app->slot, keyno, (u32)created_at, - m, mlen, e, elen, fprbuf, app->card_version); - if (rc) - goto leave; - send_fpr_if_not_null (ctrl, "KEY-FPR", -1, fprbuf); - - - leave: - xfree (buffer); - return rc; -} - - -static unsigned long -convert_sig_counter_value (const unsigned char *value, size_t valuelen) -{ - unsigned long ul; - - if (valuelen == 3 ) - ul = (value[0] << 16) | (value[1] << 8) | value[2]; - else - { - log_error ("invalid structure of OpenPGP card (DO 0x93)\n"); - ul = 0; - } - return ul; -} - -static unsigned long -get_sig_counter (APP app) -{ - void *relptr; - unsigned char *value; - size_t valuelen; - unsigned long ul; - - relptr = get_one_do (app, 0x0093, &value, &valuelen); - if (!relptr) - return 0; - ul = convert_sig_counter_value (value, valuelen); - xfree (relptr); - return ul; -} - -static int -compare_fingerprint (APP app, int keyno, unsigned char *sha1fpr) -{ - const unsigned char *fpr; - unsigned char *buffer; - size_t buflen, n; - int rc, i; - - assert (keyno >= 1 && keyno <= 3); - - rc = get_cached_data (app, 0x006E, &buffer, &buflen); - if (rc) - { - log_error ("error reading application data\n"); - return gpg_error (GPG_ERR_GENERAL); - } - fpr = find_tlv (buffer, buflen, 0x00C5, &n); - if (!fpr || n != 60) - { - xfree (buffer); - log_error ("error reading fingerprint DO\n"); - return gpg_error (GPG_ERR_GENERAL); - } - fpr += (keyno-1)*20; - for (i=0; i < 20; i++) - if (sha1fpr[i] != fpr[i]) - { - xfree (buffer); - return gpg_error (GPG_ERR_WRONG_SECKEY); - } - xfree (buffer); - return 0; -} - - - /* If a fingerprint has been specified check it against the one on - the card. This is allows for a meaningful error message in case - the key on the card has been replaced but the shadow information - known to gpg was not updated. If there is no fingerprint we - assume that this is okay. */ -static int -check_against_given_fingerprint (APP app, const char *fpr, int keyno) -{ - unsigned char tmp[20]; - const char *s; - int n; - - for (s=fpr, n=0; hexdigitp (s); s++, n++) - ; - if (n != 40) - return gpg_error (GPG_ERR_INV_ID); - else if (!*s) - ; /* okay */ - else - return gpg_error (GPG_ERR_INV_ID); - - for (s=fpr, n=0; n < 20; s += 2, n++) - tmp[n] = xtoi_2 (s); - return compare_fingerprint (app, keyno, tmp); -} - - - -/* Compute a digital signature on INDATA which is expected to be the - raw message digest. For this application the KEYIDSTR consists of - the serialnumber and the fingerprint delimited by a slash. - - Note that this fucntion may return the error code - GPG_ERR_WRONG_CARD to indicate that the card currently present does - not match the one required for the requested action (e.g. the - serial number does not match). */ -static int -do_sign (APP app, const char *keyidstr, int hashalgo, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, - 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; - static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, - 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; - int rc; - unsigned char data[35]; - unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */ - const char *s; - int n; - const char *fpr = NULL; - unsigned long sigcount; - - if (!keyidstr || !*keyidstr) - return gpg_error (GPG_ERR_INV_VALUE); - if (indatalen != 20) - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check whether an OpenPGP card of any version has been requested. */ - if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12)) - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; hexdigitp (s); s++, n++) - ; - if (n != 32) - return gpg_error (GPG_ERR_INV_ID); - else if (!*s) - ; /* no fingerprint given: we allow this for now. */ - else if (*s == '/') - fpr = s + 1; - else - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; n < 16; s += 2, n++) - tmp_sn[n] = xtoi_2 (s); - - if (app->serialnolen != 16) - return gpg_error (GPG_ERR_INV_CARD); - if (memcmp (app->serialno, tmp_sn, 16)) - return gpg_error (GPG_ERR_WRONG_CARD); - - /* If a fingerprint has been specified check it against the one on - the card. This is allows for a meaningful error message in case - the key on the card has been replaced but the shadow information - known to gpg was not updated. If there is no fingerprint, gpg - will detect a bogus signature anyway due to the - verify-after-signing feature. */ - rc = fpr? check_against_given_fingerprint (app, fpr, 1) : 0; - if (rc) - return rc; - - if (hashalgo == GCRY_MD_SHA1) - memcpy (data, sha1_prefix, 15); - else if (hashalgo == GCRY_MD_RMD160) - memcpy (data, rmd160_prefix, 15); - else - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - memcpy (data+15, indata, indatalen); - - sigcount = get_sig_counter (app); - log_info ("signatures created so far: %lu\n", sigcount); - - if (!app->did_chv1 || app->force_chv1 ) - { - char *pinvalue; - - { - char *prompt; - if (asprintf (&prompt, "PIN [sigs done: %lu]", sigcount) < 0) - return gpg_error_from_errno (errno); - rc = pincb (pincb_arg, prompt, &pinvalue); - free (prompt); - } - if (rc) - { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); - return rc; - } - - if (strlen (pinvalue) < 6) - { - log_error ("prassphrase (CHV1) is too short; minimum length is 6\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - - rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); - if (rc) - { - log_error ("verify CHV1 failed\n"); - xfree (pinvalue); - flush_cache_after_error (app); - return rc; - } - app->did_chv1 = 1; - if (!app->did_chv2) - { - /* We should also verify CHV2. */ - rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue)); - if (gpg_err_code (rc) == GPG_ERR_BAD_PIN) - rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); - if (rc) - { - log_error ("verify CHV2 failed\n"); - xfree (pinvalue); - flush_cache_after_error (app); - return rc; - } - app->did_chv2 = 1; - } - xfree (pinvalue); - } - - rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen); - return rc; -} - -/* Compute a digital signature using the INTERNAL AUTHENTICATE command - on INDATA which is expected to be the raw message digest. For this - application the KEYIDSTR consists of the serialnumber and the - fingerprint delimited by a slash. - - Note that this fucntion may return the error code - GPG_ERR_WRONG_CARD to indicate that the card currently present does - not match the one required for the requested action (e.g. the - serial number does not match). */ -static int -do_auth (APP app, const char *keyidstr, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */ - const char *s; - int n; - const char *fpr = NULL; - - if (!keyidstr || !*keyidstr) - return gpg_error (GPG_ERR_INV_VALUE); - if (indatalen > 50) /* For a 1024 bit key. */ - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check whether an OpenPGP card of any version has been requested. */ - if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12)) - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; hexdigitp (s); s++, n++) - ; - if (n != 32) - return gpg_error (GPG_ERR_INV_ID); - else if (!*s) - ; /* no fingerprint given: we allow this for now. */ - else if (*s == '/') - fpr = s + 1; - else - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; n < 16; s += 2, n++) - tmp_sn[n] = xtoi_2 (s); - - if (app->serialnolen != 16) - return gpg_error (GPG_ERR_INV_CARD); - if (memcmp (app->serialno, tmp_sn, 16)) - return gpg_error (GPG_ERR_WRONG_CARD); - - /* If a fingerprint has been specified check it against the one on - the card. This is allows for a meaningful error message in case - the key on the card has been replaced but the shadow information - known to gpg was not updated. If there is no fingerprint, gpg - will detect a bogus signature anyway due to the - verify-after-signing feature. */ - rc = fpr? check_against_given_fingerprint (app, fpr, 3) : 0; - if (rc) - return rc; - - rc = verify_chv2 (app, pincb, pincb_arg); - if (!rc) - rc = iso7816_internal_authenticate (app->slot, indata, indatalen, - outdata, outdatalen); - return rc; -} - - -static int -do_decipher (APP app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */ - const char *s; - int n; - const char *fpr = NULL; - - if (!keyidstr || !*keyidstr || !indatalen) - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check whether an OpenPGP card of any version has been requested. */ - if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12)) - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; hexdigitp (s); s++, n++) - ; - if (n != 32) - return gpg_error (GPG_ERR_INV_ID); - else if (!*s) - ; /* no fingerprint given: we allow this for now. */ - else if (*s == '/') - fpr = s + 1; - else - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; n < 16; s += 2, n++) - tmp_sn[n] = xtoi_2 (s); - - if (app->serialnolen != 16) - return gpg_error (GPG_ERR_INV_CARD); - if (memcmp (app->serialno, tmp_sn, 16)) - return gpg_error (GPG_ERR_WRONG_CARD); - - /* If a fingerprint has been specified check it against the one on - the card. This is allows for a meaningful error message in case - the key on the card has been replaced but the shadow information - known to gpg was not updated. If there is no fingerprint, the - decryption will won't produce the right plaintext anyway. */ - rc = fpr? check_against_given_fingerprint (app, fpr, 2) : 0; - if (rc) - return rc; - - rc = verify_chv2 (app, pincb, pincb_arg); - if (!rc) - rc = iso7816_decipher (app->slot, indata, indatalen, 0, - outdata, outdatalen); - return rc; -} - - -/* Perform a simple verify operation for CHV1 and CHV2, so that - further operations won't ask for CHV2 and it is possible to do a - cheap check on the PIN: If there is something wrong with the PIN - entry system, only the regular CHV will get blocked and not the - dangerous CHV3. KEYIDSTR is the usual card's serial number; an - optional fingerprint part will be ignored. */ -static int -do_check_pin (APP app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg) -{ - unsigned char tmp_sn[20]; - const char *s; - int n; - - if (!keyidstr || !*keyidstr) - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check whether an OpenPGP card of any version has been requested. */ - if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12)) - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; hexdigitp (s); s++, n++) - ; - if (n != 32) - return gpg_error (GPG_ERR_INV_ID); - else if (!*s) - ; /* No fingerprint given: we allow this for now. */ - else if (*s == '/') - ; /* We ignore a fingerprint. */ - else - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; n < 16; s += 2, n++) - tmp_sn[n] = xtoi_2 (s); - - if (app->serialnolen != 16) - return gpg_error (GPG_ERR_INV_CARD); - if (memcmp (app->serialno, tmp_sn, 16)) - return gpg_error (GPG_ERR_WRONG_CARD); - /* Yes, there is a race conditions: The user might pull the card - right here and we won't notice that. However this is not a - problem and the check above is merely for a graceful failure - between operations. */ - - return verify_chv2 (app, pincb, pincb_arg); -} - - - - -/* Select the OpenPGP application on the card in SLOT. This function - must be used before any other OpenPGP application functions. */ -int -app_select_openpgp (APP app) -{ - static char const aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 }; - int slot = app->slot; - int rc; - unsigned char *buffer; - size_t buflen; - void *relptr; - - rc = iso7816_select_application (slot, aid, sizeof aid); - if (!rc) - { - app->apptype = "OPENPGP"; - - app->did_chv1 = 0; - app->did_chv2 = 0; - app->did_chv3 = 0; - - /* The OpenPGP card returns the serial number as part of the - AID; because we prefer to use OpenPGP serial numbers, we - replace a possibly already set one from a EF.GDO with this - one. Note, that for current OpenPGP cards, no EF.GDO exists - and thus it won't matter at all. */ - rc = iso7816_get_data (slot, 0x004F, &buffer, &buflen); - if (rc) - goto leave; - if (opt.verbose) - { - log_info ("got AID: "); - log_printhex ("", buffer, buflen); - } - - app->card_version = buffer[6] << 8; - app->card_version |= buffer[7]; - xfree (app->serialno); - app->serialno = buffer; - app->serialnolen = buflen; - buffer = NULL; - - relptr = get_one_do (app, 0x00C4, &buffer, &buflen); - if (!relptr) - { - log_error ("can't access CHV Status Bytes - invalid OpenPGP card?\n"); - goto leave; - } - app->force_chv1 = (buflen && *buffer == 0); - xfree (relptr); - - if (opt.verbose > 1) - dump_all_do (slot); - - app->fnc.deinit = do_deinit; - app->fnc.learn_status = do_learn_status; - app->fnc.readcert = NULL; - app->fnc.getattr = do_getattr; - app->fnc.setattr = do_setattr; - app->fnc.genkey = do_genkey; - app->fnc.sign = do_sign; - app->fnc.auth = do_auth; - app->fnc.decipher = do_decipher; - app->fnc.change_pin = do_change_pin; - app->fnc.check_pin = do_check_pin; - } - -leave: - return rc; -} - - - -/* This function is a hack to retrieve essential information about the - card to be displayed by simple tools. It mostly resembles what the - LEARN command returns. All parameters return allocated strings or - buffers or NULL if the data object is not available. All returned - values are sanitized. */ -int -app_openpgp_cardinfo (APP app, - char **serialno, - char **disp_name, - char **pubkey_url, - unsigned char **fpr1, - unsigned char **fpr2, - unsigned char **fpr3) -{ - int rc; - void *relptr; - unsigned char *value; - size_t valuelen; - - if (serialno) - { - time_t dummy; - - *serialno = NULL; - rc = app_get_serial_and_stamp (app, serialno, &dummy); - if (rc) - { - log_error ("error getting serial number: %s\n", gpg_strerror (rc)); - return rc; - } - } - - if (disp_name) - { - *disp_name = NULL; - relptr = get_one_do (app, 0x005B, &value, &valuelen); - if (relptr) - { - *disp_name = make_printable_string (value, valuelen, 0); - xfree (relptr); - } - } - - if (pubkey_url) - { - *pubkey_url = NULL; - relptr = get_one_do (app, 0x5F50, &value, &valuelen); - if (relptr) - { - *pubkey_url = make_printable_string (value, valuelen, 0); - xfree (relptr); - } - } - - if (fpr1) - *fpr1 = NULL; - if (fpr2) - *fpr2 = NULL; - if (fpr3) - *fpr3 = NULL; - relptr = get_one_do (app, 0x00C5, &value, &valuelen); - if (relptr && valuelen >= 60) - { - if (fpr1) - { - *fpr1 = xmalloc (20); - memcpy (*fpr1, value + 0, 20); - } - if (fpr2) - { - *fpr2 = xmalloc (20); - memcpy (*fpr2, value + 20, 20); - } - if (fpr3) - { - *fpr3 = xmalloc (20); - memcpy (*fpr3, value + 40, 20); - } - } - xfree (relptr); - - return 0; -} - - - -/* This function is currently only used by the sc-copykeys program to - store a key on the smartcard. APP ist the application handle, - KEYNO is the number of the key and PINCB, PINCB_ARG are used to ask - for the SO PIN. TEMPLATE and TEMPLATE_LEN describe a buffer with - the key template to store. CREATED_AT is the timestamp used to - create the fingerprint. M, MLEN is the RSA modulus and E, ELEN the - RSA public exponent. This function silently overwrites an existing - key.*/ -int -app_openpgp_storekey (APP app, int keyno, - unsigned char *template, size_t template_len, - time_t created_at, - const unsigned char *m, size_t mlen, - const unsigned char *e, size_t elen, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc; - unsigned char fprbuf[20]; - - if (keyno < 1 || keyno > 3) - return gpg_error (GPG_ERR_INV_ID); - keyno--; - - rc = verify_chv3 (app, pincb, pincb_arg); - if (rc) - goto leave; - - - rc = iso7816_put_data (app->slot, - (app->card_version > 0x0007? 0xE0 : 0xE9) + keyno, - template, template_len); - if (rc) - { - log_error ("failed to store the key: rc=%s\n", gpg_strerror (rc)); - rc = gpg_error (GPG_ERR_CARD); - goto leave; - } - -/* log_printhex ("RSA n:", m, mlen); */ -/* log_printhex ("RSA e:", e, elen); */ - - rc = store_fpr (app->slot, keyno, (u32)created_at, - m, mlen, e, elen, fprbuf, app->card_version); - - leave: - return rc; -} - - -/* Utility function for external tools: Read the public RSA key at - KEYNO and return modulus and exponent in (M,MLEN) and (E,ELEN). */ -int -app_openpgp_readkey (APP app, int keyno, unsigned char **m, size_t *mlen, - unsigned char **e, size_t *elen) -{ - int rc; - const unsigned char *keydata, *a; - unsigned char *buffer; - size_t buflen, keydatalen, alen; - - *m = NULL; - *e = NULL; - - if (keyno < 1 || keyno > 3) - return gpg_error (GPG_ERR_INV_ID); - keyno--; - - rc = iso7816_read_public_key(app->slot, - keyno == 0? "\xB6" : - keyno == 1? "\xB8" : "\xA4", - 2, - &buffer, &buflen); - if (rc) - { - rc = gpg_error (GPG_ERR_CARD); - log_error ("reading key failed\n"); - goto leave; - } - - keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen); - if (!keydata) - { - log_error ("response does not contain the public key data\n"); - rc = gpg_error (GPG_ERR_CARD); - goto leave; - } - - a = find_tlv (keydata, keydatalen, 0x0081, &alen); - if (!a) - { - log_error ("response does not contain the RSA modulus\n"); - rc = gpg_error (GPG_ERR_CARD); - goto leave; - } - *mlen = alen; - *m = xmalloc (alen); - memcpy (*m, a, alen); - - a = find_tlv (keydata, keydatalen, 0x0082, &alen); - if (!e) - { - log_error ("response does not contain the RSA public exponent\n"); - rc = gpg_error (GPG_ERR_CARD); - goto leave; - } - *elen = alen; - *e = xmalloc (alen); - memcpy (*e, a, alen); - - leave: - xfree (buffer); - if (rc) - { - xfree (*m); *m = NULL; - xfree (*e); *e = NULL; - } - return rc; -} diff --git a/scd/app.c b/scd/app.c deleted file mode 100644 index a9a9243eb..000000000 --- a/scd/app.c +++ /dev/null @@ -1,391 +0,0 @@ -/* app.c - Application selection. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - - -#include "scdaemon.h" -#include "app-common.h" -#include "apdu.h" -#include "iso7816.h" -#include "tlv.h" - - -/* If called with NAME as NULL, select the best fitting application - and return a context; otherwise select the application with NAME - and return a context. SLOT identifies the reader device. Returns - NULL if no application was found or no card is present. */ -APP -select_application (ctrl_t ctrl, int slot, const char *name) -{ - int rc; - APP app; - unsigned char *result = NULL; - size_t resultlen; - - app = xtrycalloc (1, sizeof *app); - if (!app) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_info ("error allocating context: %s\n", gpg_strerror (rc)); - return NULL; - } - app->slot = slot; - - /* Fixme: We should now first check whether a card is at all - present. */ - - /* Try to read the GDO file first to get a default serial number. */ - rc = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL); - if (!rc) - rc = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL); - if (!rc) - rc = iso7816_read_binary (slot, 0, 0, &result, &resultlen); - if (!rc) - { - size_t n; - const unsigned char *p; - - p = find_tlv (result, resultlen, 0x5A, &n); - if (p && n && n >= (resultlen - (p - result))) - { - /* The GDO file is pretty short, thus we simply reuse it for - storing the serial number. */ - memmove (result, p, n); - app->serialno = result; - app->serialnolen = n; - } - else - xfree (result); - result = NULL; - } - - - rc = gpg_error (GPG_ERR_NOT_FOUND); - - if (!name || !strcmp (name, "openpgp")) - rc = app_select_openpgp (app); - if (rc && (!name || !strcmp (name, "nks"))) - rc = app_select_nks (app); - if (rc && (!name || !strcmp (name, "dinsig"))) - rc = app_select_dinsig (app); - if (rc && name) - rc = gpg_error (GPG_ERR_NOT_SUPPORTED); - - if (rc) - { - if (name) - log_info ("can't select application `%s': %s\n", - name, gpg_strerror (rc)); - else - log_info ("no supported card application found: %s\n", - gpg_strerror (rc)); - xfree (app); - return NULL; - } - - app->initialized = 1; - return app; -} - - -void -release_application (app_t app) -{ - if (!app) - return; - - if (app->fnc.deinit) - { - app->fnc.deinit (app); - app->fnc.deinit = NULL; - } - - xfree (app->serialno); - xfree (app); -} - - - -/* Retrieve the serial number and the time of the last update of the - card. The serial number is returned as a malloced string (hex - encoded) in SERIAL and the time of update is returned in STAMP. If - no update time is available the returned value is 0. Caller must - free SERIAL unless the function returns an error. If STAMP is not - of interest, NULL may be passed. */ -int -app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp) -{ - unsigned char *buf, *p; - int i; - - if (!app || !serial) - return gpg_error (GPG_ERR_INV_VALUE); - - *serial = NULL; - if (stamp) - *stamp = 0; /* not available */ - - buf = xtrymalloc (app->serialnolen * 2 + 1); - if (!buf) - return gpg_error_from_errno (errno); - for (p=buf, i=0; i < app->serialnolen; p +=2, i++) - sprintf (p, "%02X", app->serialno[i]); - *p = 0; - *serial = buf; - return 0; -} - - -/* Write out the application specifig status lines for the LEARN - command. */ -int -app_write_learn_status (APP app, CTRL ctrl) -{ - if (!app) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.learn_status) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - if (app->apptype) - send_status_info (ctrl, "APPTYPE", - app->apptype, strlen (app->apptype), NULL, 0); - - return app->fnc.learn_status (app, ctrl); -} - - -/* Read the certificate with id CERTID (as returned by learn_status in - the CERTINFO status lines) and return it in the freshly allocated - buffer put into CERT and the length of the certificate put into - CERTLEN. */ -int -app_readcert (app_t app, const char *certid, - unsigned char **cert, size_t *certlen) -{ - if (!app) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.readcert) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - return app->fnc.readcert (app, certid, cert, certlen); -} - - -/* Perform a GETATTR operation. */ -int -app_getattr (APP app, CTRL ctrl, const char *name) -{ - if (!app || !name || !*name) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.getattr) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - return app->fnc.getattr (app, ctrl, name); -} - -/* Perform a SETATTR operation. */ -int -app_setattr (APP app, const char *name, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const unsigned char *value, size_t valuelen) -{ - if (!app || !name || !*name || !value) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.setattr) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - return app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen); -} - -/* Create the signature and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; it - should return the PIN in an allocated buffer and put it into PIN. */ -int -app_sign (APP app, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - - if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.sign) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = app->fnc.sign (app, keyidstr, hashalgo, - pincb, pincb_arg, - indata, indatalen, - outdata, outdatalen); - if (opt.verbose) - log_info ("operation sign result: %s\n", gpg_strerror (rc)); - return rc; -} - -/* Create the signature using the INTERNAL AUTHENTICATE command and - return the allocated result in OUTDATA. If a PIN is required the - PINCB will be used to ask for the PIN; it should return the PIN in - an allocated buffer and put it into PIN. */ -int -app_auth (APP app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - - if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.auth) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = app->fnc.auth (app, keyidstr, - pincb, pincb_arg, - indata, indatalen, - outdata, outdatalen); - if (opt.verbose) - log_info ("operation auth result: %s\n", gpg_strerror (rc)); - return rc; -} - - -/* Decrypt the data in INDATA and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; it - should return the PIN in an allocated buffer and put it into PIN. */ -int -app_decipher (APP app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - - if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.decipher) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = app->fnc.decipher (app, keyidstr, - pincb, pincb_arg, - indata, indatalen, - outdata, outdatalen); - if (opt.verbose) - log_info ("operation decipher result: %s\n", gpg_strerror (rc)); - return rc; -} - - -/* Perform a SETATTR operation. */ -int -app_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc; - - if (!app || !keynostr || !*keynostr || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.genkey) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = app->fnc.genkey (app, ctrl, keynostr, flags, pincb, pincb_arg); - if (opt.verbose) - log_info ("operation genkey result: %s\n", gpg_strerror (rc)); - return rc; -} - - -/* Perform a GET CHALLENGE operation. This fucntion is special as it - directly accesses the card without any application specific - wrapper. */ -int -app_get_challenge (APP app, size_t nbytes, unsigned char *buffer) -{ - if (!app || !nbytes || !buffer) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - return iso7816_get_challenge (app->slot, nbytes, buffer); -} - - - -/* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation. */ -int -app_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc; - - if (!app || !chvnostr || !*chvnostr || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.change_pin) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode, pincb, pincb_arg); - if (opt.verbose) - log_info ("operation change_pin result: %s\n", gpg_strerror (rc)); - return rc; -} - - -/* Perform a VERIFY operation without doing anything lese. This may - be used to initialze a the PION cache for long lasting other - operations. Its use is highly application dependent. */ -int -app_check_pin (APP app, const char *keyidstr, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc; - - if (!app || !keyidstr || !*keyidstr || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.check_pin) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg); - if (opt.verbose) - log_info ("operation check_pin result: %s\n", gpg_strerror (rc)); - return rc; -} - diff --git a/scd/atr.c b/scd/atr.c deleted file mode 100644 index 6475e83f8..000000000 --- a/scd/atr.c +++ /dev/null @@ -1,287 +0,0 @@ -/* atr.c - ISO 7816 ATR fucntions - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "scdaemon.h" -#include "apdu.h" -#include "atr.h" -#include "dynload.h" - -static int const fi_table[16] = { 0, 372, 558, 744, 1116,1488, 1860, -1, - -1, 512, 768, 1024, 1536, 2048, -1, -1 }; -static int const di_table[16] = { -1, 1, 2, 4, 8, 16, -1, -1, - 0, -1, -2, -4, -8, -16, -32, -64}; - - -/* Dump the ATR of the card at SLOT in a human readable format to - stream FP. */ -int -atr_dump (int slot, FILE *fp) -{ - unsigned char *atrbuffer, *atr; - size_t atrlen; - int have_ta, have_tb, have_tc, have_td; - int n_historical; - int idx, val; - unsigned char chksum; - - atr = atrbuffer = apdu_get_atr (slot, &atrlen); - if (!atr) - return gpg_error (GPG_ERR_GENERAL); - - fprintf (fp, "Info on ATR of length %u at slot %d\n", - (unsigned int)atrlen, slot); - if (!atrlen) - { - fprintf (fp, "error: empty ATR\n"); - goto bailout; - } - - - if (*atr == 0x3b) - fputs ("direct convention\n", fp); - else if (*atr == 0x3f) - fputs ("inverse convention\n", fp); - else - fprintf (fp,"error: invalid TS character 0x%02x\n", *atr); - if (!--atrlen) - goto bailout; - atr++; - - chksum = *atr; - for (idx=1; idx < atrlen-1; idx++) - chksum ^= atr[idx]; - - have_ta = !!(*atr & 0x10); - have_tb = !!(*atr & 0x20); - have_tc = !!(*atr & 0x40); - have_td = !!(*atr & 0x80); - n_historical = (*atr & 0x0f); - fprintf (fp, "%d historical characters indicated\n", n_historical); - - if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen) - fputs ("error: ATR shorter than indicated by format character\n", fp); - if (!--atrlen) - goto bailout; - atr++; - - if (have_ta) - { - fputs ("TA1: F=", fp); - val = fi_table[(*atr >> 4) & 0x0f]; - if (!val) - fputs ("internal clock", fp); - else if (val == -1) - fputs ("RFU", fp); - else - fprintf (fp, "%d", val); - fputs (" D=", fp); - val = di_table[*atr & 0x0f]; - if (!val) - fputs ("[impossible value]\n", fp); - else if (val == -1) - fputs ("RFU\n", fp); - else if (val < 0 ) - fprintf (fp, "1/%d\n", val); - else - fprintf (fp, "%d\n", val); - - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_tb) - { - fprintf (fp, "TB1: II=%d PI1=%d%s\n", (*atr >> 5) & 3, *atr & 0x1f, - (*atr & 0x80)? " [high bit not cleared]":""); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_tc) - { - if (*atr == 255) - fputs ("TC1: guard time shortened to 1 etu\n", fp); - else - fprintf (fp, "TC1: (extra guard time) N=%d\n", *atr); - - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_td) - { - have_ta = !!(*atr & 0x10); - have_tb = !!(*atr & 0x20); - have_tc = !!(*atr & 0x40); - have_td = !!(*atr & 0x80); - fprintf (fp, "TD1: protocol T%d supported\n", *atr & 0x0f); - - if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen) - fputs ("error: ATR shorter than indicated by format character\n", fp); - - if (!--atrlen) - goto bailout; - atr++; - } - else - have_ta = have_tb = have_tc = have_td = 0; - - if (have_ta) - { - fprintf (fp, "TA2: (PTS) %stoggle, %splicit, T=%02X\n", - (*atr & 0x80)? "no-":"", - (*atr & 0x10)? "im": "ex", - (*atr & 0x0f)); - if ((*atr & 0x60)) - fprintf (fp, "note: reserved bits are set (TA2=0x%02X)\n", *atr); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_tb) - { - fprintf (fp, "TB2: PI2=%d\n", *atr); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_tc) - { - fprintf (fp, "TC2: PWI=%d\n", *atr); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_td) - { - have_ta = !!(*atr & 0x10); - have_tb = !!(*atr & 0x20); - have_tc = !!(*atr & 0x40); - have_td = !!(*atr & 0x80); - fprintf (fp, "TD2: protocol T%d supported\n", *atr & 0x0f); - - if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen) - fputs ("error: ATR shorter than indicated by format character\n", fp); - - if (!--atrlen) - goto bailout; - atr++; - } - else - have_ta = have_tb = have_tc = have_td = 0; - - for (idx = 3; have_ta || have_tb || have_tc || have_td; idx++) - { - if (have_ta) - { - fprintf (fp, "TA%d: IFSC=%d\n", idx, *atr); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_tb) - { - fprintf (fp, "TB%d: BWI=%d CWI=%d\n", - idx, (*atr >> 4) & 0x0f, *atr & 0x0f); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_tc) - { - fprintf (fp, "TC%d: 0x%02X\n", idx, *atr); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_td) - { - have_ta = !!(*atr & 0x10); - have_tb = !!(*atr & 0x20); - have_tc = !!(*atr & 0x40); - have_td = !!(*atr & 0x80); - fprintf (fp, "TD%d: protocol T%d supported\n", idx, *atr & 0x0f); - - if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen) - fputs ("error: ATR shorter than indicated by format character\n", - fp); - - if (!--atrlen) - goto bailout; - atr++; - } - else - have_ta = have_tb = have_tc = have_td = 0; - } - - if (n_historical + 1 > atrlen) - fputs ("error: ATR shorter than required for historical bytes " - "and checksum\n", fp); - - if (n_historical) - { - fputs ("Historical:", fp); - for (; n_historical && atrlen ; n_historical--, atrlen--, atr++) - fprintf (fp, " %02X", *atr); - putchar ('\n'); - } - - if (!atrlen) - fputs ("error: checksum missing\n", fp); - else if (*atr == chksum) - fprintf (fp, "TCK: %02X (good)\n", *atr); - else - fprintf (fp, "TCK: %02X (bad; calculated %02X)\n", *atr, chksum); - - atrlen--; - if (atrlen) - fprintf (fp, "error: %u bytes garbage at end of ATR\n", - (unsigned int)atrlen ); - - bailout: - xfree (atrbuffer); - - return 0; -} - - - - - - - - - diff --git a/scd/atr.h b/scd/atr.h deleted file mode 100644 index 5fdd57457..000000000 --- a/scd/atr.h +++ /dev/null @@ -1,28 +0,0 @@ -/* atr.h - ISO 7816 ATR functions - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef ATR_H -#define ATR_H - -int atr_dump (int slot, FILE *fp); - - - -#endif /*ATR_H*/ diff --git a/scd/card-common.h b/scd/card-common.h deleted file mode 100644 index cefaf120f..000000000 --- a/scd/card-common.h +++ /dev/null @@ -1,73 +0,0 @@ -/* card-common.h - Common declarations for all card types - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef CARD_COMMON_H -#define CARD_COMMON_H - -/* Declaration of private data structure used by card-p15.c */ -struct p15private_s; - - -struct card_ctx_s { - int reader; /* used reader */ - struct sc_context *ctx; - struct sc_card *scard; - struct sc_pkcs15_card *p15card; /* only if there is a pkcs15 application */ - struct p15private_s *p15priv; /* private data used by card-p15.c */ - - struct { - int initialized; /* the card has been initialied and the function - pointers may be used. However for - unsupported operations the particular - function pointer is set to NULL */ - - int (*enum_keypairs) (CARD card, int idx, - unsigned char *keygrip, char **keyid); - int (*enum_certs) (CARD card, int idx, char **certid, int *certtype); - int (*read_cert) (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert); - int (*sign) (CARD card, - const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ); - int (*decipher) (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen); - } fnc; - -}; - -/*-- card.c --*/ -gpg_error_t map_sc_err (int rc); -int card_help_get_keygrip (ksba_cert_t cert, unsigned char *array); - -/*-- card-15.c --*/ -void p15_release_private_data (CARD card); - -/* constructors */ -void card_p15_bind (CARD card); -void card_dinsig_bind (CARD card); - - -#endif /*CARD_COMMON_H*/ diff --git a/scd/card-dinsig.c b/scd/card-dinsig.c deleted file mode 100644 index df09bfb57..000000000 --- a/scd/card-dinsig.c +++ /dev/null @@ -1,258 +0,0 @@ -/* card-dinsig.c - German signature law (DINSIG) functions - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* The German signature law and its bylaw (SigG and SigV) is currently - used with an interface specification described in DIN V 66291-1. - The AID to be used is: 'D27600006601'. - - The file IDs for certificates utilize the generic format: - Cxyz - C being the hex digit 'C' (12). - x being the service indicator: - '0' := SigG conform digital signature. - '1' := entity authentication. - '2' := key encipherment. - '3' := data encipherment. - '4' := key agreement. - other values are reserved for future use. - y being the security environment number using '0' for cards - not supporting a SE number. - z being the certificate type: - '0' := C.CH (base certificate of ard holder) or C.ICC. - '1' .. '7' := C.CH (business or professional certificate - of card holder. - '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA). - 'E' := C.RCA (self certified certificate of the Root-CA). - 'F' := reserved. - - The file IDs used by default are: - '1F00' EF.SSD (security service descriptor). [o,o] - '2F02' EF.GDO (global data objects) [m,m] - 'A000' EF.PROT (signature log). Cyclic file with 20 records of 53 byte. - Read and update after user authentication. [o,o] - 'B000' EF.PK.RCA.DS (public keys of Root-CA). Size is 512b or size - of keys. [m (unless a 'C00E' is present),m] - 'B001' EF.PK.CA.DS (public keys of CAs). Size is 512b or size - of keys. [o,o] - 'C00n' EF.C.CH.DS (digital signature certificate of card holder) - with n := 0 .. 7. Size is 2k or size of cert. Read and - update allowed after user authentication. [m,m] - 'C00m' EF.C.CA.DS (digital signature certificate of CA) - with m := 8 .. E. Size is 1k or size of cert. Read always - allowed, update after uder authentication. [o,o] - 'C100' EF.C.ICC.AUT (AUT certificate of ICC) [o,m] - 'C108' EF.C.CA.AUT (AUT certificate of CA) [o,m] - 'D000' EF.DM (display message) [-,m] - - The letters in brackets indicate optional or mandatory files: The - first for card terminals under full control and the second for - "business" card terminals. - - FIXME: Needs a lot more explanation. - -*/ - - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#ifdef HAVE_OPENSC -#include <opensc/pkcs15.h> -#include "scdaemon.h" -#include <ksba.h> - -#include "card-common.h" - -static int dinsig_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert); - - - -/* See card.c for interface description. Frankly we don't do any real - enumeration but just check whether the well know files are - available. */ -static int -dinsig_enum_keypairs (CARD card, int idx, - unsigned char *keygrip, char **keyid) -{ - int rc; - unsigned char *buf; - size_t buflen; - ksba_cert_t cert; - - /* fixme: We should locate the application via the EF(DIR) and not - assume a Netkey card */ - if (!idx) - rc = dinsig_read_cert (card, "DINSIG-DF01.C000", &buf, &buflen); - else if (idx == 1) - rc = dinsig_read_cert (card, "DINSIG-DF01.C200", &buf, &buflen); - else - rc = -1; - if (rc) - return rc; - - rc = ksba_cert_new (&cert); - if (rc) - { - xfree (buf); - return rc; - } - - rc = ksba_cert_init_from_mem (cert, buf, buflen); - xfree (buf); - if (rc) - { - log_error ("failed to parse the certificate at idx %d: %s\n", - idx, gpg_strerror (rc)); - ksba_cert_release (cert); - return rc; - } - if (card_help_get_keygrip (cert, keygrip)) - { - log_error ("failed to calculate the keygrip at index %d\n", idx); - ksba_cert_release (cert); - return gpg_error (GPG_ERR_CARD); - } - ksba_cert_release (cert); - - /* return the iD */ - if (keyid) - { - *keyid = xtrymalloc (17); - if (!*keyid) - return gpg_error (gpg_err_code_from_errno (errno)); - if (!idx) - strcpy (*keyid, "DINSIG-DF01.C000"); - else - strcpy (*keyid, "DINSIG-DF01.C200"); - } - - return 0; -} - - - -/* See card.c for interface description */ -static int -dinsig_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert) -{ - int rc; - struct sc_path path; - struct sc_file *file; - unsigned char *buf; - int buflen; - - if (!strcmp (certidstr, "DINSIG-DF01.C000")) - sc_format_path ("3F00DF01C000", &path); - else if (!strcmp (certidstr, "DINSIG-DF01.C200")) - sc_format_path ("3F00DF01C200", &path); - else - return gpg_error (GPG_ERR_INV_ID); - - rc = sc_select_file (card->scard, &path, &file); - if (rc) - { - log_error ("sc_select_file failed: %s\n", sc_strerror (rc)); - return map_sc_err (rc); - } - if (file->type != SC_FILE_TYPE_WORKING_EF - || file->ef_structure != SC_FILE_EF_TRANSPARENT) - { - log_error ("wrong type or structure of certificate EF\n"); - sc_file_free (file); - return gpg_error (GPG_ERR_CARD); - } - if (file->size < 20) /* check against a somewhat arbitrary length */ - { - log_error ("certificate EF too short\n"); - sc_file_free (file); - return gpg_error (GPG_ERR_CARD); - } - buf = xtrymalloc (file->size); - if (!buf) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - sc_file_free (file); - return tmperr; - } - - rc = sc_read_binary (card->scard, 0, buf, file->size, 0); - if (rc >= 0 && rc != file->size) - { - log_error ("short read on certificate EF\n"); - sc_file_free (file); - xfree (buf); - return gpg_error (GPG_ERR_CARD); - } - sc_file_free (file); - if (rc < 0) - { - log_error ("error reading certificate EF: %s\n", sc_strerror (rc)); - xfree (buf); - return map_sc_err (rc); - } - buflen = rc; - - /* The object is not a plain certificate but wrapped into id-at - userCertificate - fixme: we should check the specs and decided - whether libksba should support it */ - if (buflen > 9 && buf[0] == 0x30 && buf[4] == 6 && buf[5] == 3 - && buf[6] == 0x55 && buf[7] == 4 && buf[8] == 0x24) - { - /* We have to strip the padding. Although this is a good idea - anyway, we have to do it due to a KSBA problem; KSBA does not - work correct when the buffer is larger than the ASN.1 - structure and the certificates here are padded with FF. So - as a workaround we look at the outer structure to get the - size of the entire thing and adjust the buflen. We can only - do this when there is a 2 byte length field */ - size_t seqlen; - if (buf[1] == 0x82) - { - seqlen = ((buf[2] << 8) | buf[3]) + 4; - if (seqlen < buflen) - buflen = seqlen; - } - memmove (buf, buf+9, buflen-9); - buflen -= 9; - } - - *cert = buf; - *ncert = buflen; - return 0; -} - - - - -/* Bind our operations to the card */ -void -card_dinsig_bind (CARD card) -{ - card->fnc.enum_keypairs = dinsig_enum_keypairs; - card->fnc.read_cert = dinsig_read_cert; - -} -#endif /*HAVE_OPENSC*/ diff --git a/scd/card-p15.c b/scd/card-p15.c deleted file mode 100644 index ae3ef148f..000000000 --- a/scd/card-p15.c +++ /dev/null @@ -1,500 +0,0 @@ -/* card-p15.c - PKCS-15 based card access - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#ifdef HAVE_OPENSC -#include <opensc/pkcs15.h> - -#include "scdaemon.h" -#include <ksba.h> -#include "card-common.h" - - -struct p15private_s { - int n_prkey_rsa_objs; - struct sc_pkcs15_object *prkey_rsa_objs[32]; - int n_cert_objs; - struct sc_pkcs15_object *cert_objs[32]; -}; - - -/* Allocate private data. */ -static int -init_private_data (CARD card) -{ - struct p15private_s *priv; - int rc; - - if (card->p15priv) - return 0; /* already done. */ - - priv = xtrycalloc (1, sizeof *priv); - if (!priv) - return gpg_error (gpg_err_code_from_errno (errno)); - - /* OpenSC (0.7.0) is a bit strange in that the get_objects functions - tries to be a bit too clever and implicitly does an enumeration - which eventually leads to the fact that every call to this - fucntion returns one more macthing object. The old code in - p15_enum_keypairs assume that it would alwyas return the same - numer of objects and used this to figure out what the last object - enumerated is. We now do an enum_objects just once and keep it - in the private data. */ - rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA, - priv->prkey_rsa_objs, - DIM (priv->prkey_rsa_objs)); - if (rc < 0) - { - log_error ("private keys enumeration failed: %s\n", sc_strerror (rc)); - xfree (priv); - return gpg_error (GPG_ERR_CARD); - } - priv->n_prkey_rsa_objs = rc; - - /* Read all certificate objects. */ - rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_CERT_X509, - priv->cert_objs, - DIM (priv->cert_objs)); - if (rc < 0) - { - log_error ("private keys enumeration failed: %s\n", sc_strerror (rc)); - xfree (priv); - return gpg_error (GPG_ERR_CARD); - } - priv->n_cert_objs = rc; - - card->p15priv = priv; - return 0; -} - - -/* Release private data used in this module. */ -void -p15_release_private_data (CARD card) -{ - if (!card->p15priv) - return; - xfree (card->p15priv); - card->p15priv = NULL; -} - - - -/* See card.c for interface description */ -static int -p15_enum_keypairs (CARD card, int idx, - unsigned char *keygrip, char **keyid) -{ - int rc; - struct p15private_s *priv; - struct sc_pkcs15_object *tmpobj; - int nobjs; - struct sc_pkcs15_prkey_info *pinfo; - struct sc_pkcs15_cert_info *certinfo; - struct sc_pkcs15_cert *certder; - ksba_cert_t cert; - - rc = init_private_data (card); - if (rc) - return rc; - priv = card->p15priv; - nobjs = priv->n_prkey_rsa_objs; - rc = 0; - if (idx >= nobjs) - return -1; - pinfo = priv->prkey_rsa_objs[idx]->data; - - /* now we need to read the certificate so that we can calculate the - keygrip */ - rc = sc_pkcs15_find_cert_by_id (card->p15card, &pinfo->id, &tmpobj); - if (rc) - { - log_info ("certificate for private key %d not found: %s\n", - idx, sc_strerror (rc)); - /* note, that we return the ID anyway */ - rc = gpg_error (GPG_ERR_MISSING_CERT); - goto return_keyid; - } - certinfo = tmpobj->data; - rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder); - if (rc) - { - log_info ("failed to read certificate for private key %d: %s\n", - idx, sc_strerror (rc)); - return gpg_error (GPG_ERR_CARD); - } - - rc = ksba_cert_new (&cert); - if (rc) - { - sc_pkcs15_free_certificate (certder); - return rc; - } - rc = ksba_cert_init_from_mem (cert, certder->data, certder->data_len); - sc_pkcs15_free_certificate (certder); - if (rc) - { - log_error ("failed to parse the certificate for private key %d: %s\n", - idx, gpg_strerror (rc)); - ksba_cert_release (cert); - return rc; - } - if (card_help_get_keygrip (cert, keygrip)) - { - log_error ("failed to calculate the keygrip of private key %d\n", idx); - ksba_cert_release (cert); - return gpg_error (GPG_ERR_CARD); - } - ksba_cert_release (cert); - - rc = 0; - return_keyid: - if (keyid) - { - char *p; - int i; - - *keyid = p = xtrymalloc (9+pinfo->id.len*2+1); - if (!*keyid) - return gpg_error (gpg_err_code_from_errno (errno)); - p = stpcpy (p, "P15-5015."); - for (i=0; i < pinfo->id.len; i++, p += 2) - sprintf (p, "%02X", pinfo->id.value[i]); - *p = 0; - } - - return rc; -} - -/* See card.c for interface description */ -static int -p15_enum_certs (CARD card, int idx, char **certid, int *type) -{ - int rc; - struct p15private_s *priv; - struct sc_pkcs15_object *obj; - struct sc_pkcs15_cert_info *cinfo; - int nobjs; - - rc = init_private_data (card); - if (rc) - return rc; - priv = card->p15priv; - nobjs = priv->n_cert_objs; - rc = 0; - if (idx >= nobjs) - return -1; - obj = priv->cert_objs[idx]; - cinfo = obj->data; - - if (certid) - { - char *p; - int i; - - *certid = p = xtrymalloc (9+cinfo->id.len*2+1); - if (!*certid) - return gpg_error (gpg_err_code_from_errno (errno)); - p = stpcpy (p, "P15-5015."); - for (i=0; i < cinfo->id.len; i++, p += 2) - sprintf (p, "%02X", cinfo->id.value[i]); - *p = 0; - } - if (type) - { - if (!obj->df) - *type = 0; /* unknown */ - else if (obj->df->type == SC_PKCS15_CDF) - *type = 100; - else if (obj->df->type == SC_PKCS15_CDF_TRUSTED) - *type = 101; - else if (obj->df->type == SC_PKCS15_CDF_USEFUL) - *type = 102; - else - *type = 0; /* error -> unknown */ - } - - return rc; -} - - - -static int -idstr_to_id (const char *idstr, struct sc_pkcs15_id *id) -{ - const char *s; - int n; - - /* For now we only support the standard DF */ - if (strncmp (idstr, "P15-5015.", 9) ) - return gpg_error (GPG_ERR_INV_ID); - for (s=idstr+9, n=0; hexdigitp (s); s++, n++) - ; - if (*s || (n&1)) - return gpg_error (GPG_ERR_INV_ID); /*invalid or odd number of digits*/ - n /= 2; - if (!n || n > SC_PKCS15_MAX_ID_SIZE) - return gpg_error (GPG_ERR_INV_ID); /* empty or too large */ - for (s=idstr+9, n=0; *s; s += 2, n++) - id->value[n] = xtoi_2 (s); - id->len = n; - return 0; -} - - -/* See card.c for interface description */ -static int -p15_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert) -{ - struct sc_pkcs15_object *tmpobj; - struct sc_pkcs15_id certid; - struct sc_pkcs15_cert_info *certinfo; - struct sc_pkcs15_cert *certder; - int rc; - - if (!card || !certidstr || !cert || !ncert) - return gpg_error (GPG_ERR_INV_VALUE); - if (!card->p15card) - return gpg_error (GPG_ERR_NO_PKCS15_APP); - - rc = idstr_to_id (certidstr, &certid); - if (rc) - return rc; - - rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj); - if (rc) - { - log_info ("certificate '%s' not found: %s\n", - certidstr, sc_strerror (rc)); - return -1; - } - certinfo = tmpobj->data; - rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder); - if (rc) - { - log_info ("failed to read certificate '%s': %s\n", - certidstr, sc_strerror (rc)); - return gpg_error (GPG_ERR_CARD); - } - - *cert = xtrymalloc (certder->data_len); - if (!*cert) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - sc_pkcs15_free_certificate (certder); - return tmperr; - } - memcpy (*cert, certder->data, certder->data_len); - *ncert = certder->data_len; - sc_pkcs15_free_certificate (certder); - return 0; -} - - - - - -static int -p15_prepare_key (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, struct sc_pkcs15_object **r_keyobj) -{ - struct sc_pkcs15_id keyid; - struct sc_pkcs15_pin_info *pin; - struct sc_pkcs15_object *keyobj, *pinobj; - char *pinvalue; - int rc; - - rc = idstr_to_id (keyidstr, &keyid); - if (rc) - return rc; - - rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj); - if (rc < 0) - { - log_error ("private key not found: %s\n", sc_strerror(rc)); - return gpg_error (GPG_ERR_NO_SECKEY); - } - - rc = sc_pkcs15_find_pin_by_auth_id (card->p15card, - &keyobj->auth_id, &pinobj); - if (rc) - { - log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc)); - return gpg_error (GPG_ERR_BAD_PIN_METHOD); - } - pin = pinobj->data; - - /* Fixme: pack this into a verification loop */ - /* Fixme: we might want to pass pin->min_length and - pin->stored_length */ - rc = pincb (pincb_arg, pinobj->label, &pinvalue); - if (rc) - { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); - return rc; - } - - rc = sc_pkcs15_verify_pin (card->p15card, pin, - pinvalue, strlen (pinvalue)); - xfree (pinvalue); - if (rc) - { - log_info ("PIN verification failed: %s\n", sc_strerror (rc)); - return gpg_error (GPG_ERR_BAD_PIN); - } - - /* fixme: check wheter we need to release KEYOBJ in case of an error */ - *r_keyobj = keyobj; - return 0; -} - - -/* See card.c for interface description */ -static int -p15_sign (CARD card, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - unsigned int cryptflags; - struct sc_pkcs15_object *keyobj; - int rc; - unsigned char *outbuf = NULL; - size_t outbuflen; - - if (hashalgo != GCRY_MD_SHA1) - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - - rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj); - if (rc) - return rc; - - cryptflags = SC_ALGORITHM_RSA_PAD_PKCS1; - - outbuflen = 1024; - outbuf = xtrymalloc (outbuflen); - if (!outbuf) - return gpg_error (gpg_err_code_from_errno (errno)); - - rc = sc_pkcs15_compute_signature (card->p15card, keyobj, - cryptflags, - indata, indatalen, - outbuf, outbuflen ); - if (rc < 0) - { - log_error ("failed to create signature: %s\n", sc_strerror (rc)); - rc = gpg_error (GPG_ERR_CARD); - } - else - { - *outdatalen = rc; - *outdata = outbuf; - outbuf = NULL; - rc = 0; - } - - xfree (outbuf); - return rc; -} - - -/* See card.c for description */ -static int -p15_decipher (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - struct sc_pkcs15_object *keyobj; - int rc; - unsigned char *outbuf = NULL; - size_t outbuflen; - - rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj); - if (rc) - return rc; - - if (card && card->scard && card->scard->driver - && !strcasecmp (card->scard->driver->short_name, "tcos")) - { - /* very ugly hack to force the use of a local key. We need this - until we have fixed the initialization code for TCOS cards */ - struct sc_pkcs15_prkey_info *prkey = keyobj->data; - if ( !(prkey->key_reference & 0x80)) - { - prkey->key_reference |= 0x80; - log_debug ("using TCOS hack to force the use of local keys\n"); - } - if (*keyidstr && keyidstr[strlen(keyidstr)-1] == '6') - { - prkey->key_reference |= 1; - log_debug ("warning: using even more TCOS hacks\n"); - } - } - - outbuflen = indatalen < 256? 256 : indatalen; - outbuf = xtrymalloc (outbuflen); - if (!outbuf) - return gpg_error (gpg_err_code_from_errno (errno)); - - rc = sc_pkcs15_decipher (card->p15card, keyobj, - 0, - indata, indatalen, - outbuf, outbuflen); - if (rc < 0) - { - log_error ("failed to decipher the data: %s\n", sc_strerror (rc)); - rc = gpg_error (GPG_ERR_CARD); - } - else - { - *outdatalen = rc; - *outdata = outbuf; - outbuf = NULL; - rc = 0; - } - - xfree (outbuf); - return rc; -} - - - -/* Bind our operations to the card */ -void -card_p15_bind (CARD card) -{ - card->fnc.enum_keypairs = p15_enum_keypairs; - card->fnc.enum_certs = p15_enum_certs; - card->fnc.read_cert = p15_read_cert; - card->fnc.sign = p15_sign; - card->fnc.decipher = p15_decipher; -} -#endif /*HAVE_OPENSC*/ diff --git a/scd/card.c b/scd/card.c deleted file mode 100644 index 9ec2a52c5..000000000 --- a/scd/card.c +++ /dev/null @@ -1,570 +0,0 @@ -/* card.c - SCdaemon card functions - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#ifdef HAVE_OPENSC -#include <opensc/pkcs15.h> -#endif - -#include "scdaemon.h" -#include <ksba.h> - -#include "card-common.h" - -/* Map the SC error codes to the GNUPG ones */ -gpg_error_t -map_sc_err (int rc) -{ - gpg_err_code_t e; - - switch (rc) - { - case 0: e = 0; break; -#ifdef HAVE_OPENSC - case SC_ERROR_NOT_SUPPORTED: e = GPG_ERR_NOT_SUPPORTED; break; - case SC_ERROR_PKCS15_APP_NOT_FOUND: e = GPG_ERR_NO_PKCS15_APP; break; - case SC_ERROR_OUT_OF_MEMORY: e = GPG_ERR_ENOMEM; break; - case SC_ERROR_CARD_NOT_PRESENT: e = GPG_ERR_CARD_NOT_PRESENT; break; - case SC_ERROR_CARD_REMOVED: e = GPG_ERR_CARD_REMOVED; break; - case SC_ERROR_INVALID_CARD: e = GPG_ERR_INV_CARD; break; -#endif - default: e = GPG_ERR_CARD; break; - } - /* It does not make much sense to further distingusih the error - source between OpenSC and SCD. Thus we use SCD as source - here. */ - return gpg_err_make (GPG_ERR_SOURCE_SCD, e); -} - -/* Get the keygrip from CERT, return 0 on success */ -int -card_help_get_keygrip (ksba_cert_t cert, unsigned char *array) -{ - gcry_sexp_t s_pkey; - int rc; - ksba_sexp_t p; - size_t n; - - p = ksba_cert_get_public_key (cert); - if (!p) - return -1; /* oops */ - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - return -1; /* libksba did not return a proper S-expression */ - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); - xfree (p); - if (rc) - return -1; /* can't parse that S-expression */ - array = gcry_pk_get_keygrip (s_pkey, array); - gcry_sexp_release (s_pkey); - if (!array) - return -1; /* failed to calculate the keygrip */ - return 0; -} - - - - - - - -/* Create a new context for the card and figures out some basic - information of the card. Detects whether a PKCS_15 application is - stored. - - Common errors: GPG_ERR_CARD_NOT_PRESENT */ -int -card_open (CARD *rcard) -{ -#ifdef HAVE_OPENSC - CARD card; - int rc; - - if (opt.disable_opensc) - return gpg_error (GPG_ERR_NOT_SUPPORTED); - - card = xtrycalloc (1, sizeof *card); - if (!card) - return gpg_error (gpg_err_code_from_errno (errno)); - card->reader = 0; - - rc = sc_establish_context (&card->ctx, "scdaemon"); - if (rc) - { - log_error ("failed to establish SC context: %s\n", sc_strerror (rc)); - rc = map_sc_err (rc); - goto leave; - } - if (card->reader >= card->ctx->reader_count) - { - log_error ("no card reader available\n"); - rc = gpg_error (GPG_ERR_CARD); - goto leave; - } - card->ctx->error_file = log_get_stream (); - card->ctx->debug = opt.debug_sc; - card->ctx->debug_file = log_get_stream (); - - if (sc_detect_card_presence (card->ctx->reader[card->reader], 0) != 1) - { - rc = gpg_error (GPG_ERR_CARD_NOT_PRESENT); - goto leave; - } - - rc = sc_connect_card (card->ctx->reader[card->reader], 0, &card->scard); - if (rc) - { - log_error ("failed to connect card in reader %d: %s\n", - card->reader, sc_strerror (rc)); - rc = map_sc_err (rc); - goto leave; - } - if (opt.verbose) - log_info ("connected to card in reader %d using driver `%s'\n", - card->reader, card->scard->driver->name); - - rc = sc_lock (card->scard); - if (rc) - { - log_error ("can't lock card in reader %d: %s\n", - card->reader, sc_strerror (rc)); - rc = map_sc_err (rc); - goto leave; - } - - - leave: - if (rc) - card_close (card); - else - *rcard = card; - - return rc; -#else - return gpg_error (GPG_ERR_NOT_SUPPORTED); -#endif -} - - -/* Close a card and release all resources */ -void -card_close (CARD card) -{ - if (card) - { -#ifdef HAVE_OPENSC - if (card->p15card) - { - sc_pkcs15_unbind (card->p15card); - card->p15card = NULL; - } - if (card->p15priv) - p15_release_private_data (card); - if (card->scard) - { - sc_unlock (card->scard); - sc_disconnect_card (card->scard, 0); - card->scard = NULL; - } - if (card->ctx) - { - sc_release_context (card->ctx); - card->ctx = NULL; - } -#endif - xfree (card); - } -} - -/* Locate a simple TLV encoded data object in BUFFER of LENGTH and - return a pointer to value as well as its length in NBYTES. Return - NULL if it was not found. Note, that the function does not check - whether the value fits into the provided buffer. */ -#ifdef HAVE_OPENSC -static const char * -find_simple_tlv (const unsigned char *buffer, size_t length, - int tag, size_t *nbytes) -{ - const char *s = buffer; - size_t n = length; - size_t len; - - for (;;) - { - buffer = s; - if (n < 2) - return NULL; /* buffer too short for tag and length. */ - len = s[1]; - s += 2; n -= 2; - if (len == 255) - { - if (n < 2) - return NULL; /* we expected 2 more bytes with the length. */ - len = (s[0] << 8) | s[1]; - s += 2; n -= 2; - } - if (*buffer == tag) - { - *nbytes = len; - return s; - } - if (len > n) - return NULL; /* buffer too short to skip to the next tag. */ - s += len; n -= len; - } -} -#endif /*HAVE_OPENSC*/ - -/* Find the ICC Serial Number within the provided BUFFER of LENGTH - (which should contain the GDO file) and return it as a hex encoded - string and allocated string in SERIAL. Return an error code when - the ICCSN was not found. */ -#ifdef HAVE_OPENSC -static int -find_iccsn (const unsigned char *buffer, size_t length, char **serial) -{ - size_t n; - const unsigned char *s; - char *p; - - s = find_simple_tlv (buffer, length, 0x5A, &n); - if (!s) - return gpg_error (GPG_ERR_CARD); - length -= s - buffer; - if (n > length) - { - /* Oops, it does not fit into the buffer. This is an invalid - encoding (or the buffer is too short. However, I have some - test cards with such an invalid encoding and therefore I use - this ugly workaround to return something I can further - experiment with. */ - if (n == 0x0D && length+1 == n) - { - log_debug ("enabling BMI testcard workaround\n"); - n--; - } - else - return gpg_error (GPG_ERR_CARD); /* Bad encoding; does - not fit into buffer. */ - } - if (!n) - return gpg_error (GPG_ERR_CARD); /* Well, that is too short. */ - - *serial = p = xtrymalloc (2*n+1); - if (!*serial) - return gpg_error (gpg_err_code_from_errno (errno)); - for (; n; n--, p += 2, s++) - sprintf (p, "%02X", *s); - *p = 0; - return 0; -} -#endif /*HAVE_OPENSC*/ - -/* Retrieve the serial number and the time of the last update of the - card. The serial number is returned as a malloced string (hex - encoded) in SERIAL and the time of update is returned in STAMP. - If no update time is available the returned value is 0. The serial - is mandatory for a PKCS_15 application and an error will be - returned if this value is not availbale. For non-PKCS-15 cards a - serial number is constructed by other means. Caller must free - SERIAL unless the function returns an error. */ -int -card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp) -{ -#ifdef HAVE_OPENSC - int rc; - struct sc_path path; - struct sc_file *file; - unsigned char buf[256]; - int buflen; -#endif - - if (!card || !serial || !stamp) - return gpg_error (GPG_ERR_INV_VALUE); - - *serial = NULL; - *stamp = 0; /* not available */ - -#ifdef HAVE_OPENSC - if (!card->fnc.initialized) - { - card->fnc.initialized = 1; - /* The first use of this card tries to figure out the type of the card - and sets up the function pointers. */ - rc = sc_pkcs15_bind (card->scard, &card->p15card); - if (rc) - { - if (rc != SC_ERROR_PKCS15_APP_NOT_FOUND) - log_error ("binding of existing PKCS-15 failed in reader %d: %s\n", - card->reader, sc_strerror (rc)); - card->p15card = NULL; - rc = 0; - } - if (card->p15card) - card_p15_bind (card); - card->fnc.initialized = 1; - } - - - /* We should lookup the iso 7812-1 and 8583-3 - argh ISO - practice is suppressing innovation - IETF rules! So we - always get the serialnumber from the 2F02 GDO file. */ - /* FIXME: in case we can't parse the 2F02 EF and we have a P15 card, - we should get the serial number from the respective P15 file */ - sc_format_path ("3F002F02", &path); - rc = sc_select_file (card->scard, &path, &file); - if (rc) - { - log_error ("sc_select_file failed: %s\n", sc_strerror (rc)); - return gpg_error (GPG_ERR_CARD); - } - if (file->type != SC_FILE_TYPE_WORKING_EF - || file->ef_structure != SC_FILE_EF_TRANSPARENT) - { - log_error ("wrong type or structure of GDO file\n"); - sc_file_free (file); - return gpg_error (GPG_ERR_CARD); - } - - if (!file->size || file->size >= DIM(buf) ) - { /* FIXME: Use a real parser */ - log_error ("unsupported size of GDO file (%d)\n", file->size); - sc_file_free (file); - return gpg_error (GPG_ERR_CARD); - } - buflen = file->size; - - rc = sc_read_binary (card->scard, 0, buf, buflen, 0); - sc_file_free (file); - if (rc < 0) - { - log_error ("error reading GDO file: %s\n", sc_strerror (rc)); - return gpg_error (GPG_ERR_CARD); - } - if (rc != buflen) - { - log_error ("short read on GDO file\n"); - return gpg_error (GPG_ERR_CARD); - } - - rc = find_iccsn (buf, buflen, serial); - if (gpg_err_code (rc) == GPG_ERR_CARD) - log_error ("invalid structure of GDO file\n"); - if (!rc && card->p15card && !strcmp (*serial, "D27600000000000000000000")) - { /* This is a German card with a silly serial number. Try to get - the serial number from the EF(TokenInfo). We indicate such a - serial number by the using the prefix: "FF0100". */ - const char *efser = card->p15card->serial_number; - char *p; - - if (!efser) - efser = ""; - - xfree (*serial); - *serial = NULL; - p = xtrymalloc (strlen (efser) + 7); - if (!p) - rc = gpg_error (gpg_err_code_from_errno (errno)); - else - { - strcpy (p, "FF0100"); - strcpy (p+6, efser); - *serial = p; - } - } - else if (!rc && **serial == 'F' && (*serial)[1] == 'F') - { /* The serial number starts with our special prefix. This - requires that we put our default prefix "FF0000" in front. */ - char *p = xtrymalloc (strlen (*serial) + 7); - if (!p) - { - xfree (*serial); - *serial = NULL; - rc = gpg_error (gpg_err_code_from_errno (errno)); - } - else - { - strcpy (p, "FF0000"); - strcpy (p+6, *serial); - xfree (*serial); - *serial = p; - } - } - return rc; -#else - return gpg_error (GPG_ERR_NOT_SUPPORTED); -#endif -} - - -/* Enumerate all keypairs on the card and return the Keygrip as well - as the internal identification of the key. KEYGRIP must be a - caller provided buffer with a size of 20 bytes which will receive - the KEYGRIP of the keypair. If KEYID is not NULL, it returns the - ID field of the key in allocated memory; this is a string without - spaces. The function returns -1 when all keys have been - enumerated. Note that the error GPG_ERR_MISSING_CERTIFICATE may be - returned if there is just the private key but no public key (ie.e a - certificate) available. Applications might want to continue - enumerating after this error.*/ -int -card_enum_keypairs (CARD card, int idx, - unsigned char *keygrip, - char **keyid) -{ - int rc; - - if (keyid) - *keyid = NULL; - - if (!card || !keygrip) - return gpg_error (GPG_ERR_INV_VALUE); - if (idx < 0) - return gpg_error (GPG_ERR_INV_INDEX); - if (!card->fnc.initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!card->fnc.enum_keypairs) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = card->fnc.enum_keypairs (card, idx, keygrip, keyid); - if (opt.verbose) - log_info ("card operation enum_keypairs result: %s\n", - gpg_strerror (rc)); - return rc; -} - - -/* Enumerate all trusted certificates available on the card, return - their ID in CERT and the type in CERTTYPE. Types of certificates - are: - 0 := Unknown - 100 := Regular X.509 cert - 101 := Trusted X.509 cert - 102 := Useful X.509 cert - 110 := Root CA cert (DINSIG) - */ -int -card_enum_certs (CARD card, int idx, char **certid, int *certtype) -{ - int rc; - - if (certid) - *certid = NULL; - - if (!card) - return gpg_error (GPG_ERR_INV_VALUE); - if (idx < 0) - return gpg_error (GPG_ERR_INV_INDEX); - if (!card->fnc.initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!card->fnc.enum_certs) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = card->fnc.enum_certs (card, idx, certid, certtype); - if (opt.verbose) - log_info ("card operation enum_certs result: %s\n", - gpg_strerror (rc)); - return rc; -} - - - -/* Read the certificate identified by CERTIDSTR which is the - hexadecimal encoded ID of the certificate, prefixed with the string - "3F005015.". The certificate is return in DER encoded form in CERT - and NCERT. */ -int -card_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert) -{ - int rc; - - if (!card || !certidstr || !cert || !ncert) - return gpg_error (GPG_ERR_INV_VALUE); - if (!card->fnc.initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!card->fnc.read_cert) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = card->fnc.read_cert (card, certidstr, cert, ncert); - if (opt.verbose) - log_info ("card operation read_cert result: %s\n", gpg_strerror (rc)); - return rc; -} - - -/* Create the signature and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; it - should return the PIN in an allocated buffer and put it into PIN. */ -int -card_sign (CARD card, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - - if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!card->fnc.initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!card->fnc.sign) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = card->fnc.sign (card, keyidstr, hashalgo, - pincb, pincb_arg, - indata, indatalen, - outdata, outdatalen); - if (opt.verbose) - log_info ("card operation sign result: %s\n", gpg_strerror (rc)); - return rc; -} - - -/* Create the signature and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; it - should return the PIN in an allocated buffer and put it into PIN. */ -int -card_decipher (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - - if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!card->fnc.initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!card->fnc.decipher) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = card->fnc.decipher (card, keyidstr, - pincb, pincb_arg, - indata, indatalen, - outdata, outdatalen); - if (opt.verbose) - log_info ("card operation decipher result: %s\n", gpg_strerror (rc)); - return rc; -} - diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c deleted file mode 100644 index cd0bee6ef..000000000 --- a/scd/ccid-driver.c +++ /dev/null @@ -1,1277 +0,0 @@ -/* ccid-driver.c - USB ChipCardInterfaceDevices driver - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * Written by Werner Koch. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * ALTERNATIVELY, this file may be distributed under the terms of the - * following license, in which case the provisions of this license are - * required INSTEAD OF the GNU General Public License. If you wish to - * allow use of your version of this file only under the terms of the - * GNU General Public License, and not to allow others to use your - * version of this file under the terms of the following license, - * indicate your decision by deleting this paragraph and the license - * below. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -/* CCID (ChipCardInterfaceDevices) is a specification for accessing - smartcard via a reader connected to the USB. - - This is a limited driver allowing to use some CCID drivers directly - without any other specila drivers. This is a fallback driver to be - used when nothing else works or the system should be kept minimal - for security reasons. It makes use of the libusb library to gain - portable access to USB. - - This driver has been tested with the SCM SCR335 smartcard reader - and requires that reader implements the TPDU level exchange and - does fully automatic initialization. -*/ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#if defined(HAVE_LIBUSB) || defined(TEST) - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include <usb.h> - -#include "ccid-driver.h" - -#define DRVNAME "ccid-driver: " - - -/* Depending on how this source is used we either define our error - output to go to stderr or to the jnlib based logging functions. We - use the latter when GNUPG_MAJOR_VERSION is defines or when both, - GNUPG_SCD_MAIN_HEADER and HAVE_JNLIB_LOGGING are defined. -*/ -#if defined(GNUPG_MAJOR_VERSION) \ - || (defined(GNUPG_SCD_MAIN_HEADER) && defined(HAVE_JNLIB_LOGGING)) - -#if defined(GNUPG_SCD_MAIN_HEADER) -# include GNUPG_SCD_MAIN_HEADER -#elif GNUPG_MAJOR_VERSION == 1 /* GnuPG Version is < 1.9. */ -# include "options.h" -# include "util.h" -# include "memory.h" -# include "cardglue.h" -# else /* This is the modularized GnuPG 1.9 or later. */ -# include "scdaemon.h" -#endif - -/* Disable all debugging output for now. */ -#undef DBG_CARD_IO -#define DBG_CARD_IO 0 - -/* Define to print information pertaining the T=1 protocol. */ -#undef DEBUG_T1 - - -# define DEBUGOUT(t) do { if (DBG_CARD_IO) \ - log_debug (DRVNAME t); } while (0) -# define DEBUGOUT_1(t,a) do { if (DBG_CARD_IO) \ - log_debug (DRVNAME t,(a)); } while (0) -# define DEBUGOUT_2(t,a,b) do { if (DBG_CARD_IO) \ - log_debug (DRVNAME t,(a),(b)); } while (0) -# define DEBUGOUT_3(t,a,b,c) do { if (DBG_CARD_IO) \ - log_debug (DRVNAME t,(a),(b),(c));} while (0) -# define DEBUGOUT_CONT(t) do { if (DBG_CARD_IO) \ - log_printf (t); } while (0) -# define DEBUGOUT_CONT_1(t,a) do { if (DBG_CARD_IO) \ - log_printf (t,(a)); } while (0) -# define DEBUGOUT_CONT_2(t,a,b) do { if (DBG_CARD_IO) \ - log_printf (t,(a),(b)); } while (0) -# define DEBUGOUT_CONT_3(t,a,b,c) do { if (DBG_CARD_IO) \ - log_printf (t,(a),(b),(c)); } while (0) -# define DEBUGOUT_LF() do { if (DBG_CARD_IO) \ - log_printf ("\n"); } while (0) - -#else /* Other usage of this source - don't use gnupg specifics. */ - -# define DEBUGOUT(t) fprintf (stderr, DRVNAME t) -# define DEBUGOUT_1(t,a) fprintf (stderr, DRVNAME t, (a)) -# define DEBUGOUT_2(t,a,b) fprintf (stderr, DRVNAME t, (a), (b)) -# define DEBUGOUT_3(t,a,b,c) fprintf (stderr, DRVNAME t, (a), (b), (c)) -# define DEBUGOUT_CONT(t) fprintf (stderr, t) -# define DEBUGOUT_CONT_1(t,a) fprintf (stderr, t, (a)) -# define DEBUGOUT_CONT_2(t,a,b) fprintf (stderr, t, (a), (b)) -# define DEBUGOUT_CONT_3(t,a,b,c) fprintf (stderr, t, (a), (b), (c)) -# define DEBUGOUT_LF() putc ('\n', stderr) - -#endif /* This source not used by scdaemon. */ - - - - - -enum { - RDR_to_PC_NotifySlotChange= 0x50, - RDR_to_PC_HardwareError = 0x51, - - PC_to_RDR_SetParameters = 0x61, - PC_to_RDR_IccPowerOn = 0x62, - PC_to_RDR_IccPowerOff = 0x63, - PC_to_RDR_GetSlotStatus = 0x65, - PC_to_RDR_Secure = 0x69, - PC_to_RDR_T0APDU = 0x6a, - PC_to_RDR_Escape = 0x6b, - PC_to_RDR_GetParameters = 0x6c, - PC_to_RDR_ResetParameters = 0x6d, - PC_to_RDR_IccClock = 0x6e, - PC_to_RDR_XfrBlock = 0x6f, - PC_to_RDR_Mechanical = 0x71, - PC_to_RDR_Abort = 0x72, - PC_to_RDR_SetDataRate = 0x73, - - RDR_to_PC_DataBlock = 0x80, - RDR_to_PC_SlotStatus = 0x81, - RDR_to_PC_Parameters = 0x82, - RDR_to_PC_Escape = 0x83, - RDR_to_PC_DataRate = 0x84 -}; - - -/* Store information on the driver's state. A pointer to such a - structure is used as handle for most functions. */ -struct ccid_driver_s { - usb_dev_handle *idev; - int seqno; - unsigned char t1_ns; - unsigned char t1_nr; - int nonnull_nad; - int auto_ifsd; - int max_ifsd; - int ifsd; -}; - - -static unsigned int compute_edc (const unsigned char *data, size_t datalen, - int use_crc); -static int bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen); -static int bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, - size_t *nread, int expected_type, int seqno); - - - -/* Convert a little endian stored 4 byte value into an unsigned - integer. */ -static unsigned int -convert_le_u32 (const unsigned char *buf) -{ - return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); -} - -static void -set_msg_len (unsigned char *msg, unsigned int length) -{ - msg[1] = length; - msg[2] = length >> 8; - msg[3] = length >> 16; - msg[4] = length >> 24; -} - - - - -/* Parse a CCID descriptor, optionally print all available features - and test whether this reader is usable by this driver. Returns 0 - if it is usable. - - Note, that this code is based on the one in lsusb.c of the - usb-utils package, I wrote on 2003-09-01. -wk. */ -static int -parse_ccid_descriptor (ccid_driver_t handle, - const unsigned char *buf, size_t buflen) -{ - unsigned int i; - unsigned int us; - int have_t1 = 0, have_tpdu=0, have_auto_conf = 0; - - - handle->nonnull_nad = 0; - handle->auto_ifsd = 0; - handle->max_ifsd = 32; - handle->ifsd = 0; - if (buflen < 54 || buf[0] < 54) - { - DEBUGOUT ("CCID device descriptor is too short\n"); - return -1; - } - - DEBUGOUT ("ChipCard Interface Descriptor:\n"); - DEBUGOUT_1 (" bLength %5u\n", buf[0]); - DEBUGOUT_1 (" bDescriptorType %5u\n", buf[1]); - DEBUGOUT_2 (" bcdCCID %2x.%02x", buf[3], buf[2]); - if (buf[3] != 1 || buf[2] != 0) - DEBUGOUT_CONT(" (Warning: Only accurate for version 1.0)"); - DEBUGOUT_LF (); - - DEBUGOUT_1 (" nMaxSlotIndex %5u\n", buf[4]); - DEBUGOUT_2 (" bVoltageSupport %5u %s\n", - buf[5], (buf[5] == 1? "5.0V" : buf[5] == 2? "3.0V" - : buf[5] == 3? "1.8V":"?")); - - us = convert_le_u32 (buf+6); - DEBUGOUT_1 (" dwProtocols %5u ", us); - if ((us & 1)) - DEBUGOUT_CONT (" T=0"); - if ((us & 2)) - { - DEBUGOUT_CONT (" T=1"); - have_t1 = 1; - } - if ((us & ~3)) - DEBUGOUT_CONT (" (Invalid values detected)"); - DEBUGOUT_LF (); - - us = convert_le_u32(buf+10); - DEBUGOUT_1 (" dwDefaultClock %5u\n", us); - us = convert_le_u32(buf+14); - DEBUGOUT_1 (" dwMaxiumumClock %5u\n", us); - DEBUGOUT_1 (" bNumClockSupported %5u\n", buf[18]); - us = convert_le_u32(buf+19); - DEBUGOUT_1 (" dwDataRate %7u bps\n", us); - us = convert_le_u32(buf+23); - DEBUGOUT_1 (" dwMaxDataRate %7u bps\n", us); - DEBUGOUT_1 (" bNumDataRatesSupp. %5u\n", buf[27]); - - us = convert_le_u32(buf+28); - DEBUGOUT_1 (" dwMaxIFSD %5u\n", us); - handle->max_ifsd = us; - - us = convert_le_u32(buf+32); - DEBUGOUT_1 (" dwSyncProtocols %08X ", us); - if ((us&1)) - DEBUGOUT_CONT ( " 2-wire"); - if ((us&2)) - DEBUGOUT_CONT ( " 3-wire"); - if ((us&4)) - DEBUGOUT_CONT ( " I2C"); - DEBUGOUT_LF (); - - us = convert_le_u32(buf+36); - DEBUGOUT_1 (" dwMechanical %08X ", us); - if ((us & 1)) - DEBUGOUT_CONT (" accept"); - if ((us & 2)) - DEBUGOUT_CONT (" eject"); - if ((us & 4)) - DEBUGOUT_CONT (" capture"); - if ((us & 8)) - DEBUGOUT_CONT (" lock"); - DEBUGOUT_LF (); - - us = convert_le_u32(buf+40); - DEBUGOUT_1 (" dwFeatures %08X\n", us); - if ((us & 0x0002)) - { - DEBUGOUT (" Auto configuration based on ATR\n"); - have_auto_conf = 1; - } - if ((us & 0x0004)) - DEBUGOUT (" Auto activation on insert\n"); - if ((us & 0x0008)) - DEBUGOUT (" Auto voltage selection\n"); - if ((us & 0x0010)) - DEBUGOUT (" Auto clock change\n"); - if ((us & 0x0020)) - DEBUGOUT (" Auto baud rate change\n"); - if ((us & 0x0040)) - DEBUGOUT (" Auto parameter negotation made by CCID\n"); - else if ((us & 0x0080)) - DEBUGOUT (" Auto PPS made by CCID\n"); - else if ((us & (0x0040 | 0x0080))) - DEBUGOUT (" WARNING: conflicting negotation features\n"); - - if ((us & 0x0100)) - DEBUGOUT (" CCID can set ICC in clock stop mode\n"); - if ((us & 0x0200)) - { - DEBUGOUT (" NAD value other than 0x00 accepted\n"); - handle->nonnull_nad = 1; - } - if ((us & 0x0400)) - { - DEBUGOUT (" Auto IFSD exchange\n"); - handle->auto_ifsd = 1; - } - - if ((us & 0x00010000)) - { - DEBUGOUT (" TPDU level exchange\n"); - have_tpdu = 1; - } - else if ((us & 0x00020000)) - DEBUGOUT (" Short APDU level exchange\n"); - else if ((us & 0x00040000)) - DEBUGOUT (" Short and extended APDU level exchange\n"); - else if ((us & 0x00070000)) - DEBUGOUT (" WARNING: conflicting exchange levels\n"); - - us = convert_le_u32(buf+44); - DEBUGOUT_1 (" dwMaxCCIDMsgLen %5u\n", us); - - DEBUGOUT ( " bClassGetResponse "); - if (buf[48] == 0xff) - DEBUGOUT_CONT ("echo\n"); - else - DEBUGOUT_CONT_1 (" %02X\n", buf[48]); - - DEBUGOUT ( " bClassEnvelope "); - if (buf[49] == 0xff) - DEBUGOUT_CONT ("echo\n"); - else - DEBUGOUT_1 (" %02X\n", buf[48]); - - DEBUGOUT ( " wlcdLayout "); - if (!buf[50] && !buf[51]) - DEBUGOUT_CONT ("none\n"); - else - DEBUGOUT_CONT_2 ("%u cols %u lines\n", buf[50], buf[51]); - - DEBUGOUT_1 (" bPINSupport %5u ", buf[52]); - if ((buf[52] & 1)) - DEBUGOUT_CONT ( " verification"); - if ((buf[52] & 2)) - DEBUGOUT_CONT ( " modification"); - DEBUGOUT_LF (); - - DEBUGOUT_1 (" bMaxCCIDBusySlots %5u\n", buf[53]); - - if (buf[0] > 54) { - DEBUGOUT (" junk "); - for (i=54; i < buf[0]-54; i++) - DEBUGOUT_CONT_1 (" %02X", buf[i]); - DEBUGOUT_LF (); - } - - if (!have_t1 || !have_tpdu || !have_auto_conf) - { - DEBUGOUT ("this drivers requires that the reader supports T=1, " - "TPDU level exchange and auto configuration - " - "this is not available\n"); - return -1; - } - else - return 0; -} - - -/* Read the device information, return all required data and check - that the device is usable for us. Returns 0 on success or an error - code. */ -static int -read_device_info (ccid_driver_t handle, struct usb_device *dev) -{ - int cfg_no; - - for (cfg_no=0; cfg_no < dev->descriptor->bNumConfigurations; cfg_no++) - { - struct usb_config_descriptor *config = dev->config + cfg_no; - int ifc_no; - - for (ifc_no=0; ifc_no < config->bNumInterfaces; ifc_no++) - { - struct usb_interface *interface = config->interface + ifc_no; - int set_no; - - for (set_no=0; set_no < interface->num_altsetting; set_no++) - { - struct usb_interface_descriptor *ifcdesc - = interface->altsetting + set_no; - - if (ifcdesc->bInterfaceClass == 11 - && ifcdesc->bInterfaceSubClass == 0 - && ifcdesc->bInterfaceProtocol == 0) - { - if (ifcdesc->extra) - { - if (!parse_ccid_descriptor (handle, - ifcdesc->extra, - ifcdesc->extralen)) - return 0; /* okay. we can use it. */ - } - } - } - } - } - return -1; /* No suitable device found. */ -} - - -/* Open the reader with the internal number READERNO and return a a - pointer to be used as handle in HANDLE. Returns 0 on success. */ -int -ccid_open_reader (ccid_driver_t *handle, int readerno) -{ - static int initialized; - - int rc; - usb_match_handle *match = NULL; - struct usb_device *dev = NULL; - usb_dev_handle *idev = NULL; - - *handle = NULL; - if (!initialized) - { - usb_init (); - initialized = 1; - } - - rc = usb_create_match (&match, -1, -1, 11, -1, -1); - if (rc) - { - DEBUGOUT_1 ("usb_create_match failed: %d\n", rc); - return -1; - } - - while (usb_find_device(match, dev, &dev) >= 0) - { - DEBUGOUT_3 ("%-40s %04X/%04X\n", dev->filename, - dev->descriptor->idVendor, dev->descriptor->idProduct); - if (!readerno) - { - *handle = calloc (1, sizeof **handle); - if (!*handle) - { - DEBUGOUT ("out of memory\n"); - rc = -1; - free (*handle); - *handle = NULL; - goto leave; - } - - rc = read_device_info (*handle, dev); - if (rc) - { - DEBUGOUT ("device not supported\n"); - free (*handle); - *handle = NULL; - goto leave; - } - - rc = usb_open (dev, &idev); - if (rc) - { - DEBUGOUT_1 ("usb_open failed: %d\n", rc); - free (*handle); - *handle = NULL; - goto leave; - } - - - /* fixme: Do we need to claim and set the interface as - determined by read_device_info ()? */ - rc = usb_claim_interface (idev, 0); - if (rc) - { - DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc); - free (*handle); - *handle = NULL; - goto leave; - } - - (*handle)->idev = idev; - idev = NULL; - /* FIXME: Do we need to get the endpoint addresses from the - structure and store them with the handle? */ - - break; - } - readerno--; - } - - - leave: - if (idev) - usb_close (idev); - /* fixme: Do we need to release dev or is it supposed to be a - shallow copy of the list created internally by usb_init ? */ - usb_free_match (match); - - if (!rc && !*handle) - rc = -1; /* In case we didn't enter the while loop at all. */ - - return rc; -} - - -/* Close the reader HANDLE. */ -int -ccid_close_reader (ccid_driver_t handle) -{ - if (!handle || !handle->idev) - return 0; - - { - int rc; - unsigned char msg[100]; - size_t msglen; - unsigned char seqno; - - msg[0] = PC_to_RDR_IccPowerOff; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 0; /* RFU */ - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - set_msg_len (msg, 0); - msglen = 10; - - rc = bulk_out (handle, msg, msglen); - if (!rc) - bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus, seqno); - } - - usb_release_interface (handle->idev, 0); - usb_close (handle->idev); - handle->idev = NULL; - free (handle); - return 0; -} - - -/* Return False if a card is present and powered. */ -int -ccid_check_card_presence (ccid_driver_t handle) -{ - - return -1; -} - - -/* Write a MSG of length MSGLEN to the designated bulk out endpoint. - Returns 0 on success. */ -static int -bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen) -{ - int rc; - - rc = usb_bulk_write (handle->idev, - 1, /*endpoint */ - msg, msglen, - 1000 /* ms timeout */); - if (rc == msglen) - return 0; - - if (rc == -1) - DEBUGOUT_1 ("usb_bulk_write error: %s\n", strerror (errno)); - else - DEBUGOUT_1 ("usb_bulk_write failed: %d\n", rc); - return -1; -} - - -/* Read a maximum of LENGTH bytes from the bulk in endpoint into - BUFFER and return the actual read number if bytes in NREAD. SEQNO - is the sequence number used to send the request and EXPECTED_TYPE - the type of message we expect. Does checks on the ccid - header. Returns 0 on success. */ -static int -bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, - size_t *nread, int expected_type, int seqno) -{ - int i, rc; - size_t msglen; - - retry: - rc = usb_bulk_read (handle->idev, - 0x82, - buffer, length, - 10000 /* ms timeout */ ); - /* Fixme: instead of using a 10 second timeout we should better - handle the timeout here and retry if appropriate. */ - if (rc < 0) - { - DEBUGOUT_1 ("usb_bulk_read error: %s\n", strerror (errno)); - return -1; - } - - *nread = msglen = rc; - - if (msglen < 10) - { - DEBUGOUT_1 ("bulk-in msg too short (%u)\n", (unsigned int)msglen); - return -1; - } - if (buffer[0] != expected_type) - { - DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]); - return -1; - } - if (buffer[5] != 0) - { - DEBUGOUT_1 ("unexpected bulk-in slot (%d)\n", buffer[5]); - return -1; - } - if (buffer[6] != seqno) - { - DEBUGOUT_2 ("bulk-in seqno does not match (%d/%d)\n", - seqno, buffer[6]); - return -1; - } - - if ( !(buffer[7] & 0x03) && (buffer[7] & 0xC0) == 0x80) - { - /* Card present and active, time extension requested. */ - DEBUGOUT_2 ("time extension requested (%02X,%02X)\n", - buffer[7], buffer[8]); - goto retry; - } - - DEBUGOUT_3 ("status: %02X error: %02X octet[9]: %02X\n" - " data:", buffer[7], buffer[8], buffer[9] ); - for (i=10; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", buffer[i]); - DEBUGOUT_LF (); - - return 0; -} - - -/* experimental */ -int -ccid_poll (ccid_driver_t handle) -{ - int rc; - unsigned char msg[10]; - size_t msglen; - int i, j; - - rc = usb_bulk_read (handle->idev, - 0x83, - msg, sizeof msg, - 0 /* ms timeout */ ); - if (rc < 0 && errno == ETIMEDOUT) - return 0; - - if (rc < 0) - { - DEBUGOUT_1 ("usb_intr_read error: %s\n", strerror (errno)); - return -1; - } - - msglen = rc; - rc = 0; - - if (msglen < 1) - { - DEBUGOUT ("intr-in msg too short\n"); - return -1; - } - - if (msg[0] == RDR_to_PC_NotifySlotChange) - { - DEBUGOUT ("notify slot change:"); - for (i=1; i < msglen; i++) - for (j=0; j < 4; j++) - DEBUGOUT_CONT_3 (" %d:%c%c", - (i-1)*4+j, - (msg[i] & (1<<(j*2)))? 'p':'-', - (msg[i] & (2<<(j*2)))? '*':' '); - DEBUGOUT_LF (); - } - else if (msg[0] == RDR_to_PC_HardwareError) - { - DEBUGOUT ("hardware error occured\n"); - } - else - { - DEBUGOUT_1 ("unknown intr-in msg of type %02X\n", msg[0]); - } - - return 0; -} - - - -int -ccid_slot_status (ccid_driver_t handle, int *statusbits) -{ - int rc; - unsigned char msg[100]; - size_t msglen; - unsigned char seqno; - - msg[0] = PC_to_RDR_GetSlotStatus; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 0; /* RFU */ - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - set_msg_len (msg, 0); - - rc = bulk_out (handle, msg, 10); - if (rc) - return rc; - rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus, seqno); - if (rc) - return rc; - *statusbits = (msg[7] & 3); - - return 0; -} - - -int -ccid_get_atr (ccid_driver_t handle, - unsigned char *atr, size_t maxatrlen, size_t *atrlen) -{ - int rc; - unsigned char msg[100]; - unsigned char *tpdu; - size_t msglen, tpdulen; - unsigned char seqno; - int use_crc = 0; - unsigned int edc; - int i; - - msg[0] = PC_to_RDR_IccPowerOn; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 0; /* power select (0=auto, 1=5V, 2=3V, 3=1.8V) */ - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - set_msg_len (msg, 0); - msglen = 10; - - rc = bulk_out (handle, msg, msglen); - if (rc) - return rc; - rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_DataBlock, seqno); - if (rc) - return rc; - - if (atr) - { - size_t n = msglen - 10; - - if (n > maxatrlen) - n = maxatrlen; - memcpy (atr, msg+10, n); - *atrlen = n; - } - - /* Setup parameters to select T=1. */ - msg[0] = PC_to_RDR_SetParameters; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 1; /* Select T=1. */ - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - - /* FIXME: Get those values from the ATR. */ - msg[10]= 0x01; /* Fi/Di */ - msg[11]= 0x10; /* LRC, direct convention. */ - msg[12]= 0; /* Extra guardtime. */ - msg[13]= 0x41; /* BWI/CWI */ - msg[14]= 0; /* No clock stoppping. */ - msg[15]= 254; /* IFSC */ - msg[16]= 0; /* Does not support non default NAD values. */ - set_msg_len (msg, 7); - msglen = 10 + 7; - - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - - rc = bulk_out (handle, msg, msglen); - if (rc) - return rc; - /* Note that we ignore the error code on purpose. */ - bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Parameters, seqno); - - - /* Send an S-Block with our maximun IFSD to the CCID. */ - if (!handle->auto_ifsd) - { - tpdu = msg+10; - /* NAD: DAD=1, SAD=0 */ - tpdu[0] = handle->nonnull_nad? ((1 << 4) | 0): 0; - tpdu[1] = (0xc0 | 0 | 1); /* S-block request: change IFSD */ - tpdu[2] = 1; - tpdu[3] = handle->max_ifsd? handle->max_ifsd : 32; - tpdulen = 4; - edc = compute_edc (tpdu, tpdulen, use_crc); - if (use_crc) - tpdu[tpdulen++] = (edc >> 8); - tpdu[tpdulen++] = edc; - - msg[0] = PC_to_RDR_XfrBlock; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 0; - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - set_msg_len (msg, tpdulen); - msglen = 10 + tpdulen; - - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - -#ifdef DEBUG_T1 - fprintf (stderr, "T1: put %c-block seq=%d\n", - ((msg[11] & 0xc0) == 0x80)? 'R' : - (msg[11] & 0x80)? 'S' : 'I', - ((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40))); -#endif - - rc = bulk_out (handle, msg, msglen); - if (rc) - return rc; - - /* Fixme: The next line for the current Valgrid without support - for USB IOCTLs. */ - memset (msg, 0, sizeof msg); - - rc = bulk_in (handle, msg, sizeof msg, &msglen, - RDR_to_PC_DataBlock, seqno); - if (rc) - return rc; - - tpdu = msg + 10; - tpdulen = msglen - 10; - - if (tpdulen < 4) - { - DEBUGOUT ("cannot yet handle short blocks!\n"); - return -1; - } - -#ifdef DEBUG_T1 - fprintf (stderr, "T1: got %c-block seq=%d err=%d\n", - ((msg[11] & 0xc0) == 0x80)? 'R' : - (msg[11] & 0x80)? 'S' : 'I', - ((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40)), - ((msg[11] & 0xc0) == 0x80)? (msg[11] & 0x0f) : 0 - ); -#endif - if ((tpdu[1] & 0xe0) != 0xe0 || tpdu[2] != 1) - { - DEBUGOUT ("invalid response for S-block (Change-IFSD)\n"); - return -1; - } - DEBUGOUT_1 ("IFSD has been set to %d\n", tpdu[3]); - } - - return 0; -} - - - - -static unsigned int -compute_edc (const unsigned char *data, size_t datalen, int use_crc) -{ - if (use_crc) - { - return 0x42; /* Not yet implemented. */ - } - else - { - unsigned char crc = 0; - - for (; datalen; datalen--) - crc ^= *data++; - return crc; - } -} - - -/* - Protocol T=1 overview - - Block Structure: - Prologue Field: - 1 byte Node Address (NAD) - 1 byte Protocol Control Byte (PCB) - 1 byte Length (LEN) - Information Field: - 0-254 byte APDU or Control Information (INF) - Epilogue Field: - 1 byte Error Detection Code (EDC) - - NAD: - bit 7 unused - bit 4..6 Destination Node Address (DAD) - bit 3 unused - bit 2..0 Source Node Address (SAD) - - If node adresses are not used, SAD and DAD should be set to 0 on - the first block sent to the card. If they are used they should - have different values (0 for one is okay); that first block sets up - the addresses of the nodes. - - PCB: - Information Block (I-Block): - bit 7 0 - bit 6 Sequence number (yep, that is modulo 2) - bit 5 Chaining flag - bit 4..0 reserved - Received-Ready Block (R-Block): - bit 7 1 - bit 6 0 - bit 5 0 - bit 4 Sequence number - bit 3..0 0 = no error - 1 = EDC or parity error - 2 = other error - other values are reserved - Supervisory Block (S-Block): - bit 7 1 - bit 6 1 - bit 5 clear=request,set=response - bit 4..0 0 = resyncronisation request - 1 = information field size request - 2 = abort request - 3 = extension of BWT request - 4 = VPP error - other values are reserved - -*/ - -int -ccid_transceive (ccid_driver_t handle, - const unsigned char *apdu_buf, size_t apdu_buflen, - unsigned char *resp, size_t maxresplen, size_t *nresp) -{ - int rc; - unsigned char send_buffer[10+259], recv_buffer[10+259]; - const unsigned char *apdu; - size_t apdulen; - unsigned char *msg, *tpdu, *p; - size_t msglen, tpdulen, last_tpdulen, n; - unsigned char seqno; - int i; - unsigned int edc; - int use_crc = 0; - size_t dummy_nresp; - int next_chunk = 1; - int sending = 1; - int retries = 0; - - if (!nresp) - nresp = &dummy_nresp; - *nresp = 0; - - tpdulen = 0; /* Avoid compiler warning about no initialization. */ - msg = send_buffer; - for (;;) - { - if (next_chunk) - { - next_chunk = 0; - - apdu = apdu_buf; - apdulen = apdu_buflen; - assert (apdulen); - - /* Construct an I-Block. */ - if (apdulen > 254) - return -1; /* Invalid length. */ - - tpdu = msg+10; - /* NAD: DAD=1, SAD=0 */ - tpdu[0] = handle->nonnull_nad? ((1 << 4) | 0): 0; - tpdu[1] = ((handle->t1_ns & 1) << 6); /* I-block */ - if (apdulen > 128 /* fixme: replace by ifsc */) - { - apdulen = 128; - apdu_buf += 128; - apdu_buflen -= 128; - tpdu[1] |= (1 << 5); /* Set more bit. */ - } - tpdu[2] = apdulen; - memcpy (tpdu+3, apdu, apdulen); - tpdulen = 3 + apdulen; - edc = compute_edc (tpdu, tpdulen, use_crc); - if (use_crc) - tpdu[tpdulen++] = (edc >> 8); - tpdu[tpdulen++] = edc; - } - - msg[0] = PC_to_RDR_XfrBlock; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 4; /* bBWI */ - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - set_msg_len (msg, tpdulen); - msglen = 10 + tpdulen; - last_tpdulen = tpdulen; - - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - -#ifdef DEBUG_T1 - fprintf (stderr, "T1: put %c-block seq=%d\n", - ((msg[11] & 0xc0) == 0x80)? 'R' : - (msg[11] & 0x80)? 'S' : 'I', - ((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40))); -#endif - - rc = bulk_out (handle, msg, msglen); - if (rc) - return rc; - - /* Fixme: The next line for the current Valgrid without support - for USB IOCTLs. */ - memset (recv_buffer, 0, sizeof recv_buffer); - - msg = recv_buffer; - rc = bulk_in (handle, msg, sizeof recv_buffer, &msglen, - RDR_to_PC_DataBlock, seqno); - if (rc) - return rc; - - tpdu = msg + 10; - tpdulen = msglen - 10; - - if (tpdulen < 4) - { - DEBUGOUT ("cannot yet handle short blocks!\n"); - return -1; - } - -#ifdef DEBUG_T1 - fprintf (stderr, "T1: got %c-block seq=%d err=%d\n", - ((msg[11] & 0xc0) == 0x80)? 'R' : - (msg[11] & 0x80)? 'S' : 'I', - ((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40)), - ((msg[11] & 0xc0) == 0x80)? (msg[11] & 0x0f) : 0 - ); -#endif - - if (!(tpdu[1] & 0x80)) - { /* This is an I-block. */ - retries = 0; - if (sending) - { /* last block sent was successful. */ - handle->t1_ns ^= 1; - sending = 0; - } - - if (!!(tpdu[1] & 0x40) != handle->t1_nr) - { /* Reponse does not match our sequence number. */ - msg = send_buffer; - tpdu = msg+10; - /* NAD: DAD=1, SAD=0 */ - tpdu[0] = handle->nonnull_nad? ((1 << 4) | 0): 0; - tpdu[1] = (0x80 | (handle->t1_nr & 1) << 4 | 2); /* R-block */ - tpdu[2] = 0; - tpdulen = 3; - edc = compute_edc (tpdu, tpdulen, use_crc); - if (use_crc) - tpdu[tpdulen++] = (edc >> 8); - tpdu[tpdulen++] = edc; - - continue; - } - - handle->t1_nr ^= 1; - - p = tpdu + 3; /* Skip the prologue field. */ - n = tpdulen - 3 - 1; /* Strip the epilogue field. */ - /* fixme: verify the checksum. */ - if (resp) - { - if (n > maxresplen) - { - DEBUGOUT_2 ("provided buffer too short for received data " - "(%u/%u)\n", - (unsigned int)n, (unsigned int)maxresplen); - return -1; - } - - memcpy (resp, p, n); - resp += n; - *nresp += n; - maxresplen -= n; - } - - if (!(tpdu[1] & 0x20)) - return 0; /* No chaining requested - ready. */ - - msg = send_buffer; - tpdu = msg+10; - /* NAD: DAD=1, SAD=0 */ - tpdu[0] = handle->nonnull_nad? ((1 << 4) | 0): 0; - tpdu[1] = (0x80 | (handle->t1_nr & 1) << 4); /* R-block */ - tpdu[2] = 0; - tpdulen = 3; - edc = compute_edc (tpdu, tpdulen, use_crc); - if (use_crc) - tpdu[tpdulen++] = (edc >> 8); - tpdu[tpdulen++] = edc; - } - else if ((tpdu[1] & 0xc0) == 0x80) - { /* This is a R-block. */ - if ( (tpdu[1] & 0x0f)) - { /* Error: repeat last block */ - if (++retries > 3) - { - DEBUGOUT ("3 failed retries\n"); - return -1; - } - msg = send_buffer; - tpdulen = last_tpdulen; - } - else if (sending && !!(tpdu[1] & 0x40) == handle->t1_ns) - { /* Reponse does not match our sequence number. */ - DEBUGOUT ("R-block with wrong seqno received on more bit\n"); - return -1; - } - else if (sending) - { /* Send next chunk. */ - retries = 0; - msg = send_buffer; - next_chunk = 1; - handle->t1_ns ^= 1; - } - else - { - DEBUGOUT ("unexpected ACK R-block received\n"); - return -1; - } - } - else - { /* This is a S-block. */ - retries = 0; - DEBUGOUT_2 ("T1 S-block %s received cmd=%d\n", - (tpdu[1] & 0x20)? "response": "request", - (tpdu[1] & 0x1f)); - if ( !(tpdu[1] & 0x20) && (tpdu[1] & 0x1f) == 3 && tpdu[2]) - { /* Wait time extension request. */ - unsigned char bwi = tpdu[3]; - msg = send_buffer; - tpdu = msg+10; - /* NAD: DAD=1, SAD=0 */ - tpdu[0] = handle->nonnull_nad? ((1 << 4) | 0): 0; - tpdu[1] = (0xc0 | 0x20 | 3); /* S-block response */ - tpdu[2] = 1; - tpdu[3] = bwi; - tpdulen = 4; - edc = compute_edc (tpdu, tpdulen, use_crc); - if (use_crc) - tpdu[tpdulen++] = (edc >> 8); - tpdu[tpdulen++] = edc; - DEBUGOUT_1 ("T1 waittime extension of bwi=%d\n", bwi); - } - else - return -1; - } - } /* end T=1 protocol loop. */ - - return 0; -} - - - - -#ifdef TEST -int -main (int argc, char **argv) -{ - int rc; - ccid_driver_t ccid; - unsigned int slotstat; - - rc = ccid_open_reader (&ccid, 0); - if (rc) - return 1; - - ccid_poll (ccid); - fputs ("getting ATR ...\n", stderr); - rc = ccid_get_atr (ccid, NULL, 0, NULL); - if (rc) - return 1; - - ccid_poll (ccid); - fputs ("getting slot status ...\n", stderr); - rc = ccid_slot_status (ccid, &slotstat); - if (rc) - return 1; - - ccid_poll (ccid); - - { - static unsigned char apdu[] = { - 0, 0xA4, 4, 0, 6, 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01}; - rc = ccid_transceive (ccid, - apdu, sizeof apdu, - NULL, 0, NULL); - } - ccid_poll (ccid); - - { - static unsigned char apdu[] = { - 0, 0xCA, 0, 0x65, 254 }; - rc = ccid_transceive (ccid, - apdu, sizeof apdu, - NULL, 0, NULL); - } - ccid_poll (ccid); - - - return 0; -} - -/* - * Local Variables: - * compile-command: "gcc -DTEST -Wall -I/usr/local/include -lusb -g ccid-driver.c" - * End: - */ -#endif /*TEST*/ -#endif /*HAVE_LIBUSB*/ diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h deleted file mode 100644 index 8b86eb1a5..000000000 --- a/scd/ccid-driver.h +++ /dev/null @@ -1,76 +0,0 @@ -/* ccid-driver.c - USB ChipCardInterfaceDevices driver - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * ALTERNATIVELY, this file may be distributed under the terms of the - * following license, in which case the provisions of this license are - * required INSTEAD OF the GNU General Public License. If you wish to - * allow use of your version of this file only under the terms of the - * GNU General Public License, and not to allow others to use your - * version of this file under the terms of the following license, - * indicate your decision by deleting this paragraph and the license - * below. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CCID_DRIVER_H -#define CCID_DRIVER_H - - -struct ccid_driver_s; -typedef struct ccid_driver_s *ccid_driver_t; - -int ccid_open_reader (ccid_driver_t *handle, int readerno); -int ccid_close_reader (ccid_driver_t handle); -int ccid_get_atr (ccid_driver_t handle, - unsigned char *atr, size_t maxatrlen, size_t *atrlen); -int ccid_slot_status (ccid_driver_t handle, int *statusbits); -int ccid_transceive (ccid_driver_t handle, - const unsigned char *apdu, size_t apdulen, - unsigned char *resp, size_t maxresplen, size_t *nresp); - - - -#endif /*CCID_DRIVER_H*/ - - - diff --git a/scd/command.c b/scd/command.c deleted file mode 100644 index 6fa100ff9..000000000 --- a/scd/command.c +++ /dev/null @@ -1,1268 +0,0 @@ -/* command.c - SCdaemon command handler - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#include <signal.h> - -#include <assuan.h> - -#include "scdaemon.h" -#include <ksba.h> -#include "app-common.h" -#include "apdu.h" /* Required for apdu_*_reader (). */ - -/* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */ -#define MAXLEN_PIN 100 - - -/* We keep track of the primary client using scdaemon. This one will - for example receive signal on card change. */ -static ctrl_t primary_connection; - - -#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t)) - -/* Data used to associate an Assuan context with local server data */ -struct server_local_s { - ASSUAN_CONTEXT assuan_ctx; - int event_signal; /* Or 0 if not used. */ -}; - - -/* Check whether the option NAME appears in LINE */ -static int -has_option (const char *line, const char *name) -{ - const char *s; - int n = strlen (name); - - s = strstr (line, name); - return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); -} - - -/* Reset the card and free the application context. With DO_CLOSE set - to true, close the reader and don't do just a reset. */ -static void -do_reset (ctrl_t ctrl, int do_close) -{ - if (ctrl->card_ctx) - { - card_close (ctrl->card_ctx); - ctrl->card_ctx = NULL; - xfree (ctrl->in_data.value); - ctrl->in_data.value = NULL; - } - if (ctrl->app_ctx) - { - release_application (ctrl->app_ctx); - ctrl->app_ctx = NULL; - } - if (ctrl->reader_slot != -1) - { - if (do_close || apdu_reset (ctrl->reader_slot)) - { - apdu_close_reader (ctrl->reader_slot); - ctrl->reader_slot = -1; - } - } -} - - -static void -reset_notify (ASSUAN_CONTEXT ctx) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - do_reset (ctrl, 0); -} - - -static int -option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value) -{ - ctrl_t ctrl = assuan_get_pointer (ctx); - - if (!strcmp (key, "event-signal")) - { - /* A value of 0 is allowed to reset the event signal. */ - int i = *value? atoi (value) : -1; - if (i < 0) - return ASSUAN_Parameter_Error; - ctrl->server_local->event_signal = i; - } - - return 0; -} - - -/* If the card has not yet been opened, do it. Note that this - function returns an Assuan error, so don't map the error a second - time */ -static AssuanError -open_card (ctrl_t ctrl, const char *apptype) -{ - int slot; - - if (ctrl->app_ctx) - return 0; /* Already initialized for one specific application. */ - if (ctrl->card_ctx) - return 0; /* Already initialized using a card context. */ - - if (ctrl->reader_slot != -1) - slot = ctrl->reader_slot; - else - slot = apdu_open_reader (opt.reader_port); - ctrl->reader_slot = slot; - if (slot != -1) - ctrl->app_ctx = select_application (ctrl, slot, apptype); - if (!ctrl->app_ctx) - { /* No application found - fall back to old mode. */ - /* Note that we should rework the old code to use the - application paradigma too. */ - int rc; - - /* If an APPTYPE was requested and it is not pkcs#15, we return - an error here. */ - if (apptype && !(!strcmp (apptype, "P15") || !strcmp (apptype, "p15"))) - rc = gpg_error (GPG_ERR_NOT_SUPPORTED); - else - rc = card_open (&ctrl->card_ctx); - if (rc) - return map_to_assuan_status (rc); - } - return 0; -} - - -/* Do the percent and plus/space unescaping in place and return the - length of the valid buffer. */ -static size_t -percent_plus_unescape (unsigned char *string) -{ - unsigned char *p = string; - size_t n = 0; - - while (*string) - { - if (*string == '%' && string[1] && string[2]) - { - string++; - *p++ = xtoi_2 (string); - n++; - string+= 2; - } - else if (*string == '+') - { - *p++ = ' '; - n++; - string++; - } - else - { - *p++ = *string++; - n++; - } - } - - return n; -} - - - -/* SERIALNO [APPTYPE] - - Return the serial number of the card using a status reponse. This - functon should be used to check for the presence of a card. - - If APPTYPE is given, an application of that type is selected and an - error is returned if the application is not supported or available. - The default is to auto-select the application using a hardwired - preference system. Note, that a future extension to this function - may allow to specify a list and order of applications to try. - - This function is special in that it can be used to reset the card. - Most other functions will return an error when a card change has - been detected and the use of this function is therefore required. - - Background: We want to keep the client clear of handling card - changes between operations; i.e. the client can assume that all - operations are done on the same card unless he calls this function. - */ -static int -cmd_serialno (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc = 0; - char *serial_and_stamp; - char *serial; - time_t stamp; - - if ((rc = open_card (ctrl, *line? line:NULL))) - return rc; - - if (ctrl->app_ctx) - rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp); - else - rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp); - if (rc) - return map_to_assuan_status (rc); - rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp); - xfree (serial); - if (rc < 0) - return ASSUAN_Out_Of_Core; - rc = 0; - assuan_write_status (ctx, "SERIALNO", serial_and_stamp); - free (serial_and_stamp); - return 0; -} - - - - -/* LEARN [--force] - - Learn all useful information of the currently inserted card. When - used without the force options, the command might do an INQUIRE - like this: - - INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp> - - The client should just send an "END" if the processing should go on - or a "CANCEL" to force the function to terminate with a Cancel - error message. The response of this command is a list of status - lines formatted as this: - - S APPTYPE <apptype> - - This returns the type of the application, currently the strings: - - P15 = PKCS-15 structure used - DINSIG = DIN SIG - OPENPGP = OpenPGP card - - are implemented. These strings are aliases for the AID - - S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id> - - If there is no certificate yet stored on the card a single "X" is - returned as the keygrip. In addition to the keypair info, information - about all certificates stored on the card is also returned: - - S CERTINFO <certtype> <hexstring_with_id> - - Where CERTTYPE is a number indicating the type of certificate: - 0 := Unknown - 100 := Regular X.509 cert - 101 := Trusted X.509 cert - 102 := Useful X.509 cert - 110 := Root CA cert (DINSIG) - - For certain cards, more information will be returned: - - S KEY-FPR <no> <hexstring> - - For OpenPGP cards this returns the stored fingerprints of the - keys. This can be used check whether a key is available on the - card. NO may be 1, 2 or 3. - - S CA-FPR <no> <hexstring> - - Similar to above, these are the fingerprints of keys assumed to be - ultimately trusted. - - S DISP-NAME <name_of_card_holder> - - The name of the card holder as stored on the card; percent - escaping takes place, spaces are encoded as '+' - - S PUBKEY-URL <url> - - The URL to be used for locating the entire public key. - -*/ -static int -cmd_learn (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc = 0; - int idx; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - /* Unless the force option is used we try a shortcut by identifying - the card using a serial number and inquiring the client with - that. The client may choose to cancel the operation if he already - knows about this card */ - { - char *serial_and_stamp; - char *serial; - time_t stamp; - - if (ctrl->app_ctx) - rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp); - else - rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp); - if (rc) - return map_to_assuan_status (rc); - rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp); - xfree (serial); - if (rc < 0) - return ASSUAN_Out_Of_Core; - rc = 0; - assuan_write_status (ctx, "SERIALNO", serial_and_stamp); - - if (!has_option (line, "--force")) - { - char *command; - - rc = asprintf (&command, "KNOWNCARDP %s", serial_and_stamp); - if (rc < 0) - { - free (serial_and_stamp); - return ASSUAN_Out_Of_Core; - } - rc = 0; - rc = assuan_inquire (ctx, command, NULL, NULL, 0); - free (command); /* (must use standard free here) */ - if (rc) - { - if (rc != ASSUAN_Canceled) - log_error ("inquire KNOWNCARDP failed: %s\n", - assuan_strerror (rc)); - free (serial_and_stamp); - return rc; - } - /* not canceled, so we have to proceeed */ - } - free (serial_and_stamp); - } - - /* If we are using the modern application paradigma, let the - application print out its collection of useful status - information. */ - if (!rc && ctrl->app_ctx) - rc = app_write_learn_status (ctrl->app_ctx, ctrl); - - /* Return information about the certificates. FIXME: Move this into - an app-p15.c*/ - for (idx=0; !rc && !ctrl->app_ctx; idx++) - { - char *certid; - int certtype; - - rc = card_enum_certs (ctrl->card_ctx, idx, &certid, &certtype); - if (!rc) - { - char *buf; - - buf = xtrymalloc (40 + 1 + strlen (certid) + 1); - if (!buf) - rc = gpg_error (gpg_err_code_from_errno (errno)); - else - { - sprintf (buf, "%d %s", certtype, certid); - assuan_write_status (ctx, "CERTINFO", buf); - xfree (buf); - } - } - xfree (certid); - } - if (rc == -1) - rc = 0; - - /* Return information about the keys. FIXME: Move this into an - app-p15.c */ - for (idx=0; !rc && !ctrl->app_ctx; idx++) - { - unsigned char keygrip[20]; - char *keyid; - int no_cert = 0; - - rc = card_enum_keypairs (ctrl->card_ctx, idx, keygrip, &keyid); - if (gpg_err_code (rc) == GPG_ERR_MISSING_CERT && keyid) - { - /* This does happen with an incomplete personalized - card; i.e. during the time we have stored the key on the - card but not stored the certificate; probably becuase it - has not yet been received back from the CA. Note that we - must release KEYID in this case. */ - rc = 0; - no_cert = 1; - } - if (!rc) - { - char *buf, *p; - - buf = p = xtrymalloc (40 + 1 + strlen (keyid) + 1); - if (!buf) - rc = gpg_error (gpg_err_code_from_errno (errno)); - else - { - int i; - - if (no_cert) - *p++ = 'X'; - else - { - for (i=0; i < 20; i++, p += 2) - sprintf (p, "%02X", keygrip[i]); - } - *p++ = ' '; - strcpy (p, keyid); - assuan_write_status (ctx, "KEYPAIRINFO", buf); - xfree (buf); - } - } - xfree (keyid); - } - if (rc == -1) - rc = 0; - - return map_to_assuan_status (rc); -} - - - -/* READCERT <hexified_certid> - - */ -static int -cmd_readcert (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - unsigned char *cert; - size_t ncert; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - line = xstrdup (line); /* Need a copy of the line. */ - if (ctrl->app_ctx) - { - rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert); - if (rc) - log_error ("app_readcert failed: %s\n", gpg_strerror (rc)); - } - else - { - rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert); - if (rc) - log_error ("card_read_cert failed: %s\n", gpg_strerror (rc)); - } - xfree (line); - line = NULL; - if (!rc) - { - rc = assuan_send_data (ctx, cert, ncert); - xfree (cert); - if (rc) - return rc; - } - - return map_to_assuan_status (rc); -} - - -/* READKEY <hexified_certid> - - Return the public key for the given cert or key ID as an standard - S-Expression. */ -static int -cmd_readkey (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - unsigned char *cert = NULL; - size_t ncert, n; - ksba_cert_t kc = NULL; - ksba_sexp_t p; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - line = xstrdup (line); /* Need a copy of the line. */ - if (ctrl->app_ctx) - { - rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert); - if (rc) - log_error ("app_readcert failed: %s\n", gpg_strerror (rc)); - } - else - { - rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert); - if (rc) - log_error ("card_read_cert failed: %s\n", gpg_strerror (rc)); - } - xfree (line); - line = NULL; - if (rc) - goto leave; - - rc = ksba_cert_new (&kc); - if (rc) - { - xfree (cert); - goto leave; - } - rc = ksba_cert_init_from_mem (kc, cert, ncert); - if (rc) - { - log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc)); - goto leave; - } - - p = ksba_cert_get_public_key (kc); - if (!p) - { - rc = gpg_error (GPG_ERR_NO_PUBKEY); - goto leave; - } - - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - rc = assuan_send_data (ctx, p, n); - rc = map_assuan_err (rc); - xfree (p); - - - leave: - ksba_cert_release (kc); - xfree (cert); - return map_to_assuan_status (rc); -} - - - - -/* SETDATA <hexstring> - - The client should use this command to tell us the data he want to - sign. */ -static int -cmd_setdata (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int n; - char *p; - unsigned char *buf; - - /* parse the hexstring */ - for (p=line,n=0; hexdigitp (p); p++, n++) - ; - if (*p) - return set_error (Parameter_Error, "invalid hexstring"); - if (!n) - return set_error (Parameter_Error, "no data given"); - if ((n&1)) - return set_error (Parameter_Error, "odd number of digits"); - n /= 2; - buf = xtrymalloc (n); - if (!buf) - return ASSUAN_Out_Of_Core; - - ctrl->in_data.value = buf; - ctrl->in_data.valuelen = n; - for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++) - buf[n] = xtoi_2 (p); - return 0; -} - - - -static int -pin_cb (void *opaque, const char *info, char **retstr) -{ - ASSUAN_CONTEXT ctx = opaque; - char *command; - int rc; - unsigned char *value; - size_t valuelen; - - *retstr = NULL; - log_debug ("asking for PIN '%s'\n", info); - - rc = asprintf (&command, "NEEDPIN %s", info); - if (rc < 0) - return gpg_error (gpg_err_code_from_errno (errno)); - - /* FIXME: Write an inquire function which returns the result in - secure memory */ - rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); - free (command); - if (rc) - return map_assuan_err (rc); - - if (!valuelen || value[valuelen-1]) - { - /* We require that the returned value is an UTF-8 string */ - xfree (value); - return gpg_error (GPG_ERR_INV_RESPONSE); - } - *retstr = value; - return 0; -} - - -/* PKSIGN <hexified_id> - - */ -static int -cmd_pksign (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - unsigned char *outdata; - size_t outdatalen; - char *keyidstr; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - /* We have to use a copy of the key ID because the function may use - the pin_cb which in turn uses the assuan line buffer and thus - overwriting the original line with the keyid */ - keyidstr = xtrystrdup (line); - if (!keyidstr) - return ASSUAN_Out_Of_Core; - - if (ctrl->app_ctx) - rc = app_sign (ctrl->app_ctx, - keyidstr, GCRY_MD_SHA1, - pin_cb, ctx, - ctrl->in_data.value, ctrl->in_data.valuelen, - &outdata, &outdatalen); - else - rc = card_sign (ctrl->card_ctx, - keyidstr, GCRY_MD_SHA1, - pin_cb, ctx, - ctrl->in_data.value, ctrl->in_data.valuelen, - &outdata, &outdatalen); - xfree (keyidstr); - if (rc) - { - log_error ("card_sign failed: %s\n", gpg_strerror (rc)); - } - else - { - rc = assuan_send_data (ctx, outdata, outdatalen); - xfree (outdata); - if (rc) - return rc; /* that is already an assuan error code */ - } - - return map_to_assuan_status (rc); -} - -/* PKAUTH <hexified_id> - - */ -static int -cmd_pkauth (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - unsigned char *outdata; - size_t outdatalen; - char *keyidstr; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - if (!ctrl->app_ctx) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - /* We have to use a copy of the key ID because the function may use - the pin_cb which in turn uses the assuan line buffer and thus - overwriting the original line with the keyid */ - keyidstr = xtrystrdup (line); - if (!keyidstr) - return ASSUAN_Out_Of_Core; - - rc = app_auth (ctrl->app_ctx, - keyidstr, - pin_cb, ctx, - ctrl->in_data.value, ctrl->in_data.valuelen, - &outdata, &outdatalen); - xfree (keyidstr); - if (rc) - { - log_error ("app_auth_sign failed: %s\n", gpg_strerror (rc)); - } - else - { - rc = assuan_send_data (ctx, outdata, outdatalen); - xfree (outdata); - if (rc) - return rc; /* that is already an assuan error code */ - } - - return map_to_assuan_status (rc); -} - -/* PKDECRYPT <hexified_id> - - */ -static int -cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - unsigned char *outdata; - size_t outdatalen; - char *keyidstr; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - keyidstr = xtrystrdup (line); - if (!keyidstr) - return ASSUAN_Out_Of_Core; - if (ctrl->app_ctx) - rc = app_decipher (ctrl->app_ctx, - keyidstr, - pin_cb, ctx, - ctrl->in_data.value, ctrl->in_data.valuelen, - &outdata, &outdatalen); - else - rc = card_decipher (ctrl->card_ctx, - keyidstr, - pin_cb, ctx, - ctrl->in_data.value, ctrl->in_data.valuelen, - &outdata, &outdatalen); - xfree (keyidstr); - if (rc) - { - log_error ("card_create_signature failed: %s\n", gpg_strerror (rc)); - } - else - { - rc = assuan_send_data (ctx, outdata, outdatalen); - xfree (outdata); - if (rc) - return rc; /* that is already an assuan error code */ - } - - return map_to_assuan_status (rc); -} - - -/* GETATTR <name> - - This command is used to retrieve data from a smartcard. The - allowed names depend on the currently selected smartcard - application. NAME must be percent and '+' escaped. The value is - returned through status message, see the LESRN command for details. - - However, the current implementation assumes that Name is not escaped; - this works as long as noone uses arbitrary escaping. - -*/ -static int -cmd_getattr (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - char *keyword; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - keyword = line; - for (; *line && !spacep (line); line++) - ; - if (*line) - *line++ = 0; - - /* (We ignore any garbage for now.) */ - - rc = app_getattr (ctrl->app_ctx, ctrl, keyword); - - return map_to_assuan_status (rc); -} - - -/* SETATTR <name> <value> - - This command is used to store data on a a smartcard. The allowed - names and values are depend on the currently selected smartcard - application. NAME and VALUE must be percent and '+' escaped. - - However, the curent implementation assumes that Name is not escaped; - this works as long as noone uses arbitrary escaping. - - A PIN will be requested for most NAMEs. See the corresponding - setattr function of the actually used application (app-*.c) for - details. */ -static int -cmd_setattr (ASSUAN_CONTEXT ctx, char *orig_line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - char *keyword; - int keywordlen; - size_t nbytes; - char *line, *linebuf; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - /* We need to use a copy of LINE, because PIN_CB uses the same - context and thus reuses the Assuan provided LINE. */ - line = linebuf = xtrystrdup (orig_line); - if (!line) - return ASSUAN_Out_Of_Core; - - keyword = line; - for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) - ; - if (*line) - *line++ = 0; - while (spacep (line)) - line++; - nbytes = percent_plus_unescape (line); - - rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, line, nbytes); - xfree (linebuf); - - return map_to_assuan_status (rc); -} - -/* GENKEY [--force] <no> - - Generate a key on-card identified by NO, which is application - specific. Return values are application specific. For OpenPGP - cards 2 status lines are returned: - - S KEY-FPR <hexstring> - S KEY-CREATED-AT <seconds_since_epoch> - S KEY-DATA [p|n] <hexdata> - - - --force is required to overwriet an already existing key. The - KEY-CREATED-AT is required for further processing because it is - part of the hashed key material for the fingerprint. - - The public part of the key can also later be retrieved using the - READKEY command. - - */ -static int -cmd_genkey (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - char *keyno; - int force = has_option (line, "--force"); - - /* Skip over options. */ - while ( *line == '-' && line[1] == '-' ) - { - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; - } - if (!*line) - return set_error (Parameter_Error, "no key number given"); - keyno = line; - while (*line && !spacep (line)) - line++; - *line = 0; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - if (!ctrl->app_ctx) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - keyno = xtrystrdup (keyno); - if (!keyno) - return ASSUAN_Out_Of_Core; - rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, pin_cb, ctx); - xfree (keyno); - return map_to_assuan_status (rc); -} - - -/* RANDOM <nbytes> - - Get NBYTES of random from the card and send them back as data. -*/ -static int -cmd_random (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - size_t nbytes; - unsigned char *buffer; - - if (!*line) - return set_error (Parameter_Error, "number of requested bytes missing"); - nbytes = strtoul (line, NULL, 0); - - if ((rc = open_card (ctrl, NULL))) - return rc; - - if (!ctrl->app_ctx) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - buffer = xtrymalloc (nbytes); - if (!buffer) - return ASSUAN_Out_Of_Core; - - rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer); - if (!rc) - { - rc = assuan_send_data (ctx, buffer, nbytes); - xfree (buffer); - return rc; /* that is already an assuan error code */ - } - xfree (buffer); - - return map_to_assuan_status (rc); -} - - -/* PASSWD [--reset] <chvno> - - Change the PIN or reset thye retry counter of the card holder - verfication vector CHVNO. */ -static int -cmd_passwd (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - char *chvnostr; - int reset_mode = has_option (line, "--reset"); - - /* Skip over options. */ - while (*line == '-' && line[1] == '-') - { - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; - } - if (!*line) - return set_error (Parameter_Error, "no CHV number given"); - chvnostr = line; - while (*line && !spacep (line)) - line++; - *line = 0; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - if (!ctrl->app_ctx) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - chvnostr = xtrystrdup (chvnostr); - if (!chvnostr) - return ASSUAN_Out_Of_Core; - rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, reset_mode, pin_cb, ctx); - if (rc) - log_error ("command passwd failed: %s\n", gpg_strerror (rc)); - xfree (chvnostr); - return map_to_assuan_status (rc); -} - - -/* CHECKPIN <hexified_id> - - */ -static int -cmd_checkpin (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - char *keyidstr; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - if (!ctrl->app_ctx) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - /* We have to use a copy of the key ID because the function may use - the pin_cb which in turn uses the assuan line buffer and thus - overwriting the original line with the keyid. */ - keyidstr = xtrystrdup (line); - if (!keyidstr) - return ASSUAN_Out_Of_Core; - - rc = app_check_pin (ctrl->app_ctx, - keyidstr, - pin_cb, ctx); - xfree (keyidstr); - if (rc) - log_error ("app_check_pin failed: %s\n", gpg_strerror (rc)); - - return map_to_assuan_status (rc); -} - - - - - -/* Tell the assuan library about our commands */ -static int -register_commands (ASSUAN_CONTEXT ctx) -{ - static struct { - const char *name; - int (*handler)(ASSUAN_CONTEXT, char *line); - } table[] = { - { "SERIALNO", cmd_serialno }, - { "LEARN", cmd_learn }, - { "READCERT", cmd_readcert }, - { "READKEY", cmd_readkey }, - { "SETDATA", cmd_setdata }, - { "PKSIGN", cmd_pksign }, - { "PKAUTH", cmd_pkauth }, - { "PKDECRYPT", cmd_pkdecrypt }, - { "INPUT", NULL }, - { "OUTPUT", NULL }, - { "GETATTR", cmd_getattr }, - { "SETATTR", cmd_setattr }, - { "GENKEY", cmd_genkey }, - { "RANDOM", cmd_random }, - { "PASSWD", cmd_passwd }, - { "CHECKPIN", cmd_checkpin }, - { NULL } - }; - int i, rc; - - for (i=0; table[i].name; i++) - { - rc = assuan_register_command (ctx, table[i].name, table[i].handler); - if (rc) - return rc; - } - assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready"); - - assuan_register_reset_notify (ctx, reset_notify); - assuan_register_option_handler (ctx, option_handler); - return 0; -} - - -/* Startup the server. If LISTEN_FD is given as -1, this is simple - piper server, otherwise it is a regular server */ -void -scd_command_handler (int listen_fd) -{ - int rc; - ASSUAN_CONTEXT ctx; - struct server_control_s ctrl; - - memset (&ctrl, 0, sizeof ctrl); - scd_init_default_ctrl (&ctrl); - - if (listen_fd == -1) - { - int filedes[2]; - - filedes[0] = 0; - filedes[1] = 1; - rc = assuan_init_pipe_server (&ctx, filedes); - } - else - { - rc = assuan_init_socket_server (&ctx, listen_fd); - } - if (rc) - { - log_error ("failed to initialize the server: %s\n", - assuan_strerror(rc)); - scd_exit (2); - } - rc = register_commands (ctx); - if (rc) - { - log_error ("failed to register commands with Assuan: %s\n", - assuan_strerror(rc)); - scd_exit (2); - } - assuan_set_pointer (ctx, &ctrl); - ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local); - ctrl.server_local->assuan_ctx = ctx; - - if (DBG_ASSUAN) - assuan_set_log_stream (ctx, log_get_stream ()); - - /* Store the primary connection's assuan context. */ - if (!primary_connection) - primary_connection = &ctrl; - - /* We open the reader right at startup so that the ticker is able to - update the status file. */ - if (ctrl.reader_slot == -1) - ctrl.reader_slot = apdu_open_reader (opt.reader_port); - - /* Command processing loop. */ - for (;;) - { - rc = assuan_accept (ctx); - if (rc == -1) - { - break; - } - else if (rc) - { - log_info ("Assuan accept problem: %s\n", assuan_strerror (rc)); - break; - } - - rc = assuan_process (ctx); - if (rc) - { - log_info ("Assuan processing failed: %s\n", assuan_strerror (rc)); - continue; - } - } - - /* The next client will be the primary conenction if this one - terminates. */ - if (primary_connection == &ctrl) - primary_connection = NULL; - - do_reset (&ctrl, 1); /* Cleanup. */ - - assuan_deinit_server (ctx); -} - - -/* Send a line with status information via assuan and escape all given - buffers. The variable elements are pairs of (char *, size_t), - terminated with a (NULL, 0). */ -void -send_status_info (CTRL ctrl, const char *keyword, ...) -{ - va_list arg_ptr; - const unsigned char *value; - size_t valuelen; - char buf[950], *p; - size_t n; - ASSUAN_CONTEXT ctx = ctrl->server_local->assuan_ctx; - - va_start (arg_ptr, keyword); - - p = buf; - n = 0; - while ( (value = va_arg (arg_ptr, const unsigned char *)) ) - { - valuelen = va_arg (arg_ptr, size_t); - if (!valuelen) - continue; /* empty buffer */ - if (n) - { - *p++ = ' '; - n++; - } - for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++) - { - if (*value < ' ' || *value == '+') - { - sprintf (p, "%%%02X", *value); - p += 3; - } - else if (*value == ' ') - *p++ = '+'; - else - *p++ = *value; - } - } - *p = 0; - assuan_write_status (ctx, keyword, buf); - - va_end (arg_ptr); -} - - - -void -scd_update_reader_status_file (void) -{ - static struct { - int any; - unsigned int status; - unsigned int changed; - } last[10]; - int slot; - int used; - unsigned int status, changed; - - /* Note, that we only try to get the status, becuase it does not - make sense to wait here for a operation to complete. If we are - so busy working with the card, delays in the status file updated - are should be acceptable. */ - for (slot=0; (slot < DIM(last) - &&!apdu_enum_reader (slot, &used)); slot++) - if (used && !apdu_get_status (slot, 0, &status, &changed)) - { - if (!last[slot].any || last[slot].status != status - || last[slot].changed != changed ) - { - char *fname; - char templ[50]; - FILE *fp; - - last[slot].any = 1; - last[slot].status = status; - last[slot].changed = changed; - - log_info ("updating status of slot %d to 0x%04X\n", slot, status); - - sprintf (templ, "reader_%d.status", slot); - fname = make_filename (opt.homedir, templ, NULL ); - fp = fopen (fname, "w"); - if (fp) - { - fprintf (fp, "%s\n", - (status & 1)? "USABLE": - (status & 4)? "ACTIVE": - (status & 2)? "PRESENT": "NOCARD"); - fclose (fp); - } - xfree (fname); - - /* Send a signal to the primary client, if any. */ - if (primary_connection && primary_connection->server_local - && primary_connection->server_local->assuan_ctx) - { - pid_t pid = assuan_get_pid (primary_connection - ->server_local->assuan_ctx); - int signo = primary_connection->server_local->event_signal; - - log_info ("client pid is %d, sending signal %d\n", pid, signo); - if (pid != (pid_t)(-1) && pid && signo > 0) - kill (pid, signo); - } - } - } -} diff --git a/scd/iso7816.c b/scd/iso7816.c deleted file mode 100644 index fd3f0485c..000000000 --- a/scd/iso7816.c +++ /dev/null @@ -1,617 +0,0 @@ -/* iso7816.c - ISO 7816 commands - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if defined(GNUPG_SCD_MAIN_HEADER) -#include GNUPG_SCD_MAIN_HEADER -#elif GNUPG_MAJOR_VERSION == 1 -/* This is used with GnuPG version < 1.9. The code has been source - copied from the current GnuPG >= 1.9 and is maintained over - there. */ -#include "options.h" -#include "errors.h" -#include "memory.h" -#include "util.h" -#include "i18n.h" -#else /* GNUPG_MAJOR_VERSION != 1 */ -#include "scdaemon.h" -#endif /* GNUPG_MAJOR_VERSION != 1 */ - -#include "iso7816.h" -#include "apdu.h" - - -#define CMD_SELECT_FILE 0xA4 -#define CMD_VERIFY 0x20 -#define CMD_CHANGE_REFERENCE_DATA 0x24 -#define CMD_RESET_RETRY_COUNTER 0x2C -#define CMD_GET_DATA 0xCA -#define CMD_PUT_DATA 0xDA -#define CMD_MSE 0x22 -#define CMD_PSO 0x2A -#define CMD_INTERNAL_AUTHENTICATE 0x88 -#define CMD_GENERATE_KEYPAIR 0x47 -#define CMD_GET_CHALLENGE 0x84 -#define CMD_READ_BINARY 0xB0 -#define CMD_READ_RECORD 0xB2 - -static gpg_error_t -map_sw (int sw) -{ - gpg_err_code_t ec; - - switch (sw) - { - case SW_EEPROM_FAILURE: ec = GPG_ERR_HARDWARE; break; - case SW_WRONG_LENGTH: ec = GPG_ERR_INV_VALUE; break; - case SW_CHV_WRONG: ec = GPG_ERR_BAD_PIN; break; - case SW_CHV_BLOCKED: ec = GPG_ERR_PIN_BLOCKED; break; - case SW_USE_CONDITIONS: ec = GPG_ERR_USE_CONDITIONS; break; - case SW_NOT_SUPPORTED: ec = GPG_ERR_NOT_SUPPORTED; break; - case SW_BAD_PARAMETER: ec = GPG_ERR_INV_VALUE; break; - case SW_FILE_NOT_FOUND: ec = GPG_ERR_ENOENT; break; - case SW_RECORD_NOT_FOUND:ec= GPG_ERR_NOT_FOUND; break; - case SW_REF_NOT_FOUND: ec = GPG_ERR_NO_OBJ; break; - case SW_BAD_P0_P1: ec = GPG_ERR_INV_VALUE; break; - case SW_INS_NOT_SUP: ec = GPG_ERR_CARD; break; - case SW_CLA_NOT_SUP: ec = GPG_ERR_CARD; break; - case SW_SUCCESS: ec = 0; break; - - case SW_HOST_OUT_OF_CORE: ec = GPG_ERR_ENOMEM; break; - case SW_HOST_INV_VALUE: ec = GPG_ERR_INV_VALUE; break; - case SW_HOST_INCOMPLETE_CARD_RESPONSE: ec = GPG_ERR_CARD; break; - case SW_HOST_NOT_SUPPORTED: ec = GPG_ERR_NOT_SUPPORTED; break; - case SW_HOST_LOCKING_FAILED: ec = GPG_ERR_BUG; break; - case SW_HOST_BUSY: ec = GPG_ERR_EBUSY; break; - default: - if ((sw & 0x010000)) - ec = GPG_ERR_GENERAL; /* Should not happen. */ - else if ((sw & 0xff00) == SW_MORE_DATA) - ec = 0; /* This should actually never been seen here. */ - else - ec = GPG_ERR_CARD; - } - return gpg_error (ec); -} - -/* This function is specialized version of the SELECT FILE command. - SLOT is the card and reader as created for example by - apdu_open_reader (), AID is a buffer of size AIDLEN holding the - requested application ID. The function can't be used to enumerate - AIDs and won't return the AID on success. The return value is 0 - for okay or a GPG error code. Note that ISO error codes are - internally mapped. */ -gpg_error_t -iso7816_select_application (int slot, const char *aid, size_t aidlen) -{ - static char const openpgp_aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 }; - int sw; - int p1 = 0x0C; /* No FCI to be returned. */ - - if (aidlen == sizeof openpgp_aid - && !memcmp (aid, openpgp_aid, sizeof openpgp_aid)) - p1 = 0; /* The current openpgp cards don't allow 0x0c. */ - - sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, 4, p1, aidlen, aid); - return map_sw (sw); -} - - -gpg_error_t -iso7816_select_file (int slot, int tag, int is_dir, - unsigned char **result, size_t *resultlen) -{ - int sw, p0, p1; - unsigned char tagbuf[2]; - - tagbuf[0] = (tag >> 8) & 0xff; - tagbuf[1] = tag & 0xff; - - if (result || resultlen) - { - *result = NULL; - *resultlen = 0; - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); - } - else - { - p0 = (tag == 0x3F00)? 0: is_dir? 1:2; - p1 = 0x0c; /* No FC return. */ - sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, - p0, p1, 2, tagbuf ); - return map_sw (sw); - } - - return 0; -} - - -/* This is a private command currently only working for TCOS cards. */ -gpg_error_t -iso7816_list_directory (int slot, int list_dirs, - unsigned char **result, size_t *resultlen) -{ - int sw; - - if (!result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - sw = apdu_send (slot, 0x80, 0xAA, list_dirs? 1:2, 0, -1, NULL, - result, resultlen); - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (*result); - *result = NULL; - *resultlen = 0; - } - return map_sw (sw); -} - - - -/* Perform a VERIFY command on SLOT using the card holder verification - vector CHVNO with a CHV of lenght CHVLEN. Returns 0 on success. */ -gpg_error_t -iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen) -{ - int sw; - - sw = apdu_send_simple (slot, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv); - return map_sw (sw); -} - -/* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder - verification vector CHVNO. If the OLDCHV is NULL (and OLDCHVLEN - 0), a "change reference data" is done, otherwise an "exchange - reference data". The new reference data is expected in NEWCHV of - length NEWCHVLEN. */ -gpg_error_t -iso7816_change_reference_data (int slot, int chvno, - const char *oldchv, size_t oldchvlen, - const char *newchv, size_t newchvlen) -{ - int sw; - char *buf; - - if ((!oldchv && oldchvlen) - || (oldchv && !oldchvlen) - || !newchv || !newchvlen ) - return gpg_error (GPG_ERR_INV_VALUE); - - buf = xtrymalloc (oldchvlen + newchvlen); - if (!buf) - return gpg_error (gpg_err_code_from_errno (errno)); - if (oldchvlen) - memcpy (buf, oldchv, oldchvlen); - memcpy (buf+oldchvlen, newchv, newchvlen); - - sw = apdu_send_simple (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, - oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf); - xfree (buf); - return map_sw (sw); - -} - -gpg_error_t -iso7816_reset_retry_counter (int slot, int chvno, - const char *newchv, size_t newchvlen) -{ - int sw; - - if (!newchv || !newchvlen ) - return gpg_error (GPG_ERR_INV_VALUE); - - sw = apdu_send_simple (slot, 0x00, CMD_RESET_RETRY_COUNTER, - 2, chvno, newchvlen, newchv); - return map_sw (sw); -} - - -/* Perform a GET DATA command requesting TAG and storing the result in - a newly allocated buffer at the address passed by RESULT. Return - the length of this data at the address of RESULTLEN. */ -gpg_error_t -iso7816_get_data (int slot, int tag, - unsigned char **result, size_t *resultlen) -{ - int sw; - - if (!result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - sw = apdu_send (slot, 0x00, CMD_GET_DATA, - ((tag >> 8) & 0xff), (tag & 0xff), -1, NULL, - result, resultlen); - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - - return 0; -} - - -/* Perform a PUT DATA command on card in SLOT. Write DATA of length - DATALEN to TAG. */ -gpg_error_t -iso7816_put_data (int slot, int tag, - const unsigned char *data, size_t datalen) -{ - int sw; - - sw = apdu_send_simple (slot, 0x00, CMD_PUT_DATA, - ((tag >> 8) & 0xff), (tag & 0xff), - datalen, data); - return map_sw (sw); -} - -/* Manage Security Environment. This is a weird operation and there - is no easy abstraction for it. Furthermore, some card seem to have - a different interpreation of 7816-8 and thus we resort to let the - caller decide what to do. */ -gpg_error_t -iso7816_manage_security_env (int slot, int p1, int p2, - const unsigned char *data, size_t datalen) -{ - int sw; - - if (p1 < 0 || p1 > 255 || p2 < 0 || p2 > 255 || !data || !datalen) - return gpg_error (GPG_ERR_INV_VALUE); - - sw = apdu_send_simple (slot, 0x00, CMD_MSE, p1, p2, datalen, data); - return map_sw (sw); -} - - -/* Perform the security operation COMPUTE DIGITAL SIGANTURE. On - success 0 is returned and the data is availavle in a newly - allocated buffer stored at RESULT with its length stored at - RESULTLEN. */ -gpg_error_t -iso7816_compute_ds (int slot, const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen) -{ - int sw; - - if (!data || !datalen || !result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - sw = apdu_send (slot, 0x00, CMD_PSO, 0x9E, 0x9A, datalen, data, - result, resultlen); - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - - return 0; -} - - -/* Perform the security operation DECIPHER. PADIND is the padding - indicator to be used. It should be 0 if no padding is required, a - value of -1 suppresses the padding byte. On success 0 is returned - and the plaintext is available in a newly allocated buffer stored - at RESULT with its length stored at RESULTLEN. */ -gpg_error_t -iso7816_decipher (int slot, const unsigned char *data, size_t datalen, - int padind, unsigned char **result, size_t *resultlen) -{ - int sw; - unsigned char *buf; - - if (!data || !datalen || !result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - if (padind >= 0) - { - /* We need to prepend the padding indicator. */ - buf = xtrymalloc (datalen + 1); - if (!buf) - return gpg_error (gpg_err_code_from_errno (errno)); - - *buf = padind; /* Padding indicator. */ - memcpy (buf+1, data, datalen); - sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, datalen+1, buf, - result, resultlen); - xfree (buf); - } - else - { - sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, datalen, data, - result, resultlen); - } - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - - return 0; -} - - -gpg_error_t -iso7816_internal_authenticate (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen) -{ - int sw; - - if (!data || !datalen || !result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - sw = apdu_send (slot, 0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0, - datalen, data, result, resultlen); - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - - return 0; -} - - -static gpg_error_t -do_generate_keypair (int slot, int readonly, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen) -{ - int sw; - - if (!data || !datalen || !result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - sw = apdu_send (slot, 0x00, CMD_GENERATE_KEYPAIR, readonly? 0x81:0x80, 0, - datalen, data, result, resultlen); - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - - return 0; -} - - -gpg_error_t -iso7816_generate_keypair (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen) -{ - return do_generate_keypair (slot, 0, data, datalen, result, resultlen); -} - - -gpg_error_t -iso7816_read_public_key (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen) -{ - return do_generate_keypair (slot, 1, data, datalen, result, resultlen); -} - - - -gpg_error_t -iso7816_get_challenge (int slot, int length, unsigned char *buffer) -{ - int sw; - unsigned char *result; - size_t resultlen, n; - - if (!buffer || length < 1) - return gpg_error (GPG_ERR_INV_VALUE); - - do - { - result = NULL; - n = length > 254? 254 : length; - sw = apdu_send_le (slot, 0x00, CMD_GET_CHALLENGE, 0, 0, -1, NULL, - n, - &result, &resultlen); - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (result); - return map_sw (sw); - } - if (resultlen > n) - resultlen = n; - memcpy (buffer, result, resultlen); - buffer += resultlen; - length -= resultlen; - xfree (result); - } - while (length > 0); - - return 0; -} - -/* Perform a READ BINARY command requesting a maximum of NMAX bytes - from OFFSET. With NMAX = 0 the entire file is read. The result is - stored in a newly allocated buffer at the address passed by RESULT. - Returns the length of this data at the address of RESULTLEN. */ -gpg_error_t -iso7816_read_binary (int slot, size_t offset, size_t nmax, - unsigned char **result, size_t *resultlen) -{ - int sw; - unsigned char *buffer; - size_t bufferlen; - int read_all = !nmax; - size_t n; - - if (!result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus - we check for this limit. */ - if (offset > 32767) - return gpg_error (GPG_ERR_INV_VALUE); - - do - { - buffer = NULL; - bufferlen = 0; - /* Fixme: Either the ccid driver or the TCOS cards have problems - with an Le of 0. */ - if (read_all || nmax > 254) - n = 254; - else - n = nmax; - sw = apdu_send_le (slot, 0x00, CMD_READ_BINARY, - ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL, - n, &buffer, &bufferlen); - - if (sw != SW_SUCCESS && sw != SW_EOF_REACHED) - { - /* Make sure that pending buffers are released. */ - xfree (buffer); - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - if (*result) /* Need to extend the buffer. */ - { - unsigned char *p = xtryrealloc (*result, *resultlen + bufferlen); - if (!p) - { - gpg_error_t err = gpg_error_from_errno (errno); - xfree (buffer); - xfree (*result); - *result = NULL; - *resultlen = 0; - return err; - } - *result = p; - memcpy (*result + *resultlen, buffer, bufferlen); - *resultlen += bufferlen; - xfree (buffer); - buffer = NULL; - } - else /* Transfer the buffer into our result. */ - { - *result = buffer; - *resultlen = bufferlen; - } - offset += bufferlen; - if (offset > 32767) - break; /* We simply truncate the result for too large - files. */ - if (nmax > bufferlen) - nmax -= bufferlen; - else - nmax = 0; - } - while ((read_all && sw != SW_EOF_REACHED) || (!read_all && nmax)); - - return 0; -} - -/* Perform a READ RECORD command. RECNO gives the record number to - read with 0 indicating the current record. RECCOUNT must be 1 (not - all cards support reading of more than one record). SHORT_EF - should be 0 to read the current EF or contain a short EF. The - result is stored in a newly allocated buffer at the address passed - by RESULT. Returns the length of this data at the address of - RESULTLEN. */ -gpg_error_t -iso7816_read_record (int slot, int recno, int reccount, int short_ef, - unsigned char **result, size_t *resultlen) -{ - int sw; - unsigned char *buffer; - size_t bufferlen; - - if (!result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus - we check for this limit. */ - if (recno < 0 || recno > 255 || reccount != 1 - || short_ef < 0 || short_ef > 254 ) - return gpg_error (GPG_ERR_INV_VALUE); - - buffer = NULL; - bufferlen = 0; - /* Fixme: Either the ccid driver of the TCOS cards have problems - with an Le of 0. */ - sw = apdu_send_le (slot, 0x00, CMD_READ_RECORD, - recno, - short_ef? short_ef : 0x04, - -1, NULL, - 254, &buffer, &bufferlen); - - if (sw != SW_SUCCESS && sw != SW_EOF_REACHED) - { - /* Make sure that pending buffers are released. */ - xfree (buffer); - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - *result = buffer; - *resultlen = bufferlen; - - return 0; -} - diff --git a/scd/iso7816.h b/scd/iso7816.h deleted file mode 100644 index 8f2b150e6..000000000 --- a/scd/iso7816.h +++ /dev/null @@ -1,73 +0,0 @@ -/* iso7816.h - ISO 7816 commands - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef ISO7816_H -#define ISO7816_H - -#if GNUPG_MAJOR_VERSION == 1 -#include "cardglue.h" -#endif - -gpg_error_t iso7816_select_application (int slot, - const char *aid, size_t aidlen); -gpg_error_t iso7816_select_file (int slot, int tag, int is_dir, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_list_directory (int slot, int list_dirs, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_verify (int slot, - int chvno, const char *chv, size_t chvlen); -gpg_error_t iso7816_change_reference_data (int slot, int chvno, - const char *oldchv, size_t oldchvlen, - const char *newchv, size_t newchvlen); -gpg_error_t iso7816_reset_retry_counter (int slot, int chvno, - const char *newchv, size_t newchvlen); -gpg_error_t iso7816_get_data (int slot, int tag, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_put_data (int slot, int tag, - const unsigned char *data, size_t datalen); -gpg_error_t iso7816_manage_security_env (int slot, int p1, int p2, - const unsigned char *data, - size_t datalen); -gpg_error_t iso7816_compute_ds (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_decipher (int slot, - const unsigned char *data, size_t datalen, - int padind, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_internal_authenticate (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_generate_keypair (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_read_public_key (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_get_challenge (int slot, - int length, unsigned char *buffer); - -gpg_error_t iso7816_read_binary (int slot, size_t offset, size_t nmax, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_read_record (int slot, int recno, int reccount, - int short_ef, - unsigned char **result, size_t *resultlen); - -#endif /*ISO7816_H*/ diff --git a/scd/pcsc-wrapper.c b/scd/pcsc-wrapper.c deleted file mode 100644 index 4f47ee95c..000000000 --- a/scd/pcsc-wrapper.c +++ /dev/null @@ -1,631 +0,0 @@ -/* pcsc-wrapper.c - Wrapper for ccessing the PC/SC service - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* - This wrapper is required to handle problems with the libpscslite - library. That library assumes that pthreads are used and fails - badly if one tries to use it with a procerss using Pth. - - The operation model is pretty simple: It reads requests from stdin - and returns the answer on stdout. There is no direct mapping to the - pcsc interface but to a higher level one which resembles the code - used in scdaemon (apdu.c) when not using Pth or while running under - Windows. - - The interface is binary consisting of a command tag and the length - of the parameter list. The calling process needs to pass the - version number of the interface on the command line to make sure - that both agree on the same interface. For each port a separate - instance of this process needs to be started. - -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <errno.h> -#include <stdarg.h> -#include <assert.h> -#include <dlfcn.h> - - -#define PGM "pcsc-wrapper" - -/* Allow for a standalone build. */ -#ifdef VERSION -#define MYVERSION_LINE PGM " (GnuPG) " VERSION -#define BUGREPORT_LINE "\nReport bugs to <bug-gnupg@gnu.org>.\n" -#else -#define MYVERSION_LINE PGM -#define BUGREPORT_LINE "" -#endif - -#define DEFAULT_PCSC_DRIVER "libpcsclite.so" - - -static int verbose; - - -/* PC/SC constants and function pointer. */ -#define PCSC_SCOPE_USER 0 -#define PCSC_SCOPE_TERMINAL 1 -#define PCSC_SCOPE_SYSTEM 2 -#define PCSC_SCOPE_GLOBAL 3 - -#define PCSC_PROTOCOL_T0 1 -#define PCSC_PROTOCOL_T1 2 -#define PCSC_PROTOCOL_RAW 4 - -#define PCSC_SHARE_EXCLUSIVE 1 -#define PCSC_SHARE_SHARED 2 -#define PCSC_SHARE_DIRECT 3 - -#define PCSC_LEAVE_CARD 0 -#define PCSC_RESET_CARD 1 -#define PCSC_UNPOWER_CARD 2 -#define PCSC_EJECT_CARD 3 - -struct pcsc_io_request_s { - unsigned long protocol; - unsigned long pci_len; -}; - -typedef struct pcsc_io_request_s *pcsc_io_request_t; - - -static int driver_is_open; /* True if the PC/SC driver has been - initialzied and is ready for - operations. The follwoing variables - are then valid. */ -static unsigned long pcsc_context; /* The current PC/CS context. */ -static unsigned long pcsc_card; -static unsigned long pcsc_protocol; -static unsigned char current_atr[33]; -static size_t current_atrlen; - -long (* pcsc_establish_context) (unsigned long scope, - const void *reserved1, - const void *reserved2, - unsigned long *r_context); -long (* pcsc_release_context) (unsigned long context); -long (* pcsc_list_readers) (unsigned long context, - const char *groups, - char *readers, unsigned long*readerslen); -long (* pcsc_connect) (unsigned long context, - const char *reader, - unsigned long share_mode, - unsigned long preferred_protocols, - unsigned long *r_card, - unsigned long *r_active_protocol); -long (* pcsc_disconnect) (unsigned long card, - unsigned long disposition); -long (* pcsc_status) (unsigned long card, - char *reader, unsigned long *readerlen, - unsigned long *r_state, - unsigned long *r_protocol, - unsigned char *atr, unsigned long *atrlen); -long (* pcsc_begin_transaction) (unsigned long card); -long (* pcsc_end_transaction) (unsigned long card); -long (* pcsc_transmit) (unsigned long card, - const pcsc_io_request_t send_pci, - const unsigned char *send_buffer, - unsigned long send_len, - pcsc_io_request_t recv_pci, - unsigned char *recv_buffer, - unsigned long *recv_len); -long (* pcsc_set_timeout) (unsigned long context, - unsigned long timeout); - - - -static void -bad_request (const char *type) -{ - fprintf (stderr, PGM ": bad `%s' request\n", type); - exit (1); -} - -static void -request_failed (int err) -{ - if (!err) - err = -1; - - putchar (0x81); /* Simple error/success response. */ - - putchar (0); - putchar (0); - putchar (0); - putchar (4); - - putchar ((err >> 24) & 0xff); - putchar ((err >> 16) & 0xff); - putchar ((err >> 8) & 0xff); - putchar ((err ) & 0xff); - - fflush (stdout); -} - - -static void -request_succeeded (const void *buffer, size_t buflen) -{ - size_t len; - - putchar (0x81); /* Simple error/success response. */ - - len = 4 + buflen; - putchar ((len >> 24) & 0xff); - putchar ((len >> 16) & 0xff); - putchar ((len >> 8) & 0xff); - putchar ((len ) & 0xff); - - /* Error code. */ - putchar (0); - putchar (0); - putchar (0); - putchar (0); - - /* Optional reponse string. */ - if (buffer) - fwrite (buffer, buflen, 1, stdout); - - fflush (stdout); -} - - - -static unsigned long -read_32 (FILE *fp) -{ - int c1, c2, c3, c4; - - c1 = getc (stdin); - c2 = getc (stdin); - c3 = getc (stdin); - c4 = getc (stdin); - if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF) - { - fprintf (stderr, PGM ": premature EOF while parsing request\n"); - exit (1); - } - return (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; -} - - - -static const char * -pcsc_error_string (long err) -{ - const char *s; - - if (!err) - return "okay"; - if ((err & 0x80100000) != 0x80100000) - return "invalid PC/SC error code"; - err &= 0xffff; - switch (err) - { - case 0x0002: s = "cancelled"; break; - case 0x000e: s = "can't dispose"; break; - case 0x0008: s = "insufficient buffer"; break; - case 0x0015: s = "invalid ATR"; break; - case 0x0003: s = "invalid handle"; break; - case 0x0004: s = "invalid parameter"; break; - case 0x0005: s = "invalid target"; break; - case 0x0011: s = "invalid value"; break; - case 0x0006: s = "no memory"; break; - case 0x0013: s = "comm error"; break; - case 0x0001: s = "internal error"; break; - case 0x0014: s = "unknown error"; break; - case 0x0007: s = "waited too long"; break; - case 0x0009: s = "unknown reader"; break; - case 0x000a: s = "timeout"; break; - case 0x000b: s = "sharing violation"; break; - case 0x000c: s = "no smartcard"; break; - case 0x000d: s = "unknown card"; break; - case 0x000f: s = "proto mismatch"; break; - case 0x0010: s = "not ready"; break; - case 0x0012: s = "system cancelled"; break; - case 0x0016: s = "not transacted"; break; - case 0x0017: s = "reader unavailable"; break; - case 0x0065: s = "unsupported card"; break; - case 0x0066: s = "unresponsive card"; break; - case 0x0067: s = "unpowered card"; break; - case 0x0068: s = "reset card"; break; - case 0x0069: s = "removed card"; break; - case 0x006a: s = "inserted card"; break; - case 0x001f: s = "unsupported feature"; break; - case 0x0019: s = "PCI too small"; break; - case 0x001a: s = "reader unsupported"; break; - case 0x001b: s = "duplicate reader"; break; - case 0x001c: s = "card unsupported"; break; - case 0x001d: s = "no service"; break; - case 0x001e: s = "service stopped"; break; - default: s = "unknown PC/SC error code"; break; - } - return s; -} - -static void -load_pcsc_driver (const char *libname) -{ - void *handle; - - handle = dlopen (libname, RTLD_LAZY); - if (!handle) - { - fprintf (stderr, PGM ": failed to open driver `%s': %s", - libname, dlerror ()); - exit (1); - } - - pcsc_establish_context = dlsym (handle, "SCardEstablishContext"); - pcsc_release_context = dlsym (handle, "SCardReleaseContext"); - pcsc_list_readers = dlsym (handle, "SCardListReaders"); - pcsc_connect = dlsym (handle, "SCardConnect"); - pcsc_disconnect = dlsym (handle, "SCardDisconnect"); - pcsc_status = dlsym (handle, "SCardStatus"); - pcsc_begin_transaction = dlsym (handle, "SCardBeginTransaction"); - pcsc_end_transaction = dlsym (handle, "SCardEndTransaction"); - pcsc_transmit = dlsym (handle, "SCardTransmit"); - pcsc_set_timeout = dlsym (handle, "SCardSetTimeout"); - - if (!pcsc_establish_context - || !pcsc_release_context - || !pcsc_list_readers - || !pcsc_connect - || !pcsc_disconnect - || !pcsc_status - || !pcsc_begin_transaction - || !pcsc_end_transaction - || !pcsc_transmit - /* || !pcsc_set_timeout */) - { - /* Note that set_timeout is currently not used and also not - available under Windows. */ - fprintf (stderr, - "apdu_open_reader: invalid PC/SC driver " - "(%d%d%d%d%d%d%d%d%d%d)\n", - !!pcsc_establish_context, - !!pcsc_release_context, - !!pcsc_list_readers, - !!pcsc_connect, - !!pcsc_disconnect, - !!pcsc_status, - !!pcsc_begin_transaction, - !!pcsc_end_transaction, - !!pcsc_transmit, - !!pcsc_set_timeout ); - dlclose (handle); - exit (1); - } -} - - - - -/* Handle a open request. The argument is expected to be a string - with the port indentification. ARGBUF is always guaranteed to be - terminted by a 0 which is not counted in ARGLEN. We may modifiy - ARGBUF. */ -static void -handle_open (unsigned char *argbuf, size_t arglen) -{ - long err; - const char * portstr; - char *list = NULL; - unsigned long nreader, listlen, atrlen; - char *p; - unsigned long card_state, card_protocol; - unsigned char atr[33]; - - /* Make sure there is only the port string */ - if (arglen != strlen (argbuf)) - bad_request ("OPEN"); - portstr = argbuf; - - if (driver_is_open) - { - fprintf (stderr, PGM ": PC/SC has already been opened\n"); - request_failed (-1); - } - - err = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL, &pcsc_context); - if (err) - { - fprintf (stderr, PGM": pcsc_establish_context failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - request_failed (err); - return; - } - - err = pcsc_list_readers (pcsc_context, NULL, NULL, &nreader); - if (!err) - { - list = malloc (nreader+1); /* Better add 1 for safety reasons. */ - if (!list) - { - fprintf (stderr, PGM": error allocating memory for reader list\n"); - exit (1); - } - err = pcsc_list_readers (pcsc_context, NULL, list, &nreader); - } - if (err) - { - fprintf (stderr, PGM": pcsc_list_readers failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (pcsc_context); - free (list); - request_failed (err); - return; - } - - listlen = nreader; - p = list; - while (nreader) - { - if (!*p && !p[1]) - break; - fprintf (stderr, PGM": detected reader `%s'\n", p); - if (nreader < (strlen (p)+1)) - { - fprintf (stderr, PGM": invalid response from pcsc_list_readers\n"); - break; - } - nreader -= strlen (p)+1; - p += strlen (p) + 1; - } - - err = pcsc_connect (pcsc_context, - portstr && *portstr? portstr : list, - PCSC_SHARE_EXCLUSIVE, - PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1, - &pcsc_card, - &pcsc_protocol); - if (err) - { - fprintf (stderr, PGM": pcsc_connect failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (pcsc_context); - free (list); - request_failed (err); - return; - } - - atrlen = 32; - /* (We need to pass a dummy buffer. We use LIST because it ought to - be large enough.) */ - err = pcsc_status (pcsc_card, - list, &listlen, - &card_state, &card_protocol, - atr, &atrlen); - free (list); - if (err) - { - fprintf (stderr, PGM": pcsc_status failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (pcsc_context); - request_failed (err); - return; - } - if (atrlen >= sizeof atr || atrlen >= sizeof current_atr) - { - fprintf (stderr, PGM": ATR returned by pcsc_status is too large\n"); - exit (4); - } - memcpy (current_atr, atr, atrlen); - current_atrlen = atrlen; - driver_is_open = 1; - request_succeeded (current_atr, current_atrlen); -} - - - -/* Handle a close request. We expect no arguments. We may modifiy - ARGBUF. */ -static void -handle_close (unsigned char *argbuf, size_t arglen) -{ - if (!driver_is_open) - { - fprintf (stderr, PGM ": PC/SC has not yet been opened\n"); - request_failed (-1); - } - - pcsc_release_context (pcsc_context); - - request_succeeded (NULL, 0); -} - - - -/* Handle a transmit request. The argument is expected to be a bufer - with the APDU. We may modifiy ARGBUF. */ -static void -handle_transmit (unsigned char *argbuf, size_t arglen) -{ - long err; - struct pcsc_io_request_s send_pci; - unsigned long recv_len; - unsigned char buffer[1024]; - - /* The apdu should at least be one byte. */ - if (!arglen) - bad_request ("TRANSMIT"); - - if (!driver_is_open) - { - fprintf (stderr, PGM ": PC/SC has not yet been opened\n"); - request_failed (-1); - } - - if ((pcsc_protocol & PCSC_PROTOCOL_T1)) - send_pci.protocol = PCSC_PROTOCOL_T1; - else - send_pci.protocol = PCSC_PROTOCOL_T0; - send_pci.pci_len = sizeof send_pci; - recv_len = sizeof (buffer); - err = pcsc_transmit (pcsc_card, &send_pci, argbuf, arglen, - NULL, buffer, &recv_len); - if (err) - { - if (verbose) - fprintf (stderr, PGM": pcsc_transmit failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - request_failed (err); - return; - } - request_succeeded (buffer, recv_len); -} - - - - - - - - - - - - -static void -print_version (int with_help) -{ - fputs (MYVERSION_LINE "\n" - "Copyright (C) 2004 Free Software Foundation, Inc.\n" - "This program comes with ABSOLUTELY NO WARRANTY.\n" - "This is free software, and you are welcome to redistribute it\n" - "under certain conditions. See the file COPYING for details.\n", - stdout); - - if (with_help) - fputs ("\n" - "Usage: " PGM " [OPTIONS] API-NUMBER [LIBNAME]\n" - "Helper to connect scdaemon to the PC/SC library\n" - "\n" - " --verbose enable extra informational output\n" - " --version print version of the program and exit\n" - " --help display this help and exit\n" - BUGREPORT_LINE, stdout ); - - exit (0); -} - - -int -main (int argc, char **argv) -{ - int last_argc = -1; - int api_number = 0; - int c; - - if (argc) - { - argc--; argv++; - } - while (argc && last_argc != argc ) - { - last_argc = argc; - if (!strcmp (*argv, "--")) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--version")) - print_version (0); - else if (!strcmp (*argv, "--help")) - print_version (1); - else if (!strcmp (*argv, "--verbose")) - { - verbose = 1; - argc--; argv++; - } - } - if (argc != 1 && argc != 2) - { - fprintf (stderr, "usage: " PGM " API-NUMBER [LIBNAME]\n"); - exit (1); - } - - api_number = atoi (*argv); - argv++; argc--; - if (api_number != 1) - { - fprintf (stderr, PGM ": api-number %d is not valid\n", api_number); - exit (1); - } - - load_pcsc_driver (argc? *argv : DEFAULT_PCSC_DRIVER); - - while ((c = getc (stdin)) != EOF) - { - size_t arglen; - unsigned char argbuffer[2048]; - - arglen = read_32 (stdin); - if (arglen >= sizeof argbuffer - 1) - { - fprintf (stderr, PGM ": request too long\n"); - exit (1); - } - if (arglen && fread (argbuffer, arglen, 1, stdin) != 1) - { - fprintf (stderr, PGM ": error reading request: %s\n", - strerror (errno)); - exit (1); - } - argbuffer[arglen] = 0; - switch (c) - { - case 1: - handle_open (argbuffer, arglen); - break; - - case 2: - handle_close (argbuffer, arglen); - exit (0); - break; - - case 3: - handle_transmit (argbuffer, arglen); - break; - - default: - fprintf (stderr, PGM ": invalid request 0x%02X\n", c); - exit (1); - } - free (argbuffer); - } - return 0; -} - - - -/* -Local Variables: -compile-command: "gcc -Wall -g -o pcsc-wrapper pcsc-wrapper.c -ldl" -End: -*/ diff --git a/scd/sc-copykeys.c b/scd/sc-copykeys.c deleted file mode 100644 index 78cb2acc8..000000000 --- a/scd/sc-copykeys.c +++ /dev/null @@ -1,735 +0,0 @@ -/* sc-copykeys.c - A tool to store keys on a smartcard. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#define JNLIB_NEED_LOG_LOGV -#include "scdaemon.h" -#include <gcrypt.h> - -#include "../common/ttyio.h" -#include "../common/simple-pwquery.h" -#include "apdu.h" /* for open_reader */ -#include "atr.h" -#include "app-common.h" - -#define _(a) (a) - - -enum cmd_and_opt_values -{ oVerbose = 'v', - oReaderPort = 500, - octapiDriver, - oDebug, - oDebugAll, - -aTest }; - - -static ARGPARSE_OPTS opts[] = { - - { 301, NULL, 0, "@Options:\n " }, - - { oVerbose, "verbose", 0, "verbose" }, - { oReaderPort, "reader-port", 2, "|N|connect to reader at port N"}, - { octapiDriver, "ctapi-driver", 2, "NAME|use NAME as ctAPI driver"}, - { oDebug, "debug" ,4|16, "set debugging flags"}, - { oDebugAll, "debug-all" ,0, "enable full debugging"}, - {0} -}; - - -static void copykeys (APP app, const char *fname); - - -static const char * -my_strusage (int level) -{ - const char *p; - switch (level) - { - case 11: p = "sc-copykeys (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: sc-copykeys [options] (-h for help)\n"); - break; - case 41: p = _("Syntax: sc-copykeys [options] " - "file-with-key\n" - "Copy keys to a smartcards\n"); - break; - - default: p = NULL; - } - return p; -} - -/* Used by gcry for logging */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - /* translate the log levels */ - switch (level) - { - case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break; - case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break; - case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break; - case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break; - case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break; - case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break; - case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break; - default: level = JNLIB_LOG_ERROR; break; - } - log_logv (level, fmt, arg_ptr); -} - - -int -main (int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - int slot, rc; - const char *reader_port = NULL; - struct app_ctx_s appbuf; - - memset (&appbuf, 0, sizeof appbuf); - - set_strusage (my_strusage); - gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - log_set_prefix ("sc-copykeys", 1); - - /* check that the libraries are suitable. Do it here because - the option parsing may need services of the library */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal( _("libgcrypt is too old (need %s, have %s)\n"), - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - - gcry_set_log_handler (my_gcry_logger, NULL); - gcry_control (GCRYCTL_DISABLE_SECMEM, 0); /* FIXME - we want to use it */ - /* FIXME? gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);*/ - - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - while (arg_parse (&pargs, opts) ) - { - switch (pargs.r_opt) - { - case oVerbose: opt.verbose++; break; - case oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oReaderPort: reader_port = pargs.r.ret_str; break; - case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break; - default : pargs.err = 2; break; - } - } - if (log_get_errorcount(0)) - exit(2); - - if (argc != 1) - usage (1); - - slot = apdu_open_reader (reader_port); - if (slot == -1) - exit (1); - - /* FIXME: Use select_application. */ - appbuf.slot = slot; - rc = app_select_openpgp (&appbuf); - if (rc) - { - log_error ("selecting openpgp failed: %s\n", gpg_strerror (rc)); - exit (1); - } - appbuf.initialized = 1; - log_info ("openpgp application selected\n"); - - copykeys (&appbuf, *argv); - - - return 0; -} - - - -void -send_status_info (CTRL ctrl, const char *keyword, ...) -{ - /* DUMMY */ -} - - - -static char * -read_file (const char *fname, size_t *r_length) -{ - FILE *fp; - struct stat st; - char *buf; - size_t buflen; - - fp = fname? fopen (fname, "rb") : stdin; - if (!fp) - { - log_error ("can't open `%s': %s\n", - fname? fname: "[stdin]", strerror (errno)); - return NULL; - } - - if (fstat (fileno(fp), &st)) - { - log_error ("can't stat `%s': %s\n", - fname? fname: "[stdin]", strerror (errno)); - if (fname) - fclose (fp); - return NULL; - } - - buflen = st.st_size; - buf = xmalloc (buflen+1); - if (fread (buf, buflen, 1, fp) != 1) - { - log_error ("error reading `%s': %s\n", - fname? fname: "[stdin]", strerror (errno)); - if (fname) - fclose (fp); - xfree (buf); - return NULL; - } - if (fname) - fclose (fp); - - *r_length = buflen; - return buf; -} - - -static gcry_sexp_t -read_key (const char *fname) -{ - char *buf; - size_t buflen; - gcry_sexp_t private; - int rc; - - buf = read_file (fname, &buflen); - if (!buf) - return NULL; - - rc = gcry_sexp_new (&private, buf, buflen, 1); - if (rc) - { - log_error ("gcry_sexp_new failed: %s\n", gpg_strerror (rc)); - return NULL; - } - xfree (buf); - - return private; -} - - - -static gcry_mpi_t * -sexp_to_kparms (gcry_sexp_t sexp, unsigned long *created) -{ - gcry_sexp_t list, l2; - const char *name; - const char *s; - size_t n; - int i, idx; - const char *elems; - gcry_mpi_t *array; - - *created = 0; - list = gcry_sexp_find_token (sexp, "private-key", 0 ); - if(!list) - return NULL; - - /* quick hack to get the creation time. */ - l2 = gcry_sexp_find_token (list, "created", 0); - if (l2 && (name = gcry_sexp_nth_data (l2, 1, &n))) - { - char *tmp = xmalloc (n+1); - memcpy (tmp, name, n); - tmp[n] = 0; - *created = strtoul (tmp, NULL, 10); - xfree (tmp); - } - gcry_sexp_release (l2); - l2 = gcry_sexp_cadr (list); - gcry_sexp_release (list); - list = l2; - name = gcry_sexp_nth_data (list, 0, &n); - if(!name || n != 3 || memcmp (name, "rsa", 3)) - { - gcry_sexp_release (list); - return NULL; - } - - /* Parameter names used with RSA. */ - elems = "nedpqu"; - array = xcalloc (strlen(elems) + 1, sizeof *array); - for (idx=0, s=elems; *s; s++, idx++ ) - { - l2 = gcry_sexp_find_token (list, s, 1); - if (!l2) - { - for (i=0; i<idx; i++) - gcry_mpi_release (array[i]); - xfree (array); - gcry_sexp_release (list); - return NULL; /* required parameter not found */ - } - array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); - gcry_sexp_release (l2); - if (!array[idx]) - { - for (i=0; i<idx; i++) - gcry_mpi_release (array[i]); - xfree (array); - gcry_sexp_release (list); - return NULL; /* required parameter is invalid */ - } - } - - gcry_sexp_release (list); - return array; -} - - -/* Return true if the SHA1 fingerprint FPR consists only of zeroes. */ -static int -fpr_is_zero (const char *fpr) -{ - int i; - - for (i=0; i < 20 && !fpr[i]; i++) - ; - return (i == 20); -} - - -static void -show_sha1_fpr (const unsigned char *fpr) -{ - int i; - - if (fpr) - { - for (i=0; i < 20 ; i+=2, fpr += 2 ) - { - if (i == 10 ) - tty_printf (" "); - tty_printf (" %02X%02X", *fpr, fpr[1]); - } - } - else - tty_printf (" [none]"); - tty_printf ("\n"); -} - -/* Query the card, show a list of already stored keys and ask the user - where to store the key. Returns the key number or 0 for cancel - operation. */ -static int -query_card (APP app) -{ - int keyno = 0; - char *serialno, *disp_name, *pubkey_url; - unsigned char *fpr1, *fpr2, *fpr3; - - - if (app_openpgp_cardinfo (app, - &serialno, - &disp_name, - &pubkey_url, - &fpr1, &fpr2, &fpr3)) - return 0; - - - for (;;) - { - char *answer; - - tty_printf ("\n"); - - tty_printf ("Serial number ....: %s\n", - serialno? serialno : "[none]"); - tty_printf ("Name of cardholder: %s\n", - disp_name && *disp_name? disp_name : "[not set]"); - tty_printf ("URL of public key : %s\n", - pubkey_url && *pubkey_url? pubkey_url : "[not set]"); - tty_printf ("Signature key ....:"); - show_sha1_fpr (fpr1); - tty_printf ("Encryption key....:"); - show_sha1_fpr (fpr2); - tty_printf ("Authentication key:"); - show_sha1_fpr (fpr3); - - tty_printf ("\n" - "1 - store as signature key and reset usage counter\n" - "2 - store as encryption key\n" - "3 - store as authentication key\n" - "Q - quit\n" - "\n"); - - answer = tty_get("Your selection? "); - tty_kill_prompt(); - if (strlen (answer) != 1) - ; - else if ( *answer == '1' ) - { - if ( (fpr1 && !fpr_is_zero (fpr1)) ) - { - tty_printf ("\n"); - log_error ("WARNING: signature key does already exists!\n"); - tty_printf ("\n"); - if ( tty_get_answer_is_yes ("Replace existing key? ") ) - { - keyno = 1; - break; - } - } - else - { - keyno = 1; - break; - } - } - else if ( *answer == '2' ) - { - if ( (fpr2 && !fpr_is_zero (fpr2)) ) - { - tty_printf ("\n"); - log_error ("WARNING: encryption key does already exists!\n"); - tty_printf ("\n"); - if ( tty_get_answer_is_yes ("Replace existing key? ") ) - { - keyno = 2; - break; - } - } - else - { - keyno = 2; - break; - } - } - else if ( *answer == '3' ) - { - if ( (fpr3 && !fpr_is_zero (fpr3)) ) - { - tty_printf ("\n"); - log_error ("WARNING: authentication key does already exists!\n"); - tty_printf ("\n"); - if ( tty_get_answer_is_yes ("Replace existing key? ") ) - { - keyno = 3; - break; - } - } - else - { - keyno = 3; - break; - } - } - else if ( *answer == 'q' || *answer == 'Q') - { - keyno = 0; - break; - } - } - - xfree (serialno); - xfree (disp_name); - xfree (pubkey_url); - xfree (fpr1); - xfree (fpr2); - xfree (fpr3); - - return keyno; -} - - -/* Callback function to ask for a PIN. */ -static int -pincb (void *arg, const char *prompt, char **pinvalue) -{ - char *pin = xstrdup ("12345678"); - -/* pin = simple_pwquery (NULL, NULL, prompt, */ -/* "We need the admin's PIN to store the key on the card", */ -/* NULL); */ -/* if (!pin) */ -/* return gpg_error (GPG_ERR_CANCELED); */ - - - - *pinvalue = pin; - return 0; -} - - -/* This function expects a file (or NULL for stdin) with the secret - and public key parameters. This file should consist of an - S-expression as used by gpg-agent. Only the unprotected format is - supported. Example: - - (private-key - (rsa - (n #00e0ce9..[some bytes not shown]..51#) - (e #010001#) - (d #046129F..[some bytes not shown]..81#) - (p #00e861b..[some bytes not shown]..f1#) - (q #00f7a7c..[some bytes not shown]..61#) - (u #304559a..[some bytes not shown]..9b#)) - (uri http://foo.bar x-foo:whatever_you_want)) - -*/ -static void -copykeys (APP app, const char *fname) -{ - int rc; - gcry_sexp_t private; - gcry_mpi_t *mpis, rsa_n, rsa_e, rsa_p, rsa_q; - unsigned int nbits; - size_t n; - unsigned char *template, *tp; - unsigned char m[128], e[4]; - size_t mlen, elen; - unsigned long creation_date; - time_t created_at; - int keyno; - - if (!strcmp (fname, "-")) - fname = NULL; - - private = read_key (fname); - if (!private) - exit (1); - - mpis = sexp_to_kparms (private, &creation_date); - if (!creation_date) - { - log_info ("no creation date found - assuming current date\n"); - created_at = time (NULL); - } - else - created_at = creation_date; - gcry_sexp_release (private); - if (!mpis) - { - log_error ("invalid structure of key file or not RSA\n"); - exit (1); - } - /* MPIS is now an array with the key parameters as defined by OpenPGP. */ - rsa_n = mpis[0]; - rsa_e = mpis[1]; - gcry_mpi_release (mpis[2]); - rsa_p = mpis[3]; - rsa_q = mpis[4]; - gcry_mpi_release (mpis[5]); - xfree (mpis); - - nbits = gcry_mpi_get_nbits (rsa_e); - if (nbits < 2 || nbits > 32) - { - log_error ("public exponent too large (more than 32 bits)\n"); - goto failure; - } - nbits = gcry_mpi_get_nbits (rsa_p); - if (nbits != 512) - { - log_error ("length of first RSA prime is not 512\n"); - goto failure; - } - nbits = gcry_mpi_get_nbits (rsa_q); - if (nbits != 512) - { - log_error ("length of second RSA prime is not 512\n"); - goto failure; - } - - nbits = gcry_mpi_get_nbits (rsa_n); - if (nbits != 1024) - { - log_error ("length of RSA modulus is not 1024\n"); - goto failure; - } - - keyno = query_card (app); - if (!keyno) - goto failure; - - /* Build the private key template as described in section 4.3.3.6 of - the specs. - 0xC0 <length> public exponent - 0xC1 <length> prime p - 0xC2 <length> prime q */ - template = tp = xmalloc (1+2 + 1+1+4 + 1+1+64 + 1+1+64); - *tp++ = 0xC0; - *tp++ = 4; - rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, 4, &n, rsa_e); - if (rc) - { - log_error ("mpi_print failed: %s\n", gpg_strerror (rc)); - goto failure; - } - assert (n <= 4); - memcpy (e, tp, n); - elen = n; - if (n != 4) - { - memmove (tp+4-n, tp, 4-n); - memset (tp, 0, 4-n); - } - tp += 4; - - *tp++ = 0xC1; - *tp++ = 64; - rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, 64, &n, rsa_p); - if (rc) - { - log_error ("mpi_print failed: %s\n", gpg_strerror (rc)); - goto failure; - } - assert (n == 64); - tp += 64; - - *tp++ = 0xC2; - *tp++ = 64; - rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, 64, &n, rsa_q); - if (rc) - { - log_error ("mpi_print failed: %s\n", gpg_strerror (rc)); - goto failure; - } - assert (n == 64); - tp += 64; - assert (tp - template == 138); - - /* (we need the modulus to calculate the fingerprint) */ - rc = gcry_mpi_print (GCRYMPI_FMT_USG, m, 128, &n, rsa_n); - if (rc) - { - log_error ("mpi_print failed: %s\n", gpg_strerror (rc)); - goto failure; - } - assert (n == 128); - mlen = 128; - - - rc = app_openpgp_storekey (app, keyno, - template, tp - template, - created_at, - m, mlen, - e, elen, - pincb, NULL); - - if (rc) - { - log_error ("error storing key: %s\n", gpg_strerror (rc)); - goto failure; - } - log_info ("key successfully stored\n"); - { - unsigned char *mm, *ee; - size_t mmlen, eelen; - int i; - - rc = app_openpgp_readkey (app, keyno, &mm, &mmlen, &ee, &eelen); - if (rc) - { - log_error ("error reading key back: %s\n", gpg_strerror (rc)); - goto failure; - } - - /* Strip leading zeroes. */ - for (i=0; i < mmlen && !mm[i]; i++) - ; - mmlen -= i; - memmove (mm, mm+i, mmlen); - for (i=0; i < eelen && !ee[i]; i++) - ; - eelen -= i; - memmove (ee, ee+i, eelen); - - if (eelen != elen || mmlen != mlen) - { - log_error ("key parameter length mismatch (n=%u/%u, e=%u/%u)\n", - (unsigned int)mlen, (unsigned int)mmlen, - (unsigned int)elen, (unsigned int)eelen); - xfree (mm); - xfree (ee); - goto failure; - } - - if (memcmp (m, mm, mlen)) - { - log_error ("key parameter n mismatch\n"); - log_printhex ("original n: ", m, mlen); - log_printhex (" copied n: ", mm, mlen); - xfree (mm); - xfree (ee); - goto failure; - } - if (memcmp (e, ee, elen)) - { - log_error ("key parameter e mismatch\n"); - log_printhex ("original e: ", e, elen); - log_printhex (" copied e: ", ee, elen); - xfree (mm); - xfree (ee); - goto failure; - } - xfree (mm); - xfree (ee); - } - - - gcry_mpi_release (rsa_e); - gcry_mpi_release (rsa_p); - gcry_mpi_release (rsa_q); - gcry_mpi_release (rsa_n); - return; - - failure: - gcry_mpi_release (rsa_e); - gcry_mpi_release (rsa_p); - gcry_mpi_release (rsa_q); - gcry_mpi_release (rsa_n); - exit (1); -} - - diff --git a/scd/sc-investigate.c b/scd/sc-investigate.c deleted file mode 100644 index 3882e1dfd..000000000 --- a/scd/sc-investigate.c +++ /dev/null @@ -1,770 +0,0 @@ -/* sc-investigate.c - A tool to look around on smartcards. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <ctype.h> -#include <unistd.h> - -#ifdef HAVE_READLINE_READLINE_H -#include <readline/readline.h> -#include <readline/history.h> -#endif - -#define JNLIB_NEED_LOG_LOGV -#include "scdaemon.h" -#include <gcrypt.h> - -#include "apdu.h" /* for open_reader */ -#include "atr.h" -#include "app-common.h" -#include "iso7816.h" - -#define _(a) (a) - -#define CONTROL_D ('D' - 'A' + 1) - - -enum cmd_and_opt_values -{ - oInteractive = 'i', - oVerbose = 'v', - oQuiet = 'q', - oReaderPort = 500, - octapiDriver, - - oDebug, - oDebugAll, - - oDisableCCID, - - - oGenRandom, - -aTest }; - - -static ARGPARSE_OPTS opts[] = { - - { 301, NULL, 0, "@Options:\n " }, - - { oInteractive, "interactive", 0, "start in interactive explorer mode"}, - { oQuiet, "quiet", 0, "quiet" }, - { oVerbose, "verbose", 0, "verbose" }, - { oReaderPort, "reader-port", 2, "|N|connect to reader at port N"}, - { octapiDriver, "ctapi-driver", 2, "NAME|use NAME as ctAPI driver"}, - { oDisableCCID, "disable-ccid", 0, -#ifdef HAVE_LIBUSB - "do not use the internal CCID driver" -#else - "@" -#endif - }, - { oDebug, "debug" ,4|16, "set debugging flags"}, - { oDebugAll, "debug-all" ,0, "enable full debugging"}, - { oGenRandom, "gen-random", 4, "|N|generate N bytes of random"}, - {0} -}; - - -static void interactive_shell (int slot); -static void dump_other_cards (int slot); - -static const char * -my_strusage (int level) -{ - const char *p; - switch (level) - { - case 11: p = "sc-investigate (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: sc-investigate [options] (-h for help)\n"); - break; - case 41: p = _("Syntax: sc-investigate [options] [args]]\n" - "Have a look at smartcards\n"); - break; - - default: p = NULL; - } - return p; -} - -/* Used by gcry for logging */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - /* translate the log levels */ - switch (level) - { - case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break; - case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break; - case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break; - case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break; - case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break; - case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break; - case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break; - default: level = JNLIB_LOG_ERROR; break; - } - log_logv (level, fmt, arg_ptr); -} - - -int -main (int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - int slot, rc; - const char *reader_port = NULL; - unsigned long gen_random = 0; - int interactive = 0; - - set_strusage (my_strusage); - gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - log_set_prefix ("sc-investigate", 1); - - /* Try to auto set the character set. */ - set_native_charset (NULL); - - /* check that the libraries are suitable. Do it here because - the option parsing may need services of the library */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal( _("libgcrypt is too old (need %s, have %s)\n"), - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - - - gcry_set_log_handler (my_gcry_logger, NULL); - /* FIXME? gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);*/ - - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - while (arg_parse (&pargs, opts) ) - { - switch (pargs.r_opt) - { - case oVerbose: opt.verbose++; break; - case oQuiet: opt.quiet++; break; - case oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oReaderPort: reader_port = pargs.r.ret_str; break; - case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break; - case oDisableCCID: opt.disable_ccid = 1; break; - case oGenRandom: gen_random = pargs.r.ret_ulong; break; - case oInteractive: interactive = 1; break; - default : pargs.err = 2; break; - } - } - if (log_get_errorcount(0)) - exit(2); - - if (opt.verbose < 2) - opt.verbose = 2; /* Hack to let select_openpgp print some info. */ - - if (argc) - usage (1); - - slot = apdu_open_reader (reader_port); - if (slot == -1) - exit (1); - - if (!gen_random && !opt.quiet) - { - rc = atr_dump (slot, stdout); - if (rc) - log_error ("can't dump ATR: %s\n", gpg_strerror (rc)); - } - - if (interactive) - interactive_shell (slot); - else - { - struct app_ctx_s appbuf; - - /* Fixme: We better use app.c directly. */ - memset (&appbuf, 0, sizeof appbuf); - appbuf.slot = slot; - rc = app_select_openpgp (&appbuf); - if (rc) - { - if (!opt.quiet) - log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc)); - memset (&appbuf, 0, sizeof appbuf); - appbuf.slot = slot; - rc = app_select_dinsig (&appbuf); - if (rc) - { - if (!opt.quiet) - log_info ("selecting dinsig failed: %s\n", gpg_strerror (rc)); - dump_other_cards (slot); - } - else - { - appbuf.initialized = 1; - log_info ("dinsig application selected\n"); - } - } - else - { - appbuf.initialized = 1; - log_info ("openpgp application selected\n"); - - if (gen_random) - { - size_t nbytes; - unsigned char *buffer; - - buffer = xmalloc (4096); - do - { - nbytes = gen_random > 4096? 4096 : gen_random; - rc = app_get_challenge (&appbuf, nbytes, buffer); - if (rc) - log_error ("app_get_challenge failed: %s\n",gpg_strerror (rc)); - else - { - if (fwrite (buffer, nbytes, 1, stdout) != 1) - log_error ("writing to stdout failed: %s\n", - strerror (errno)); - gen_random -= nbytes; - } - } - while (gen_random && !log_get_errorcount (0)); - xfree (buffer); - } - } - } - - return log_get_errorcount (0)? 2:0; -} - - - -void -send_status_info (CTRL ctrl, const char *keyword, ...) -{ - /* DUMMY */ -} - - - -/* Dump BUFFER of length NBYTES in a nicely human readable format. */ -static void -dump_buffer (const unsigned char *buffer, size_t nbytes) -{ - int i; - - while (nbytes) - { - for (i=0; i < 16 && i < nbytes; i++) - printf ("%02X%s ", buffer[i], i==8? " ":""); - for (; i < 16; i++) - printf (" %s ", i==8? " ":""); - putchar (' '); - putchar (' '); - for (i=0; i < 16 && i < nbytes; i++) - if (isprint (buffer[i])) - putchar (buffer[i]); - else - putchar ('.'); - nbytes -= i; - buffer += i; - for (; i < 16; i++) - putchar (' '); - putchar ('\n'); - } -} - - -static void -dump_or_store_buffer (const char *arg, - const unsigned char *buffer, size_t nbytes) -{ - const char *s = strchr (arg, '>'); - int append; - FILE *fp; - - if (!s) - { - dump_buffer (buffer, nbytes); - return; - } - if ((append = (*++s == '>'))) - s++; - fp = fopen (s, append? "ab":"wb"); - if (!fp) - { - log_error ("failed to create `%s': %s\n", s, strerror (errno)); - return; - } - if (nbytes && fwrite (buffer, nbytes, 1, fp) != 1) - log_error ("failed to write to `%s': %s\n", s, strerror (errno)); - if (fclose (fp)) - log_error ("failed to close `%s': %s\n", s, strerror (errno)); -} - - -/* Convert STRING into a a newly allocated buffer and return the - length of the buffer in R_LENGTH. Detect xx:xx:xx... sequence and - unhexify that one. */ -static unsigned char * -pin_to_buffer (const char *string, size_t *r_length) -{ - unsigned char *buffer = xmalloc (strlen (string)+1); - const char *s; - size_t n; - - for (s=string, n=0; *s; s += 3) - { - if (hexdigitp (s) && hexdigitp (s+1) && (s[2]==':'||!s[2])) - { - buffer[n++] = xtoi_2 (s); - if (!s[2]) - break; - } - else - { - memcpy (buffer, string, strlen (string)); - *r_length = strlen (string); - return buffer; - } - } - *r_length = n; - return buffer; -} - - -static char * -read_line (int use_readline, char *prompt) -{ - static char buf[256]; - -#ifdef HAVE_READLINE - if (use_readline) - { - char *line = readline (prompt); - if (line) - trim_spaces (line); - if (line && strlen (line) > 2 ) - add_history (line); - return line; - } -#endif - /* Either we don't have readline or we are not running - interactively */ -#ifndef HAVE_READLINE - printf ("%s", prompt ); -#endif - fflush(stdout); - if (!fgets(buf, sizeof(buf), stdin)) - return NULL; - if (!strlen(buf)) - return NULL; - if (buf[strlen (buf)-1] == '\n') - buf[strlen (buf)-1] = 0; - trim_spaces (buf); - return buf; -} - -/* Run a shell for interactive exploration of the card. */ -static void -interactive_shell (int slot) -{ - enum cmdids - { - cmdNOP = 0, - cmdQUIT, cmdHELP, - cmdSELECT, - cmdCHDIR, - cmdLS, - cmdAPP, - cmdREAD, - cmdREADREC, - cmdREADSHORTREC, - cmdDEBUG, - cmdVERIFY, - cmdCHANGEREF, - - cmdINVCMD - }; - static struct - { - const char *name; - enum cmdids id; - const char *desc; - } cmds[] = { - { "quit" , cmdQUIT , "quit this menu" }, - { "q" , cmdQUIT , NULL }, - { "help" , cmdHELP , "show this help" }, - { "?" , cmdHELP , NULL }, - { "debug" , cmdDEBUG, "set debugging flags" }, - { "select" , cmdSELECT, "select file (EF)" }, - { "s" , cmdSELECT, NULL }, - { "chdir" , cmdCHDIR, "change directory (select DF)"}, - { "cd" , cmdCHDIR, NULL }, - { "ls" , cmdLS, "list directory (some cards only)"}, - { "app" , cmdAPP, "select application"}, - { "read" , cmdREAD, "read binary" }, - { "rb" , cmdREAD, NULL }, - { "readrec", cmdREADREC, "read record(s)" }, - { "rr" , cmdREADREC, NULL }, - { "rsr" , cmdREADSHORTREC, "readshortrec RECNO SHORT_EF" }, - { "verify" , cmdVERIFY, "verify CHVNO PIN" }, - { "ver" , cmdVERIFY, NULL }, - { "changeref", cmdCHANGEREF, "change reference data" }, - { NULL, cmdINVCMD } - }; - enum cmdids cmd = cmdNOP; - int use_readline = isatty (fileno(stdin)); - char *line; - gpg_error_t err = 0; - unsigned char *result = NULL; - size_t resultlen; - -#ifdef HAVE_READLINE - if (use_readline) - using_history (); -#endif - - for (;;) - { - int arg_number; - const char *arg_string = ""; - const char *arg_next = ""; - char *p; - int i; - - if (err) - printf ("command failed: %s\n", gpg_strerror (err)); - err = 0; - xfree (result); - result = NULL; - - printf ("\n"); - do - { - line = read_line (use_readline, "cmd> "); - } - while ( line && *line == '#' ); - - arg_number = 0; - if (!line || *line == CONTROL_D) - cmd = cmdQUIT; - else if (!*line) - cmd = cmdNOP; - else { - if ((p=strchr (line,' '))) - { - char *endp; - - *p++ = 0; - trim_spaces (line); - trim_spaces (p); - arg_number = strtol (p, &endp, 0); - arg_string = p; - if (endp != p) - { - arg_next = endp; - while ( spacep (arg_next) ) - arg_next++; - } - } - - for (i=0; cmds[i].name; i++ ) - if (!ascii_strcasecmp (line, cmds[i].name )) - break; - - cmd = cmds[i].id; - } - - switch (cmd) - { - case cmdHELP: - for (i=0; cmds[i].name; i++ ) - if (cmds[i].desc) - printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) ); - break; - - case cmdQUIT: - goto leave; - - case cmdNOP: - break; - - case cmdDEBUG: - if (!*arg_string) - opt.debug = opt.debug? 0 : 2048; - else - opt.debug = arg_number; - break; - - case cmdSELECT: - err = iso7816_select_file (slot, arg_number, 0, NULL, NULL); - break; - - case cmdCHDIR: - err = iso7816_select_file (slot, arg_number, 1, NULL, NULL); - break; - - case cmdLS: - err = iso7816_list_directory (slot, 1, &result, &resultlen); - if (!err || gpg_err_code (err) == GPG_ERR_ENOENT) - err = iso7816_list_directory (slot, 0, &result, &resultlen); - /* FIXME: Do something with RESULT. */ - break; - - case cmdAPP: - { - app_t app; - - app = select_application (NULL, slot, *arg_string? arg_string:NULL); - if (app) - { - char *sn; - - app_get_serial_and_stamp (app, &sn, NULL); - log_info ("application `%s' ready; sn=%s\n", - app->apptype?app->apptype:"?", sn? sn:"[none]"); - release_application (app); - } - } - break; - - case cmdREAD: - err = iso7816_read_binary (slot, 0, 0, &result, &resultlen); - if (!err) - dump_or_store_buffer (arg_string, result, resultlen); - break; - - case cmdREADREC: - if (*arg_string == '*' && (!arg_string[1] || arg_string[1] == ' ')) - { - /* Fixme: Can't write to a file yet. */ - for (i=1, err=0; !err; i++) - { - xfree (result); result = NULL; - err = iso7816_read_record (slot, i, 1, 0, - &result, &resultlen); - if (!err) - dump_buffer (result, resultlen); - } - if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) - err = 0; - } - else - { - err = iso7816_read_record (slot, arg_number, 1, 0, - &result, &resultlen); - if (!err) - dump_or_store_buffer (arg_string, result, resultlen); - } - break; - - case cmdREADSHORTREC: - { - int short_ef; - - short_ef = strtol (arg_next, NULL, 0); - - if (short_ef < 1 || short_ef > 254) - printf ("error: short EF must be between 1 and 254\n"); - else - { - err = iso7816_read_record (slot, arg_number, 1, short_ef, - &result, &resultlen); - if (!err) - dump_or_store_buffer (arg_string, result, resultlen); - } - } - break; - - case cmdVERIFY: - if (arg_number < 0 || arg_number > 255 || (arg_number & 127) > 31) - printf ("error: invalid CHVNO\n"); - else - { - unsigned char *pin; - size_t pinlen; - - pin = pin_to_buffer (arg_next, &pinlen); - err = iso7816_verify (slot, arg_number, pin, pinlen); - xfree (pin); - } - break; - - case cmdCHANGEREF: - { - const char *newpin = arg_next; - - while ( *newpin && !spacep (newpin) ) - newpin++; - while ( spacep (newpin) ) - newpin++; - - if (arg_number < 0 || arg_number > 255 || (arg_number & 127) > 31) - printf ("error: invalid CHVNO\n"); - else if (!*arg_next || !*newpin || newpin == arg_next) - printf ("usage: changeref CHVNO OLDPIN NEWPIN\n"); - else - { - char *oldpin = xstrdup (arg_next); - unsigned char *oldpin_buf, *newpin_buf; - size_t oldpin_len, newpin_len; - - for (p=oldpin; *p && !spacep (p); p++ ) - ; - *p = 0; - oldpin_buf = pin_to_buffer (oldpin, &oldpin_len); - newpin_buf = pin_to_buffer (newpin, &newpin_len); - - err = iso7816_change_reference_data (slot, arg_number, - oldpin_buf, oldpin_len, - newpin_buf, newpin_len); - - xfree (newpin_buf); - xfree (oldpin_buf); - xfree (oldpin); - } - } - break; - - case cmdINVCMD: - default: - printf ("\n"); - printf ("Invalid command (try \"help\")\n"); - break; - } /* End command switch. */ - } /* End of main menu loop. */ - - leave: - ; -} - - - -/* Figure out whether the current card is a German Geldkarte and print - what we know about it. */ -static int -dump_geldkarte (int slot) -{ - unsigned char *r = NULL; - size_t rlen; - const char *t; - - if (iso7816_read_record (slot, 1, 1, 0xbc, &r, &rlen)) - return -1; - /* We require that the record is at least 24 bytes, the first byte - is 0x67 and the filler byte is correct. */ - if (rlen < 24 || *r != 0x67 || r[22]) - return -1; - - /* The short Bankleitzahl consists of 3 bytes at offset 1. */ - switch (r[1]) - { - case 0x21: t = "Oeffentlich-rechtliche oder private Bank"; break; - case 0x22: t = "Privat- oder Geschäftsbank"; break; - case 0x25: t = "Sparkasse"; break; - case 0x26: - case 0x29: t = "Genossenschaftsbank"; break; - default: - xfree (r); - return -1; /* Probably not a Geldkarte. */ - } - - printf ("KBLZ .....: %02X-%02X%02X (%s)\n", r[1], r[2], r[3], t); - printf ("Card-No ..: %02X%02X%02X%02X%02X\n", r[4], r[5], r[6], r[7], r[8]); - -/* Byte 10 enthält im linken Halbbyte eine Prüfziffer, die nach dem */ -/* Verfahren 'Luhn formula for computing modulus 10' über die Ziffern der */ -/* ersten 9 Byte berechnet ist. */ - -/* Das rechte Halbbyte wird zu 'D' gesetzt. */ - -/* Für die Berechnung der Luhn-Prüfziffer sind die folgenden Schritte */ -/* durchzuführen: */ - -/* Schritt 1: Mit der rechtesten Ziffer beginnend ist einschließlich dieser */ -/* Ziffer jede übernächste Ziffer zu verdoppeln (mit 2 multiplizieren). */ - -/* Schritt 2: Die einzelnen Ziffern der Produkte aus Schritt 1 und die bei */ -/* diesen Multiplikationen unberührt gebliebenen Ziffern sind zu addieren. */ - -/* Schritt 3: Das Ergebnis der Addition aus Schritt 2 ist von dem auf die */ -/* nächst höhere Zahl mit der Einerstelle 0 aufgerundeten Ergebnis der */ -/* Addition aus Schritt 2 abzuziehen. Wenn das Ergebnis der Addition aus */ -/* Schritt 2 bereits eine Zahl mit der Einerstelle 0 ergibt (z.B. 30, 40, */ -/* usw.), ist die Prüfziffer 0. */ - -/* Beispiel: Kartennummer ohne Prüfziffer: 992 839 871 */ - -/* 9 9 2 8 3 9 8 7 1 */ - -/* x 2 x 2 x 2 x 2 x 2 Schritt 1 */ - -/* 18 4 6 16 2 */ - -/* 1+8 +9 +4 +8 +6 +9 +1+6 +7 +2 = 61 Schritt 2 */ - -/* 70-61 = 9 Schritt 3 */ - -/* Prüfziffer zu 992 839 871 = 9 */ - - - printf ("Expires at: %02X/%02X\n", r[11], r[10] ); - printf ("Valid from: %02X.%02X.%02X\n", r[14], r[13], r[12]); - printf ("Country ..: %02X%02X\n", r[15], r[16]); - printf ("Currency .: %c%c%c\n", isascii (r[17])? r[17]:' ', - isascii (r[18])? r[18]:' ', isascii (r[19])? r[19]:' '); - printf ("Cur.-Mult : %s\n", - r[20] == 0x01? "0.01": - r[20] == 0x02? "0.1": - r[20] == 0x04? "1": - r[20] == 0x08? "10": - r[20] == 0x10? "100": - r[20] == 0x20? "1000": "?"); - printf ("ZKA ChipID: %02X\n", r[21]); - printf ("OS version: %02X\n", r[23]); - - xfree (r); - return 0; -} - - - -/* Try to figure out the type of teh card and dump its contents. */ -static void -dump_other_cards (int slot) -{ - - if (!dump_geldkarte (slot)) - return; - -} - diff --git a/scd/scdaemon.c b/scd/scdaemon.c deleted file mode 100644 index 5e9737ae4..000000000 --- a/scd/scdaemon.c +++ /dev/null @@ -1,933 +0,0 @@ -/* scdaemon.c - The GnuPG Smartcard Daemon - * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <stdarg.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <time.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <unistd.h> -#include <signal.h> -#ifdef USE_GNU_PTH -# include <pth.h> -#endif - -#define JNLIB_NEED_LOG_LOGV -#include "scdaemon.h" -#include <ksba.h> -#include <gcrypt.h> - -#include <assuan.h> /* malloc hooks */ - -#include "i18n.h" -#include "sysutils.h" -#include "app-common.h" - - -enum cmd_and_opt_values -{ aNull = 0, - oCsh = 'c', - oQuiet = 'q', - oSh = 's', - oVerbose = 'v', - - oNoVerbose = 500, - aGPGConfList, - oOptions, - oDebug, - oDebugAll, - oDebugLevel, - oDebugWait, - oDebugSC, - oNoGreeting, - oNoOptions, - oHomedir, - oNoDetach, - oNoGrab, - oLogFile, - oServer, - oDaemon, - oBatch, - oReaderPort, - octapiDriver, - opcscDriver, - oDisableCCID, - oDisableOpenSC, - oAllowAdmin, - oDenyAdmin, - -aTest }; - - - -static ARGPARSE_OPTS opts[] = { - - { aGPGConfList, "gpgconf-list", 256, "@" }, - - { 301, NULL, 0, N_("@Options:\n ") }, - - { oServer, "server", 0, N_("run in server mode (foreground)") }, - { oDaemon, "daemon", 0, N_("run in daemon mode (background)") }, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oSh, "sh", 0, N_("sh-style command output") }, - { oCsh, "csh", 0, N_("csh-style command output") }, - { oOptions, "options" , 2, N_("read options from file")}, - { oDebug, "debug" ,4|16, "@"}, - { oDebugAll, "debug-all" ,0, "@"}, - { oDebugLevel, "debug-level" ,2, "@"}, - { oDebugWait,"debug-wait",1, "@"}, - { oDebugSC, "debug-sc", 1, N_("|N|set OpenSC debug level to N")}, - { oNoDetach, "no-detach" ,0, N_("do not detach from the console")}, - { oLogFile, "log-file" ,2, N_("use a log file for the server")}, - { oReaderPort, "reader-port", 2, N_("|N|connect to reader at port N")}, - { octapiDriver, "ctapi-driver", 2, N_("|NAME|use NAME as ct-API driver")}, - { opcscDriver, "pcsc-driver", 2, N_("|NAME|use NAME as PC/SC driver")}, - { oDisableCCID, "disable-ccid", 0, -#ifdef HAVE_LIBUSB - N_("do not use the internal CCID driver") -#else - "@" -#endif - /* end --disable-ccid */}, - { oDisableOpenSC, "disable-opensc", 0, -#ifdef HAVE_OPENSC - N_("do not use the OpenSC layer") -#else - "@" -#endif - /* end --disable-opensc */}, - { oAllowAdmin, "allow-admin", 0, N_("allow the use of admin card commands")}, - { oDenyAdmin, "deny-admin", 0, "@" }, - - {0} -}; - - -#define DEFAULT_PCSC_DRIVER "libpcsclite.so" - - -static volatile int caught_fatal_sig = 0; - -/* Flag to indicate that a shutdown was requested. */ -static int shutdown_pending; - -/* It is possible that we are currently running under setuid permissions */ -static int maybe_setuid = 1; - -/* Name of the communication socket */ -static char socket_name[128]; - - -#ifdef USE_GNU_PTH -/* Pth wrapper function definitions. */ -GCRY_THREAD_OPTION_PTH_IMPL; - -static void *ticker_thread (void *arg); -#endif /*USE_GNU_PTH*/ - - -static const char * -my_strusage (int level) -{ - const char *p; - switch (level) - { - case 11: p = "scdaemon (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: scdaemon [options] (-h for help)"); - break; - case 41: p = _("Syntax: scdaemon [options] [command [args]]\n" - "Smartcard daemon for GnuPG\n"); - break; - - default: p = NULL; - } - return p; -} - - - -static void -i18n_init (void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE_GT ); -#else -#ifdef ENABLE_NLS - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE_GT, LOCALEDIR); - textdomain (PACKAGE_GT); -#endif -#endif -} - - - -/* Used by gcry for logging */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - /* translate the log levels */ - switch (level) - { - case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break; - case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break; - case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break; - case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break; - case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break; - case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break; - case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break; - default: level = JNLIB_LOG_ERROR; break; - } - log_logv (level, fmt, arg_ptr); -} - - -/* Setup the debugging. With a LEVEL of NULL only the active debug - flags are propagated to the subsystems. With LEVEL set, a specific - set of debug flags is set; thus overriding all flags already - set. */ -static void -set_debug (const char *level) -{ - if (!level) - ; - else if (!strcmp (level, "none")) - opt.debug = 0; - else if (!strcmp (level, "basic")) - opt.debug = DBG_ASSUAN_VALUE; - else if (!strcmp (level, "advanced")) - opt.debug = DBG_ASSUAN_VALUE|DBG_COMMAND_VALUE; - else if (!strcmp (level, "expert")) - opt.debug = (DBG_ASSUAN_VALUE|DBG_COMMAND_VALUE - |DBG_CACHE_VALUE|DBG_CARD_IO_VALUE); - else if (!strcmp (level, "guru")) - opt.debug = ~0; - else - { - log_error (_("invalid debug-level `%s' given\n"), level); - scd_exit(2); - } - - - if (opt.debug && !opt.verbose) - opt.verbose = 1; - if (opt.debug && opt.quiet) - opt.quiet = 0; - - if (opt.debug & DBG_MPI_VALUE) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2); - if (opt.debug & DBG_CRYPTO_VALUE ) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1); - gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); -} - - - -static void -cleanup (void) -{ - if (*socket_name) - { - char *p; - - remove (socket_name); - p = strrchr (socket_name, '/'); - if (p) - { - *p = 0; - rmdir (socket_name); - *p = '/'; - } - *socket_name = 0; - } -} - - -static RETSIGTYPE -cleanup_sh (int sig) -{ - if (caught_fatal_sig) - raise (sig); - caught_fatal_sig = 1; - - /* gcry_control( GCRYCTL_TERM_SECMEM );*/ - cleanup (); - -#ifndef HAVE_DOSISH_SYSTEM - { /* reset action to default action and raise signal again */ - struct sigaction nact; - nact.sa_handler = SIG_DFL; - sigemptyset( &nact.sa_mask ); - nact.sa_flags = 0; - sigaction( sig, &nact, NULL); - } -#endif - raise( sig ); -} - -int -main (int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - int orig_argc; - gpg_error_t err; - int may_coredump; - char **orig_argv; - FILE *configfp = NULL; - char *configname = NULL; - const char *shell; - unsigned configlineno; - int parse_debug = 0; - const char *debug_level = NULL; - int default_config =1; - int greeting = 0; - int nogreeting = 0; - int pipe_server = 0; - int is_daemon = 0; - int nodetach = 0; - int csh_style = 0; - char *logfile = NULL; - int debug_wait = 0; - int gpgconf_list = 0; - const char *config_filename = NULL; - - set_strusage (my_strusage); - gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - /* Please note that we may running SUID(ROOT), so be very CAREFUL - when adding any stuff between here and the call to INIT_SECMEM() - somewhere after the option parsing */ - log_set_prefix ("scdaemon", 1|4); - /* Try to auto set the character set. */ - set_native_charset (NULL); - - i18n_init (); - - /* Libgcrypt requires us to register the threading model first. - Note that this will also do the pth_init. */ -#ifdef USE_GNU_PTH - err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); - if (err) - { - log_fatal ("can't register GNU Pth with Libgcrypt: %s\n", - gpg_strerror (err)); - } -#endif /*USE_GNU_PTH*/ - - /* Check that the libraries are suitable. Do it here because - the option parsing may need services of the library */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal( _("libgcrypt is too old (need %s, have %s)\n"), - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - - ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - - assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - assuan_set_assuan_log_stream (log_get_stream ()); - assuan_set_assuan_log_prefix (log_get_prefix (NULL)); - - gcry_set_log_handler (my_gcry_logger, NULL); - gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); - - may_coredump = disable_core_dumps (); - - /* Set default options. */ - opt.pcsc_driver = DEFAULT_PCSC_DRIVER; - - - shell = getenv ("SHELL"); - if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") ) - csh_style = 1; - - /* FIXME: Using this homedir option does only make sense when not - running as a system service. We might want to check for this by - looking at the uid or ebtter use an explict option for this */ - opt.homedir = getenv("GNUPGHOME"); - if (!opt.homedir || !*opt.homedir) - opt.homedir = GNUPG_DEFAULT_HOMEDIR; - - /* check whether we have a config file on the commandline */ - orig_argc = argc; - orig_argv = argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */ - while (arg_parse( &pargs, opts)) - { - if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll) - parse_debug++; - else if (pargs.r_opt == oOptions) - { /* yes there is one, so we do not try the default one, but - read the option file when it is encountered at the - commandline */ - default_config = 0; - } - else if (pargs.r_opt == oNoOptions) - default_config = 0; /* --no-options */ - else if (pargs.r_opt == oHomedir) - opt.homedir = pargs.r.ret_str; - } - - /* initialize the secure memory. */ - gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); - maybe_setuid = 0; - - /* - Now we are working under our real uid - */ - - - if (default_config) - configname = make_filename (opt.homedir, "scdaemon.conf", NULL ); - - - argc = orig_argc; - argv = orig_argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - next_pass: - if (configname) - { - configlineno = 0; - configfp = fopen (configname, "r"); - if (!configfp) - { - if (default_config) - { - if( parse_debug ) - log_info (_("NOTE: no default option file `%s'\n"), - configname ); - } - else - { - log_error (_("option file `%s': %s\n"), - configname, strerror(errno) ); - exit(2); - } - xfree (configname); - configname = NULL; - } - if (parse_debug && configname ) - log_info (_("reading options from `%s'\n"), configname ); - default_config = 0; - } - - while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) ) - { - switch (pargs.r_opt) - { - case aGPGConfList: gpgconf_list = 1; break; - case oQuiet: opt.quiet = 1; break; - case oVerbose: opt.verbose++; break; - case oBatch: opt.batch=1; break; - - case oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oDebugLevel: debug_level = pargs.r.ret_str; break; - case oDebugWait: debug_wait = pargs.r.ret_int; break; - case oDebugSC: opt.debug_sc = pargs.r.ret_int; break; - - case oOptions: - /* config files may not be nested (silently ignore them) */ - if (!configfp) - { - xfree(configname); - configname = xstrdup(pargs.r.ret_str); - goto next_pass; - } - break; - case oNoGreeting: nogreeting = 1; break; - case oNoVerbose: opt.verbose = 0; break; - case oNoOptions: break; /* no-options */ - case oHomedir: opt.homedir = pargs.r.ret_str; break; - case oNoDetach: nodetach = 1; break; - case oLogFile: logfile = pargs.r.ret_str; break; - case oCsh: csh_style = 1; break; - case oSh: csh_style = 0; break; - case oServer: pipe_server = 1; break; - case oDaemon: is_daemon = 1; break; - - case oReaderPort: opt.reader_port = pargs.r.ret_str; break; - case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break; - case opcscDriver: opt.pcsc_driver = pargs.r.ret_str; break; - case oDisableCCID: opt.disable_ccid = 1; break; - case oDisableOpenSC: opt.disable_opensc = 1; break; - - case oAllowAdmin: opt.allow_admin = 1; break; - case oDenyAdmin: opt.allow_admin = 0; break; - - default : pargs.err = configfp? 1:2; break; - } - } - if (configfp) - { - fclose( configfp ); - configfp = NULL; - /* Keep a copy of the config name for use by --gpgconf-list. */ - config_filename = configname; - configname = NULL; - goto next_pass; - } - xfree (configname); - configname = NULL; - if (log_get_errorcount(0)) - exit(2); - if (nogreeting ) - greeting = 0; - - if (greeting) - { - fprintf (stderr, "%s %s; %s\n", - strusage(11), strusage(13), strusage(14) ); - fprintf (stderr, "%s\n", strusage(15) ); - } -#ifdef IS_DEVELOPMENT_VERSION - log_info ("NOTE: this is a development version!\n"); -#endif - - - if (atexit (cleanup)) - { - log_error ("atexit failed\n"); - cleanup (); - exit (1); - } - - set_debug (debug_level); - - if (debug_wait && pipe_server) - { - log_debug ("waiting for debugger - my pid is %u .....\n", - (unsigned int)getpid()); - sleep (debug_wait); - log_debug ("... okay\n"); - } - - if (gpgconf_list) - { - /* List options and default values in the GPG Conf format. */ - - /* The following list is taken from gnupg/tools/gpgconf-comp.c. */ - /* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING - FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */ -#define GC_OPT_FLAG_NONE 0UL - /* The RUNTIME flag for an option indicates that the option can be - changed at runtime. */ -#define GC_OPT_FLAG_RUNTIME (1UL << 3) - /* The DEFAULT flag for an option indicates that the option has a - default value. */ -#define GC_OPT_FLAG_DEFAULT (1UL << 4) - /* The DEF_DESC flag for an option indicates that the option has a - default, which is described by the value of the default field. */ -#define GC_OPT_FLAG_DEF_DESC (1UL << 5) - /* The NO_ARG_DESC flag for an option indicates that the argument has - a default, which is described by the value of the ARGDEF field. */ -#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) - if (!config_filename) - config_filename = make_filename (opt.homedir, "scdaemon.conf", NULL ); - - printf ("gpgconf-scdaemon.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, config_filename); - - printf ("verbose:%lu:\n" - "quiet:%lu:\n" - "debug-level:%lu:\"none:\n" - "log-file:%lu:\n", - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_DEFAULT, - GC_OPT_FLAG_NONE ); - - printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE ); - printf ("ctapi-driver:%lu:\n", GC_OPT_FLAG_NONE ); - printf ("pcsc-driver:%lu:\"%s:\n", - GC_OPT_FLAG_DEFAULT, DEFAULT_PCSC_DRIVER ); -#ifdef HAVE_LIBUSB - printf ("disable-ccid:%lu:\n", GC_OPT_FLAG_NONE ); -#endif -#ifdef HAVE_LIBUSB - printf ("disable-opensc:%lu:\n", GC_OPT_FLAG_NONE ); -#endif - printf ("allow-admin:%lu:\n", GC_OPT_FLAG_NONE ); - - - scd_exit (0); - } - - /* now start with logging to a file if this is desired */ - if (logfile) - { - log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); - } - - - if (pipe_server) - { /* This is the simple pipe based server */ -#ifdef USE_GNU_PTH - pth_attr_t tattr; - - tattr = pth_attr_new(); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, "ticker"); - - if (!pth_spawn (tattr, ticker_thread, NULL)) - { - log_error ("error spawning ticker thread: %s\n", strerror (errno)); - scd_exit (2); - } -#endif /*USE_GNU_PTH*/ - scd_command_handler (-1); - } - else if (!is_daemon) - { - log_info (_("please use the option `--daemon'" - " to run the program in the background\n")); - } - else - { /* regular server mode */ - int fd; - pid_t pid; - int i; - int len; - struct sockaddr_un serv_addr; - char *p; - - /* fixme: if there is already a running gpg-agent we should - share the same directory - and vice versa */ - *socket_name = 0; - snprintf (socket_name, DIM(socket_name)-1, - "/tmp/gpg-XXXXXX/S.scdaemon"); - socket_name[DIM(socket_name)-1] = 0; - p = strrchr (socket_name, '/'); - if (!p) - BUG (); - *p = 0;; - if (!mkdtemp(socket_name)) - { - log_error ("can't create directory `%s': %s\n", - socket_name, strerror(errno) ); - exit (1); - } - *p = '/'; - - if (strchr (socket_name, ':') ) - { - log_error ("colons are not allowed in the socket name\n"); - exit (1); - } - if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path ) - { - log_error ("name of socket to long\n"); - exit (1); - } - - - fd = socket (AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) - { - log_error ("can't create socket: %s\n", strerror(errno) ); - exit (1); - } - - memset (&serv_addr, 0, sizeof serv_addr); - serv_addr.sun_family = AF_UNIX; - strcpy (serv_addr.sun_path, socket_name); - len = (offsetof (struct sockaddr_un, sun_path) - + strlen(serv_addr.sun_path) + 1); - - if (bind (fd, (struct sockaddr*)&serv_addr, len) == -1) - { - log_error ("error binding socket to `%s': %s\n", - serv_addr.sun_path, strerror (errno) ); - close (fd); - exit (1); - } - - if (listen (fd, 5 ) == -1) - { - log_error ("listen() failed: %s\n", strerror (errno)); - close (fd); - exit (1); - } - - if (opt.verbose) - log_info ("listening on socket `%s'\n", socket_name ); - - - fflush (NULL); - pid = fork (); - if (pid == (pid_t)-1) - { - log_fatal ("fork failed: %s\n", strerror (errno) ); - exit (1); - } - else if (pid) - { /* we are the parent */ - char *infostr; - - close (fd); - - /* create the info string: <name>:<pid>:<protocol_version> */ - if (asprintf (&infostr, "SCDAEMON_INFO=%s:%lu:1", - socket_name, (ulong)pid ) < 0) - { - log_error ("out of core\n"); - kill (pid, SIGTERM); - exit (1); - } - *socket_name = 0; /* don't let cleanup() remove the socket - - the child should do this from now on */ - if (argc) - { /* run the program given on the commandline */ - if (putenv (infostr)) - { - log_error ("failed to set environment: %s\n", - strerror (errno) ); - kill (pid, SIGTERM ); - exit (1); - } - execvp (argv[0], argv); - log_error ("failed to run the command: %s\n", strerror (errno)); - kill (pid, SIGTERM); - exit (1); - } - else - { - /* print the environment string, so that the caller can use - shell's eval to set it */ - if (csh_style) - { - *strchr (infostr, '=') = ' '; - printf ( "setenv %s\n", infostr); - } - else - { - printf ( "%s; export SCDAEMON_INFO;\n", infostr); - } - free (infostr); - exit (0); - } - /* NOTREACHED */ - } /* end parent */ - - /* this is the child */ - - /* detach from tty and put process into a new session */ - if (!nodetach ) - { /* close stdin, stdout and stderr unless it is the log stream */ - for (i=0; i <= 2; i++) - { - if ( log_get_fd () != i) - close (i); - } - if (setsid() == -1) - { - log_error ("setsid() failed: %s\n", strerror(errno) ); - cleanup (); - exit (1); - } - } - - /* setup signals */ - { - struct sigaction oact, nact; - - nact.sa_handler = cleanup_sh; - sigemptyset (&nact.sa_mask); - nact.sa_flags = 0; - - sigaction (SIGHUP, NULL, &oact); - if (oact.sa_handler != SIG_IGN) - sigaction (SIGHUP, &nact, NULL); - sigaction( SIGTERM, NULL, &oact ); - if (oact.sa_handler != SIG_IGN) - sigaction (SIGTERM, &nact, NULL); - nact.sa_handler = SIG_IGN; - sigaction (SIGPIPE, &nact, NULL); - sigaction (SIGINT, &nact, NULL); - } - - if (chdir("/")) - { - log_error ("chdir to / failed: %s\n", strerror (errno)); - exit (1); - } - - scd_command_handler (fd); - - close (fd); - } - - return 0; -} - -void -scd_exit (int rc) -{ -#if 0 -#warning no update_random_seed_file - update_random_seed_file(); -#endif -#if 0 - /* at this time a bit annoying */ - if (opt.debug & DBG_MEMSTAT_VALUE) - { - gcry_control( GCRYCTL_DUMP_MEMORY_STATS ); - gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); - } - if (opt.debug) - gcry_control (GCRYCTL_DUMP_SECMEM_STATS ); -#endif - gcry_control (GCRYCTL_TERM_SECMEM ); - rc = rc? rc : log_get_errorcount(0)? 2 : 0; - exit (rc); -} - - -void -scd_init_default_ctrl (CTRL ctrl) -{ - ctrl->reader_slot = -1; -} - - -#ifdef USE_GNU_PTH - -static void -handle_signal (int signo) -{ - switch (signo) - { - case SIGHUP: - log_info ("SIGHUP received - " - "re-reading configuration and resetting cards\n"); -/* reread_configuration (); */ - break; - - case SIGUSR1: - log_info ("SIGUSR1 received - no action defined\n"); - break; - - case SIGUSR2: - log_info ("SIGUSR2 received - no action defined\n"); - break; - - case SIGTERM: - if (!shutdown_pending) - log_info ("SIGTERM received - shutting down ...\n"); - else - log_info ("SIGTERM received - still %ld running threads\n", - pth_ctrl( PTH_CTRL_GETTHREADS )); - shutdown_pending++; - if (shutdown_pending > 2) - { - log_info ("shutdown forced\n"); - log_info ("%s %s stopped\n", strusage(11), strusage(13) ); - cleanup (); - scd_exit (0); - } - break; - - case SIGINT: - log_info ("SIGINT received - immediate shutdown\n"); - log_info( "%s %s stopped\n", strusage(11), strusage(13)); - cleanup (); - scd_exit (0); - break; - - default: - log_info ("signal %d received - no action defined\n", signo); - } -} - -static void -handle_tick (void) -{ - scd_update_reader_status_file (); -} - -static void * -ticker_thread (void *dummy_arg) -{ - pth_event_t sigs_ev, time_ev = NULL; - sigset_t sigs; - int signo; - - sigemptyset (&sigs ); - sigaddset (&sigs, SIGHUP); - sigaddset (&sigs, SIGUSR1); - sigaddset (&sigs, SIGUSR2); - sigaddset (&sigs, SIGINT); - sigaddset (&sigs, SIGTERM); - sigs_ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); - - for (;;) - { - if (!time_ev) - { - time_ev = pth_event (PTH_EVENT_TIME, pth_timeout (2, 0)); - if (time_ev) - pth_event_concat (sigs_ev, time_ev, NULL); - } - - if (pth_wait (sigs_ev) < 1) - continue; - - if ( -#ifdef PTH_STATUS_OCCURRED /* This is Pth 2 */ - pth_event_status (sigs_ev) == PTH_STATUS_OCCURRED -#else - pth_event_occurred (sigs_ev) -#endif - ) - handle_signal (signo); - - /* Always run the ticker. */ - if (!shutdown_pending) - { - pth_event_isolate (sigs_ev); - pth_event_free (time_ev, PTH_FREE_ALL); - time_ev = NULL; - handle_tick (); - } - } - - pth_event_free (sigs_ev, PTH_FREE_ALL); -} -#endif /*USE_GNU_PTH*/ diff --git a/scd/scdaemon.h b/scd/scdaemon.h deleted file mode 100644 index 1dd32ae90..000000000 --- a/scd/scdaemon.h +++ /dev/null @@ -1,130 +0,0 @@ -/* scdaemon.h - Global definitions for the SCdaemon - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef SCDAEMON_H -#define SCDAEMON_H - -#ifdef GPG_ERR_SOURCE_DEFAULT -#error GPG_ERR_SOURCE_DEFAULT already defined -#endif -#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_SCD -#include <gpg-error.h> -#include <errno.h> - -#include <time.h> -#include <gcrypt.h> -#include "../common/util.h" -#include "../common/errors.h" - - -#define MAX_DIGEST_LEN 24 - -/* A large struct name "opt" to keep global flags */ -struct { - unsigned int debug; /* debug flags (DBG_foo_VALUE) */ - int debug_sc; /* OpenSC debug level */ - int verbose; /* verbosity level */ - int quiet; /* be as quiet as possible */ - int dry_run; /* don't change any persistent data */ - int batch; /* batch mode */ - const char *homedir; /* configuration directory name */ - const char *ctapi_driver; /* Library to access the ctAPI. */ - const char *pcsc_driver; /* Library to access the PC/SC system. */ - const char *reader_port; /* NULL or reder port to use. */ - int disable_opensc; /* Disable the use of the OpenSC framework. */ - int disable_ccid; /* Disable the use of the internal CCID driver. */ - int allow_admin; /* Allow the use of admin commands for certain - cards. */ -} opt; - - -#define DBG_COMMAND_VALUE 1 /* debug commands i/o */ -#define DBG_MPI_VALUE 2 /* debug mpi details */ -#define DBG_CRYPTO_VALUE 4 /* debug low level crypto */ -#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */ -#define DBG_CACHE_VALUE 64 /* debug the caching */ -#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ -#define DBG_HASHING_VALUE 512 /* debug hashing operations */ -#define DBG_ASSUAN_VALUE 1024 -#define DBG_CARD_IO_VALUE 2048 - -#define DBG_COMMAND (opt.debug & DBG_COMMAND_VALUE) -#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE) -#define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE) -#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE) -#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) -#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE) -#define DBG_CARD_IO (opt.debug & DBG_CARD_IO_VALUE) - -struct server_local_s; -struct card_ctx_s; -struct app_ctx_s; - -struct server_control_s { - struct server_local_s *server_local; - int reader_slot; /* Slot of the open reader or -1 if not open. */ - struct card_ctx_s *card_ctx; - struct app_ctx_s *app_ctx; - struct { - unsigned char *value; - int valuelen; - } in_data; /* helper to store the value we are going to sign */ - -}; - -typedef struct server_control_s *CTRL; -typedef struct server_control_s *ctrl_t; -typedef struct card_ctx_s *CARD; -typedef struct app_ctx_s *APP; -typedef struct app_ctx_s *app_t; - -/*-- scdaemon.c --*/ -void scd_exit (int rc); -void scd_init_default_ctrl (CTRL ctrl); - -/*-- command.c --*/ -void scd_command_handler (int); -void send_status_info (CTRL ctrl, const char *keyword, ...); -void scd_update_reader_status_file (void); - -/*-- card.c --*/ -int card_open (CARD *rcard); -void card_close (CARD card); -int card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp); -int card_enum_keypairs (CARD card, int idx, - unsigned char *keygrip, - char **keyid); -int card_enum_certs (CARD card, int idx, char **certid, int *certtype); -int card_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert); -int card_sign (CARD card, - const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ); -int card_decipher (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen); - - -#endif /*SCDAEMON_H*/ diff --git a/scd/tlv.c b/scd/tlv.c deleted file mode 100644 index 5b9d0d6b9..000000000 --- a/scd/tlv.c +++ /dev/null @@ -1,208 +0,0 @@ -/* tlv.c - Tag-Length-Value Utilities - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include <gpg-error.h> - -#include "tlv.h" - -static const unsigned char * -do_find_tlv (const unsigned char *buffer, size_t length, - int tag, size_t *nbytes, int nestlevel) -{ - const unsigned char *s = buffer; - size_t n = length; - size_t len; - int this_tag; - int composite; - - for (;;) - { - buffer = s; - if (n < 2) - return NULL; /* Buffer definitely too short for tag and length. */ - if (!*s || *s == 0xff) - { /* Skip optional filler between TLV objects. */ - s++; - n--; - continue; - } - composite = !!(*s & 0x20); - if ((*s & 0x1f) == 0x1f) - { /* more tag bytes to follow */ - s++; - n--; - if (n < 2) - return NULL; /* buffer definitely too short for tag and length. */ - if ((*s & 0x1f) == 0x1f) - return NULL; /* We support only up to 2 bytes. */ - this_tag = (s[-1] << 8) | (s[0] & 0x7f); - } - else - this_tag = s[0]; - len = s[1]; - s += 2; n -= 2; - if (len < 0x80) - ; - else if (len == 0x81) - { /* One byte length follows. */ - if (!n) - return NULL; /* we expected 1 more bytes with the length. */ - len = s[0]; - s++; n--; - } - else if (len == 0x82) - { /* Two byte length follows. */ - if (n < 2) - return NULL; /* We expected 2 more bytes with the length. */ - len = (s[0] << 8) | s[1]; - s += 2; n -= 2; - } - else - return NULL; /* APDU limit is 65535, thus it does not make - sense to assume longer length fields. */ - - if (composite && nestlevel < 100) - { /* Dive into this composite DO after checking for a too deep - nesting. */ - const unsigned char *tmp_s; - size_t tmp_len; - - tmp_s = do_find_tlv (s, len, tag, &tmp_len, nestlevel+1); - if (tmp_s) - { - *nbytes = tmp_len; - return tmp_s; - } - } - - if (this_tag == tag) - { - *nbytes = len; - return s; - } - if (len > n) - return NULL; /* Buffer too short to skip to the next tag. */ - s += len; n -= len; - } -} - - -/* Locate a TLV encoded data object in BUFFER of LENGTH and - return a pointer to value as well as its length in NBYTES. Return - NULL if it was not found. Note, that the function does not check - whether the value fits into the provided buffer. */ -const unsigned char * -find_tlv (const unsigned char *buffer, size_t length, - int tag, size_t *nbytes) -{ - return do_find_tlv (buffer, length, tag, nbytes, 0); -} - - - - -/* ASN.1 BER parser: Parse BUFFER of length SIZE and return the tag - and the length part from the TLV triplet. Update BUFFER and SIZE - on success. */ -gpg_error_t -parse_ber_header (unsigned char const **buffer, size_t *size, - int *r_class, int *r_tag, - int *r_constructed, int *r_ndef, - size_t *r_length, size_t *r_nhdr) -{ - int c; - unsigned long tag; - const unsigned char *buf = *buffer; - size_t length = *size; - - *r_ndef = 0; - *r_length = 0; - *r_nhdr = 0; - - /* Get the tag. */ - if (!length) - return gpg_error (GPG_ERR_EOF); - c = *buf++; length--; ++*r_nhdr; - - *r_class = (c & 0xc0) >> 6; - *r_constructed = !!(c & 0x20); - tag = c & 0x1f; - - if (tag == 0x1f) - { - tag = 0; - do - { - tag <<= 7; - if (!length) - return gpg_error (GPG_ERR_EOF); - c = *buf++; length--; ++*r_nhdr; - tag |= c & 0x7f; - - } - while (c & 0x80); - } - *r_tag = tag; - - /* Get the length. */ - if (!length) - return gpg_error (GPG_ERR_EOF); - c = *buf++; length--; ++*r_nhdr; - - if ( !(c & 0x80) ) - *r_length = c; - else if (c == 0x80) - *r_ndef = 1; - else if (c == 0xff) - return gpg_error (GPG_ERR_BAD_BER); - else - { - unsigned long len = 0; - int count = c & 0x7f; - - if (count > sizeof (len) || count > sizeof (size_t)) - return gpg_error (GPG_ERR_BAD_BER); - - for (; count; count--) - { - len <<= 8; - if (!length) - return gpg_error (GPG_ERR_EOF); - c = *buf++; length--; ++*r_nhdr; - len |= c & 0xff; - } - *r_length = len; - } - - /* Without this kludge some example certs can't be parsed. */ - if (*r_class == CLASS_UNIVERSAL && !*r_tag) - *r_length = 0; - - *buffer = buf; - *size = length; - return 0; -} diff --git a/scd/tlv.h b/scd/tlv.h deleted file mode 100644 index 26a9905f7..000000000 --- a/scd/tlv.h +++ /dev/null @@ -1,84 +0,0 @@ -/* tlv.h - Tag-Length-Value Utilities - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef SCD_TLV_H -#define SCD_TLV_H 1 - - -enum tlv_tag_class { - CLASS_UNIVERSAL = 0, - CLASS_APPLICATION = 1, - CLASS_CONTEXT = 2, - CLASS_PRIVATE =3 -}; - -enum tlv_tag_type { - TAG_NONE = 0, - TAG_BOOLEAN = 1, - TAG_INTEGER = 2, - TAG_BIT_STRING = 3, - TAG_OCTET_STRING = 4, - TAG_NULL = 5, - TAG_OBJECT_ID = 6, - TAG_OBJECT_DESCRIPTOR = 7, - TAG_EXTERNAL = 8, - TAG_REAL = 9, - TAG_ENUMERATED = 10, - TAG_EMBEDDED_PDV = 11, - TAG_UTF8_STRING = 12, - TAG_REALTIVE_OID = 13, - TAG_SEQUENCE = 16, - TAG_SET = 17, - TAG_NUMERIC_STRING = 18, - TAG_PRINTABLE_STRING = 19, - TAG_TELETEX_STRING = 20, - TAG_VIDEOTEX_STRING = 21, - TAG_IA5_STRING = 22, - TAG_UTC_TIME = 23, - TAG_GENERALIZED_TIME = 24, - TAG_GRAPHIC_STRING = 25, - TAG_VISIBLE_STRING = 26, - TAG_GENERAL_STRING = 27, - TAG_UNIVERSAL_STRING = 28, - TAG_CHARACTER_STRING = 29, - TAG_BMP_STRING = 30 -}; - - - -/* Locate a TLV encoded data object in BUFFER of LENGTH and return a - pointer to value as well as its length in NBYTES. Return NULL if - it was not found. Note, that the function does not check whether - the value fits into the provided buffer.*/ -const unsigned char *find_tlv (const unsigned char *buffer, size_t length, - int tag, size_t *nbytes); - - -/* ASN.1 BER parser: Parse BUFFER of length SIZE and return the tag - and the length part from the TLV triplet. Update BUFFER and SIZE - on success. */ -gpg_error_t parse_ber_header (unsigned char const **buffer, size_t *size, - int *r_class, int *r_tag, - int *r_constructed, - int *r_ndef, size_t *r_length, size_t *r_nhdr); - - - -#endif /* SCD_TLV_H */ diff --git a/scripts/compile b/scripts/compile deleted file mode 100755 index ac07cc541..000000000 --- a/scripts/compile +++ /dev/null @@ -1,107 +0,0 @@ -#! /bin/sh - -# Wrapper for compilers which do not understand `-c -o'. - -# Copyright 1999, 2000 Free Software Foundation, Inc. -# Written by Tom Tromey <tromey@cygnus.com>. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Usage: -# compile PROGRAM [ARGS]... -# `-o FOO.o' is removed from the args passed to the actual compile. - -# Usage statement added by Billy Biggs <vektor@dumbterm.net>. -if [ -z $1 ]; then - echo "Wrapper for compilers which do not understand '-c -o'." - echo "usage: compile PROGRAM [ARGS]..." - echo "'-o FOO.o' is removed from the args passed to the actual compile." - exit 1 -fi - -prog=$1 -shift - -ofile= -cfile= -args= -while test $# -gt 0; do - case "$1" in - -o) - # configure might choose to run compile as `compile cc -o foo foo.c'. - # So we do something ugly here. - ofile=$2 - shift - case "$ofile" in - *.o | *.obj) - ;; - *) - args="$args -o $ofile" - ofile= - ;; - esac - ;; - *.c) - cfile=$1 - args="$args $1" - ;; - *) - args="$args $1" - ;; - esac - shift -done - -if test -z "$ofile" || test -z "$cfile"; then - # If no `-o' option was seen then we might have been invoked from a - # pattern rule where we don't need one. That is ok -- this is a - # normal compilation that the losing compiler can handle. If no - # `.c' file was seen then we are probably linking. That is also - # ok. - exec "$prog" $args -fi - -# Name of file we expect compiler to create. -cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'` - -# Create the lock directory. -# Note: use `[/.-]' here to ensure that we don't use the same name -# that we are using for the .o file. Also, base the name on the expected -# object file name, since that is what matters with a parallel build. -lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d -while true; do - if mkdir $lockdir > /dev/null 2>&1; then - break - fi - sleep 1 -done -# FIXME: race condition here if user kills between mkdir and trap. -trap "rmdir $lockdir; exit 1" 1 2 15 - -# Run the compile. -"$prog" $args -status=$? - -if test -f "$cofile"; then - mv "$cofile" "$ofile" -fi - -rmdir $lockdir -exit $status diff --git a/scripts/config.guess b/scripts/config.guess deleted file mode 100755 index ed2e03b7f..000000000 --- a/scripts/config.guess +++ /dev/null @@ -1,1321 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002 Free Software Foundation, Inc. - -timestamp='2002-03-20' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Per Bothner <per@bothner.com>. -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - - -dummy=dummy-$$ -trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int dummy(){}" > $dummy.c ; - for c in cc gcc c89 c99 ; do - ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; - if test $? = 0 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - rm -f $dummy.c $dummy.o $dummy.rel ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit 0 ;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - arc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - macppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvmeppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - pmax:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mipseb-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sun3:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - wgrisc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - alpha:OSF1:*:*) - if test $UNAME_RELEASE = "V4.0"; then - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - fi - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - cat <<EOF >$dummy.s - .data -\$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main -main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - eval $set_cc_for_build - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `./$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - 2-1307) - UNAME_MACHINE="alphaev68" - ;; - esac - fi - rm -f $dummy.s $dummy - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit 0 ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit 0 ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit 0 ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit 0;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit 0 ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit 0 ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit 0 ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit 0;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit 0;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit 0 ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit 0 ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit 0 ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit 0 ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit 0 ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit 0 ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit 0 ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit 0 ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit 0 ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include <stdio.h> /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy \ - && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo mips-mips-riscos${UNAME_RELEASE} - exit 0 ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit 0 ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit 0 ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit 0 ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit 0 ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit 0 ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit 0 ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit 0 ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit 0 ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit 0 ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit 0 ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit 0 ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit 0 ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <sys/systemcfg.h> - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo rs6000-ibm-aix3.2.5 - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit 0 ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit 0 ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit 0 ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit 0 ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit 0 ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit 0 ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit 0 ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include <stdlib.h> - #include <unistd.h> - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` - if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi - rm -f $dummy.c $dummy - fi ;; - esac - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit 0 ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit 0 ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <unistd.h> - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo unknown-hitachi-hiuxwe2 - exit 0 ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit 0 ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit 0 ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit 0 ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit 0 ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit 0 ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit 0 ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit 0 ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit 0 ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit 0 ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit 0 ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit 0 ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3D:*:*:*) - echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit 0 ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit 0 ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit 0 ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit 0 ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit 0 ;; - x86:Interix*:3*) - echo i386-pc-interix3 - exit 0 ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i386-pc-interix - exit 0 ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit 0 ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit 0 ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit 0 ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - rm -f $dummy.c - test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 - ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit 0 ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit 0 ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit 0 ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit 0 ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit 0 ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit 0 ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit 0 ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit 0 ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <features.h> - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - rm -f $dummy.c - test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 - test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit 0 ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit 0 ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit 0 ;; - i*86:*:5:[78]*) - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit 0 ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` - echo ${UNAME_MACHINE}-pc-isc$UNAME_REL - elif /bin/uname -X 2>/dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` - (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit 0 ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit 0 ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit 0 ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit 0 ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit 0 ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit 0 ;; - M68*:*:R3V[567]*:*) - test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4.3${OS_REL} && exit 0 - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit 0 ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit 0 ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit 0 ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <Richard.M.Bartel@ccMail.Census.GOV> - echo i586-unisys-sysv4 - exit 0 ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes <hewes@openmarket.com>. - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit 0 ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit 0 ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit 0 ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit 0 ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit 0 ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit 0 ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit 0 ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit 0 ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit 0 ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit 0 ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit 0 ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Darwin:*:*) - echo `uname -p`-apple-darwin${UNAME_RELEASE} - exit 0 ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit 0 ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit 0 ;; - NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit 0 ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit 0 ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit 0 ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit 0 ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit 0 ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit 0 ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit 0 ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit 0 ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit 0 ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit 0 ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit 0 ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit 0 ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c <<EOF -#ifdef _SEQUENT_ -# include <sys/types.h> -# include <sys/utsname.h> -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include <sys/param.h> - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include <sys/param.h> -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 -rm -f $dummy.c $dummy - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit 0 ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - c34*) - echo c34-convex-bsd - exit 0 ;; - c38*) - echo c38-convex-bsd - exit 0 ;; - c4*) - echo c4-convex-bsd - exit 0 ;; - esac -fi - -cat >&2 <<EOF -$0: unable to guess system type - -This script, last modified $timestamp, has failed to recognize -the operating system you are using. It is advised that you -download the most up to date version of the config scripts from - - ftp://ftp.gnu.org/pub/gnu/config/ - -If the version you run ($0) is already up to date, please -send the following data and any information you think might be -pertinent to <config-patches@gnu.org> in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/scripts/config.rpath b/scripts/config.rpath deleted file mode 100755 index fa24bfc2d..000000000 --- a/scripts/config.rpath +++ /dev/null @@ -1,548 +0,0 @@ -#! /bin/sh -# Output a system dependent set of variables, describing how to set the -# run time search path of shared libraries in an executable. -# -# Copyright 1996-2003 Free Software Foundation, Inc. -# Taken from GNU libtool, 2001 -# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. -# -# The first argument passed to this file is the canonical host specification, -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld -# should be set by the caller. -# -# The set of defined variables is at the end of this script. - -# Known limitations: -# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer -# than 256 bytes, otherwise the compiler driver will dump core. The only -# known workaround is to choose shorter directory names for the build -# directory and/or the installation directory. - -# All known linkers require a `.a' archive for static linking (except M$VC, -# which needs '.lib'). -libext=a -shrext=.so - -host="$1" -host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - -# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC. - -wl= -if test "$GCC" = yes; then - wl='-Wl,' -else - case "$host_os" in - aix*) - wl='-Wl,' - ;; - mingw* | pw32* | os2*) - ;; - hpux9* | hpux10* | hpux11*) - wl='-Wl,' - ;; - irix5* | irix6* | nonstopux*) - wl='-Wl,' - ;; - newsos6) - ;; - linux*) - case $CC in - icc|ecc) - wl='-Wl,' - ;; - ccc) - wl='-Wl,' - ;; - esac - ;; - osf3* | osf4* | osf5*) - wl='-Wl,' - ;; - sco3.2v5*) - ;; - solaris*) - wl='-Wl,' - ;; - sunos4*) - wl='-Qoption ld ' - ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - wl='-Wl,' - ;; - sysv4*MP*) - ;; - uts4*) - ;; - esac -fi - -# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. - -hardcode_libdir_flag_spec= -hardcode_libdir_separator= -hardcode_direct=no -hardcode_minus_L=no - -case "$host_os" in - cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - openbsd*) - with_gnu_ld=no - ;; -esac - -ld_shlibs=yes -if test "$with_gnu_ld" = yes; then - case "$host_os" in - aix3* | aix4* | aix5*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs=no - fi - ;; - amigaos*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can use - # them. - ld_shlibs=no - ;; - beos*) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - cygwin* | mingw* | pw32*) - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - netbsd*) - ;; - solaris* | sysv5*) - if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - sunos4*) - hardcode_direct=yes - ;; - *) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - esac - if test "$ld_shlibs" = yes; then - # Unlike libtool, we use -rpath here, not --rpath, since the documented - # option of GNU ld is called -rpath, not --rpath. - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - fi -else - case "$host_os" in - aix3*) - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - else - aix_use_runtimelinking=no - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - esac - fi - hardcode_direct=yes - hardcode_libdir_separator=':' - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct=yes - else - # We have old collect2 - hardcode_direct=unsupported - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - esac - fi - # Begin _LT_AC_SYS_LIBPATH_AIX. - echo 'int main () { return 0; }' > conftest.c - ${CC} ${LDFLAGS} conftest.c -o conftest - aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` - if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` - fi - if test -z "$aix_libpath"; then - aix_libpath="/usr/lib:/lib" - fi - rm -f conftest.c conftest - # End _LT_AC_SYS_LIBPATH_AIX. - if test "$aix_use_runtimelinking" = yes; then - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - else - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - fi - fi - ;; - amigaos*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # see comment about different semantics on the GNU ld section - ld_shlibs=no - ;; - bsdi4*) - ;; - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - libext=lib - ;; - darwin* | rhapsody*) - if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then - hardcode_direct=no - fi - ;; - dgux*) - hardcode_libdir_flag_spec='-L$libdir' - ;; - freebsd1*) - ld_shlibs=no - ;; - freebsd2.2*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - freebsd2*) - hardcode_direct=yes - hardcode_minus_L=yes - ;; - freebsd*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - hpux9*) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - hpux10* | hpux11*) - if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=no - ;; - ia64*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=no - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - *) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - irix5* | irix6* | nonstopux*) - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - netbsd*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - newsos6) - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - openbsd*) - hardcode_direct=yes - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - else - case "$host_os" in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - osf3*) - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - osf4* | osf5*) - if test "$GCC" = yes; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - # Both cc and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - hardcode_libdir_separator=: - ;; - sco3.2v5*) - ;; - solaris*) - hardcode_libdir_flag_spec='-R$libdir' - ;; - sunos4*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - ;; - sysv4) - case $host_vendor in - sni) - hardcode_direct=yes # is this really true??? - ;; - siemens) - hardcode_direct=no - ;; - motorola) - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - ;; - sysv4.3*) - ;; - sysv4*MP*) - if test -d /usr/nec; then - ld_shlibs=yes - fi - ;; - sysv4.2uw2*) - hardcode_direct=yes - hardcode_minus_L=no - ;; - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - ;; - sysv5*) - hardcode_libdir_flag_spec= - ;; - uts4*) - hardcode_libdir_flag_spec='-L$libdir' - ;; - *) - ld_shlibs=no - ;; - esac -fi - -# Check dynamic linker characteristics -# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER. -libname_spec='lib$name' -case "$host_os" in - aix3*) - ;; - aix4* | aix5*) - ;; - amigaos*) - ;; - beos*) - ;; - bsdi4*) - ;; - cygwin* | mingw* | pw32*) - shrext=.dll - ;; - darwin* | rhapsody*) - shrext=.dylib - ;; - dgux*) - ;; - freebsd1*) - ;; - freebsd*) - ;; - gnu*) - ;; - hpux9* | hpux10* | hpux11*) - case "$host_cpu" in - ia64*) - shrext=.so - ;; - hppa*64*) - shrext=.sl - ;; - *) - shrext=.sl - ;; - esac - ;; - irix5* | irix6* | nonstopux*) - case "$host_os" in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; - *) libsuff= shlibsuff= ;; - esac - ;; - esac - ;; - linux*oldld* | linux*aout* | linux*coff*) - ;; - linux*) - ;; - netbsd*) - ;; - newsos6) - ;; - nto-qnx) - ;; - openbsd*) - ;; - os2*) - libname_spec='$name' - shrext=.dll - ;; - osf3* | osf4* | osf5*) - ;; - sco3.2v5*) - ;; - solaris*) - ;; - sunos4*) - ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - ;; - sysv4*MP*) - ;; - uts4*) - ;; -esac - -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' -escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` -shlibext=`echo "$shrext" | sed -e 's,^\.,,'` -escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` - -sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF - -# How to pass a linker flag through the compiler. -wl="$escaped_wl" - -# Static library suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally "so"). -shlibext="$shlibext" - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec" - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator="$hardcode_libdir_separator" - -# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the -# resulting binary. -hardcode_direct="$hardcode_direct" - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L="$hardcode_minus_L" - -EOF diff --git a/scripts/config.sub b/scripts/config.sub deleted file mode 100755 index f3657978c..000000000 --- a/scripts/config.sub +++ /dev/null @@ -1,1443 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002 Free Software Foundation, Inc. - -timestamp='2002-03-07' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit 0;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | c4x | clipper \ - | d10v | d30v | dsp16xx \ - | fr30 \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | m32r | m68000 | m68k | m88k | mcore \ - | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el | mips64vr4300 \ - | mips64vr4300el | mips64vr5000 | mips64vr5000el \ - | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ - | mipsisa32 | mipsisa64 \ - | mn10200 | mn10300 \ - | ns16k | ns32k \ - | openrisc | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ - | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xscale | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armv*-* \ - | avr-* \ - | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c54x-* \ - | clipper-* | cydra-* \ - | d10v-* | d30v-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | m32r-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | mcore-* \ - | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ - | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ - | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ - | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ - | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ - | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - crds | unos) - basic_machine=m68k-crds - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - mmix*) - basic_machine=mmix-knuth - os=-mmixware - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - or32 | or32-*) - basic_machine=or32-unknown - os=-coff - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon) - basic_machine=i686-pc - ;; - pentiumii | pentium2) - basic_machine=i686-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3d) - basic_machine=alpha-cray - os=-unicos - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - windows32) - basic_machine=i386-pc - os=-windows32-msvcrt - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh3 | sh4 | sh3eb | sh4eb) - basic_machine=sh-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparc | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - c4x*) - basic_machine=c4x-none - os=-coff - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto*) - os=-nto-qnx - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-ibm) - os=-aix - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -vxsim* | -vxworks*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/scripts/depcomp b/scripts/depcomp deleted file mode 100755 index aea3d0078..000000000 --- a/scripts/depcomp +++ /dev/null @@ -1,472 +0,0 @@ -#! /bin/sh - -# depcomp - compile a program generating dependencies as side-effects -# Copyright 1999, 2000 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi -# `libtool' can also be set to `yes' or `no'. - -if test -z "$depfile"; then - base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` - dir=`echo "$object" | sed 's,/.*$,/,'` - if test "$dir" = "$object"; then - dir= - fi - # FIXME: should be _deps on DOS. - depfile="$dir.deps/$base" -fi - -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. - "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory -## that the space means something, we add a space to the output as -## well. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the - # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> $depfile - echo >> $depfile - - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> $depfile - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. This file always lives in the current directory. - # Also, the AIX compiler puts `$object:' at the start of each line; - # $object doesn't have directory information. - stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` - tmpdepfile="$stripped.u" - outname="$stripped.o" - if test "$libtool" = yes; then - "$@" -Wc,-M - else - "$@" -M - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - - if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" - sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - tmpdepfile1="$dir.libs/$base.lo.d" - tmpdepfile2="$dir.libs/$base.d" - "$@" -Wc,-MD - else - tmpdepfile1="$dir$base.o.d" - tmpdepfile2="$dir$base.d" - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - if test -f "$tmpdepfile1"; then - tmpdepfile="$tmpdepfile1" - else - tmpdepfile="$tmpdepfile2" - fi - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a space and a tab in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the proprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' - # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. - "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # Remove any Libtool call - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - # X makedepend - shift - cleared=no - for arg in "$@"; do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - # Strip any option that makedepend may not understand. Remove - # the object too, otherwise makedepend will parse it as a source file. - -*|$object) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix="`echo $object | sed 's/^.*\././'`" - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the proprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E | - sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the proprocessed file to stdout, regardless of -o, - # because we must use -o when running libtool. - "$@" || exit $? - IFS=" " - for arg - do - case "$arg" in - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 diff --git a/scripts/install-sh b/scripts/install-sh deleted file mode 100755 index 6ce63b9f7..000000000 --- a/scripts/install-sh +++ /dev/null @@ -1,294 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd=$cpprog - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd=$stripprog - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "$0: no input file specified" >&2 - exit 1 -else - : -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d "$dst" ]; then - instcmd=: - chmodcmd="" - else - instcmd=$mkdirprog - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f "$src" ] || [ -d "$src" ] - then - : - else - echo "$0: $src does not exist" >&2 - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "$0: no destination specified" >&2 - exit 1 - else - : - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d "$dst" ] - then - dst=$dst/`basename "$src"` - else - : - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' - ' -IFS="${IFS-$defaultIFS}" - -oIFS=$IFS -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS=$oIFS - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp=$pathcomp$1 - shift - - if [ ! -d "$pathcomp" ] ; - then - $mkdirprog "$pathcomp" - else - : - fi - - pathcomp=$pathcomp/ -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd "$dst" && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename "$dst"` - else - dstfile=`basename "$dst" $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename "$dst"` - else - : - fi - -# Make a couple of temp file names in the proper directory. - - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - -# Trap to clean up temp files at exit. - - trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 - trap '(exit $?); exit' 1 2 13 15 - -# Move or copy the file name to the temp name - - $doit $instcmd "$src" "$dsttmp" && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && - -# Now remove or move aside any old file at destination location. We try this -# two ways since rm can't unlink itself on some systems and the destination -# file might be busy for other reasons. In this case, the final cleanup -# might fail but the new file should still install successfully. - -{ - if [ -f "$dstdir/$dstfile" ] - then - $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || - $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || - { - echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 - (exit 1); exit - } - else - : - fi -} && - -# Now rename the file to the real destination. - - $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" - -fi && - -# The final little trick to "correctly" pass the exit status to the exit trap. - -{ - (exit 0); exit -} diff --git a/scripts/mdate-sh b/scripts/mdate-sh deleted file mode 100755 index b610b47a6..000000000 --- a/scripts/mdate-sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/bin/sh -# Get modification time of a file or directory and pretty-print it. -# Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc. -# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Prevent date giving response in another language. -LANG=C -export LANG -LC_ALL=C -export LC_ALL -LC_TIME=C -export LC_TIME - -save_arg1="$1" - -# Find out how to get the extended ls output of a file or directory. -if ls -L /dev/null 1>/dev/null 2>&1; then - ls_command='ls -L -l -d' -else - ls_command='ls -l -d' -fi - -# A `ls -l' line looks as follows on OS/2. -# drwxrwx--- 0 Aug 11 2001 foo -# This differs from Unix, which adds ownership information. -# drwxrwx--- 2 root root 4096 Aug 11 2001 foo -# -# To find the date, we split the line on spaces and iterate on words -# until we find a month. This cannot work with files whose owner is a -# user named `Jan', or `Feb', etc. However, it's unlikely that `/' -# will be owned by a user whose name is a month. So we first look at -# the extended ls output of the root directory to decide how many -# words should be skipped to get the date. - -# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. -set - x`$ls_command /` - -# Find which argument is the month. -month= -command= -until test $month -do - shift - # Add another shift to the command. - command="$command shift;" - case $1 in - Jan) month=January; nummonth=1;; - Feb) month=February; nummonth=2;; - Mar) month=March; nummonth=3;; - Apr) month=April; nummonth=4;; - May) month=May; nummonth=5;; - Jun) month=June; nummonth=6;; - Jul) month=July; nummonth=7;; - Aug) month=August; nummonth=8;; - Sep) month=September; nummonth=9;; - Oct) month=October; nummonth=10;; - Nov) month=November; nummonth=11;; - Dec) month=December; nummonth=12;; - esac -done - -# Get the extended ls output of the file or directory. -set - x`eval "$ls_command \"\$save_arg1\""` - -# Remove all preceding arguments -eval $command - -# Get the month. Next argument is day, followed by the year or time. -case $1 in - Jan) month=January; nummonth=1;; - Feb) month=February; nummonth=2;; - Mar) month=March; nummonth=3;; - Apr) month=April; nummonth=4;; - May) month=May; nummonth=5;; - Jun) month=June; nummonth=6;; - Jul) month=July; nummonth=7;; - Aug) month=August; nummonth=8;; - Sep) month=September; nummonth=9;; - Oct) month=October; nummonth=10;; - Nov) month=November; nummonth=11;; - Dec) month=December; nummonth=12;; -esac - -day=$2 - -# Here we have to deal with the problem that the ls output gives either -# the time of day or the year. -case $3 in - *:*) set `date`; eval year=\$$# - case $2 in - Jan) nummonthtod=1;; - Feb) nummonthtod=2;; - Mar) nummonthtod=3;; - Apr) nummonthtod=4;; - May) nummonthtod=5;; - Jun) nummonthtod=6;; - Jul) nummonthtod=7;; - Aug) nummonthtod=8;; - Sep) nummonthtod=9;; - Oct) nummonthtod=10;; - Nov) nummonthtod=11;; - Dec) nummonthtod=12;; - esac - # For the first six month of the year the time notation can also - # be used for files modified in the last year. - if (expr $nummonth \> $nummonthtod) > /dev/null; - then - year=`expr $year - 1` - fi;; - *) year=$3;; -esac - -# The result. -echo $day $month $year diff --git a/scripts/missing b/scripts/missing deleted file mode 100755 index 6a37006e8..000000000 --- a/scripts/missing +++ /dev/null @@ -1,336 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. -# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -run=: - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -case "$1" in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case "$1" in - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch]" - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing 0.4 - GNU automake" - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - - aclocal*) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case "$f" in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is needed, and you do not seem to have it handy on your - system. You might have modified some files without having the - proper tools for further handling them. - You can get \`$1Help2man' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` - test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison|yacc) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if [ ! -f y.tab.h ]; then - echo >y.tab.h - fi - if [ ! -f y.tab.c ]; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex|flex) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if [ ! -f lex.yy.c ]; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` - fi - if [ -f "$file" ]; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit 1 - fi - ;; - - makeinfo) - if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then - # We have makeinfo, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` - fi - touch $file - ;; - - tar) - shift - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - fi - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case "$firstarg" in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case "$firstarg" in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and you do not seem to have it handy on your - system. You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequirements for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 diff --git a/scripts/mkinstalldirs b/scripts/mkinstalldirs deleted file mode 100755 index d2d5f21b6..000000000 --- a/scripts/mkinstalldirs +++ /dev/null @@ -1,111 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman <friedman@prep.ai.mit.edu> -# Created: 1993-05-16 -# Public domain - -errstatus=0 -dirmode="" - -usage="\ -Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." - -# process command line arguments -while test $# -gt 0 ; do - case $1 in - -h | --help | --h*) # -h for help - echo "$usage" 1>&2 - exit 0 - ;; - -m) # -m PERM arg - shift - test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } - dirmode=$1 - shift - ;; - --) # stop option processing - shift - break - ;; - -*) # unknown option - echo "$usage" 1>&2 - exit 1 - ;; - *) # first non-opt arg - break - ;; - esac -done - -for file -do - if test -d "$file"; then - shift - else - break - fi -done - -case $# in - 0) exit 0 ;; -esac - -case $dirmode in - '') - if mkdir -p -- . 2>/dev/null; then - echo "mkdir -p -- $*" - exec mkdir -p -- "$@" - fi - ;; - *) - if mkdir -m "$dirmode" -p -- . 2>/dev/null; then - echo "mkdir -m $dirmode -p -- $*" - exec mkdir -m "$dirmode" -p -- "$@" - fi - ;; -esac - -for file -do - set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` - shift - - pathcomp= - for d - do - pathcomp="$pathcomp$d" - case $pathcomp in - -*) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - else - if test ! -z "$dirmode"; then - echo "chmod $dirmode $pathcomp" - lasterr="" - chmod "$dirmode" "$pathcomp" || lasterr=$? - - if test ! -z "$lasterr"; then - errstatus=$lasterr - fi - fi - fi - fi - - pathcomp="$pathcomp/" - done -done - -exit $errstatus - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# End: -# mkinstalldirs ends here diff --git a/scripts/texinfo.tex b/scripts/texinfo.tex deleted file mode 100644 index e9293f3b9..000000000 --- a/scripts/texinfo.tex +++ /dev/null @@ -1,6773 +0,0 @@ -% texinfo.tex -- TeX macros to handle Texinfo files. -% -% Load plain if necessary, i.e., if running under initex. -\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi -% -\def\texinfoversion{2003-05-04.08} -% -% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, -% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -% -% This texinfo.tex file is free software; you can redistribute it and/or -% modify it under the terms of the GNU General Public License as -% published by the Free Software Foundation; either version 2, or (at -% your option) any later version. -% -% This texinfo.tex file is distributed in the hope that it will be -% useful, but WITHOUT ANY WARRANTY; without even the implied warranty -% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -% General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with this texinfo.tex file; see the file COPYING. If not, write -% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -% Boston, MA 02111-1307, USA. -% -% In other words, you are welcome to use, share and improve this program. -% You are forbidden to forbid anyone else to use, share and improve -% what you give them. Help stamp out software-hoarding! -% -% Please try the latest version of texinfo.tex before submitting bug -% reports; you can get the latest version from: -% ftp://ftp.gnu.org/gnu/texinfo/texinfo.tex -% (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) -% ftp://tug.org/tex/texinfo.tex -% (and all CTAN mirrors, see http://www.ctan.org), -% and /home/gd/gnu/doc/texinfo.tex on the GNU machines. -% -% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. -% -% The texinfo.tex in any given Texinfo distribution could well be out -% of date, so if that's what you're using, please check. -% -% Send bug reports to bug-texinfo@gnu.org. Please include including a -% complete document in each bug report with which we can reproduce the -% problem. Patches are, of course, greatly appreciated. -% -% To process a Texinfo manual with TeX, it's most reliable to use the -% texi2dvi shell script that comes with the distribution. For a simple -% manual foo.texi, however, you can get away with this: -% tex foo.texi -% texindex foo.?? -% tex foo.texi -% tex foo.texi -% dvips foo.dvi -o # or whatever; this makes foo.ps. -% The extra TeX runs get the cross-reference information correct. -% Sometimes one run after texindex suffices, and sometimes you need more -% than two; texi2dvi does it as many times as necessary. -% -% It is possible to adapt texinfo.tex for other languages, to some -% extent. You can get the existing language-specific files from the -% full Texinfo distribution. - -\message{Loading texinfo [version \texinfoversion]:} - -% If in a .fmt file, print the version number -% and turn on active characters that we couldn't do earlier because -% they might have appeared in the input file name. -\everyjob{\message{[Texinfo version \texinfoversion]}% - \catcode`+=\active \catcode`\_=\active} - -\message{Basics,} -\chardef\other=12 - -% We never want plain's \outer definition of \+ in Texinfo. -% For @tex, we can use \tabalign. -\let\+ = \relax - -% Save some plain tex macros whose names we will redefine. -\let\ptexb=\b -\let\ptexbullet=\bullet -\let\ptexc=\c -\let\ptexcomma=\, -\let\ptexdot=\. -\let\ptexdots=\dots -\let\ptexend=\end -\let\ptexequiv=\equiv -\let\ptexexclam=\! -\let\ptexgtr=> -\let\ptexhat=^ -\let\ptexi=\i -\let\ptexindent=\indent -\let\ptexlbrace=\{ -\let\ptexless=< -\let\ptexplus=+ -\let\ptexrbrace=\} -\let\ptexslash=\/ -\let\ptexstar=\* -\let\ptext=\t - -% If this character appears in an error message or help string, it -% starts a new line in the output. -\newlinechar = `^^J - -% Set up fixed words for English if not already set. -\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi -\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi -\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi -\ifx\putwordin\undefined \gdef\putwordin{in}\fi -\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi -\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi -\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi -\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi -\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi -\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi -\ifx\putwordof\undefined \gdef\putwordof{of}\fi -\ifx\putwordon\undefined \gdef\putwordon{on}\fi -\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi -\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi -\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi -\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi -\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi -\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi -\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi -% -\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi -\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi -\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi -\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi -\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi -\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi -\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi -\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi -\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi -\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi -\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi -\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi -% -\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi -\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi -\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi -\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi -\ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi -\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi -\ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi - -% In some macros, we cannot use the `\? notation---the left quote is -% in some cases the escape char. -\chardef\colonChar = `\: -\chardef\commaChar = `\, -\chardef\dotChar = `\. -\chardef\equalChar = `\= -\chardef\exclamChar= `\! -\chardef\questChar = `\? -\chardef\semiChar = `\; -\chardef\spaceChar = `\ % -\chardef\underChar = `\_ - -% Ignore a token. -% -\def\gobble#1{} - -% True if #1 is the empty string, i.e., called like `\ifempty{}'. -% -\def\ifempty#1{\ifemptyx #1\emptymarkA\emptymarkB}% -\def\ifemptyx#1#2\emptymarkB{\ifx #1\emptymarkA}% - -% Hyphenation fixes. -\hyphenation{ap-pen-dix} -\hyphenation{eshell} -\hyphenation{mini-buf-fer mini-buf-fers} -\hyphenation{time-stamp} -\hyphenation{white-space} - -% Margin to add to right of even pages, to left of odd pages. -\newdimen\bindingoffset -\newdimen\normaloffset -\newdimen\pagewidth \newdimen\pageheight - -% Sometimes it is convenient to have everything in the transcript file -% and nothing on the terminal. We don't just call \tracingall here, -% since that produces some useless output on the terminal. We also make -% some effort to order the tracing commands to reduce output in the log -% file; cf. trace.sty in LaTeX. -% -\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% -\def\loggingall{% - \tracingstats2 - \tracingpages1 - \tracinglostchars2 % 2 gives us more in etex - \tracingparagraphs1 - \tracingoutput1 - \tracingmacros2 - \tracingrestores1 - \showboxbreadth\maxdimen \showboxdepth\maxdimen - \ifx\eTeXversion\undefined\else % etex gives us more logging - \tracingscantokens1 - \tracingifs1 - \tracinggroups1 - \tracingnesting2 - \tracingassigns1 - \fi - \tracingcommands3 % 3 gives us more in etex - \errorcontextlines\maxdimen -}% - -% add check for \lastpenalty to plain's definitions. If the last thing -% we did was a \nobreak, we don't want to insert more space. -% -\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount - \removelastskip\penalty-50\smallskip\fi\fi} -\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount - \removelastskip\penalty-100\medskip\fi\fi} -\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount - \removelastskip\penalty-200\bigskip\fi\fi} - -% For @cropmarks command. -% Do @cropmarks to get crop marks. -% -\newif\ifcropmarks -\let\cropmarks = \cropmarkstrue -% -% Dimensions to add cropmarks at corners. -% Added by P. A. MacKay, 12 Nov. 1986 -% -\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines -\newdimen\cornerlong \cornerlong=1pc -\newdimen\cornerthick \cornerthick=.3pt -\newdimen\topandbottommargin \topandbottommargin=.75in - -% Main output routine. -\chardef\PAGE = 255 -\output = {\onepageout{\pagecontents\PAGE}} - -\newbox\headlinebox -\newbox\footlinebox - -% \onepageout takes a vbox as an argument. Note that \pagecontents -% does insertions, but you have to call it yourself. -\def\onepageout#1{% - \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi - % - \ifodd\pageno \advance\hoffset by \bindingoffset - \else \advance\hoffset by -\bindingoffset\fi - % - % Do this outside of the \shipout so @code etc. will be expanded in - % the headline as they should be, not taken literally (outputting ''code). - \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% - \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% - % - {% - % Have to do this stuff outside the \shipout because we want it to - % take effect in \write's, yet the group defined by the \vbox ends - % before the \shipout runs. - % - \escapechar = `\\ % use backslash in output files. - \indexdummies % don't expand commands in the output. - \normalturnoffactive % \ in index entries must not stay \, e.g., if - % the page break happens to be in the middle of an example. - \shipout\vbox{% - % Do this early so pdf references go to the beginning of the page. - \ifpdfmakepagedest \pdfmkdest{\the\pageno} \fi - % - \ifcropmarks \vbox to \outervsize\bgroup - \hsize = \outerhsize - \vskip-\topandbottommargin - \vtop to0pt{% - \line{\ewtop\hfil\ewtop}% - \nointerlineskip - \line{% - \vbox{\moveleft\cornerthick\nstop}% - \hfill - \vbox{\moveright\cornerthick\nstop}% - }% - \vss}% - \vskip\topandbottommargin - \line\bgroup - \hfil % center the page within the outer (page) hsize. - \ifodd\pageno\hskip\bindingoffset\fi - \vbox\bgroup - \fi - % - \unvbox\headlinebox - \pagebody{#1}% - \ifdim\ht\footlinebox > 0pt - % Only leave this space if the footline is nonempty. - % (We lessened \vsize for it in \oddfootingxxx.) - % The \baselineskip=24pt in plain's \makefootline has no effect. - \vskip 2\baselineskip - \unvbox\footlinebox - \fi - % - \ifcropmarks - \egroup % end of \vbox\bgroup - \hfil\egroup % end of (centering) \line\bgroup - \vskip\topandbottommargin plus1fill minus1fill - \boxmaxdepth = \cornerthick - \vbox to0pt{\vss - \line{% - \vbox{\moveleft\cornerthick\nsbot}% - \hfill - \vbox{\moveright\cornerthick\nsbot}% - }% - \nointerlineskip - \line{\ewbot\hfil\ewbot}% - }% - \egroup % \vbox from first cropmarks clause - \fi - }% end of \shipout\vbox - }% end of group with \normalturnoffactive - \advancepageno - \ifnum\outputpenalty>-20000 \else\dosupereject\fi -} - -\newinsert\margin \dimen\margin=\maxdimen - -\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} -{\catcode`\@ =11 -\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi -% marginal hacks, juha@viisa.uucp (Juha Takala) -\ifvoid\margin\else % marginal info is present - \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi -\dimen@=\dp#1 \unvbox#1 -\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi -\ifr@ggedbottom \kern-\dimen@ \vfil \fi} -} - -% Here are the rules for the cropmarks. Note that they are -% offset so that the space between them is truly \outerhsize or \outervsize -% (P. A. MacKay, 12 November, 1986) -% -\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} -\def\nstop{\vbox - {\hrule height\cornerthick depth\cornerlong width\cornerthick}} -\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} -\def\nsbot{\vbox - {\hrule height\cornerlong depth\cornerthick width\cornerthick}} - -% Parse an argument, then pass it to #1. The argument is the rest of -% the input line (except we remove a trailing comment). #1 should be a -% macro which expects an ordinary undelimited TeX argument. -% -\def\parsearg#1{% - \let\next = #1% - \begingroup - \obeylines - \futurelet\temp\parseargx -} - -% If the next token is an obeyed space (from an @example environment or -% the like), remove it and recurse. Otherwise, we're done. -\def\parseargx{% - % \obeyedspace is defined far below, after the definition of \sepspaces. - \ifx\obeyedspace\temp - \expandafter\parseargdiscardspace - \else - \expandafter\parseargline - \fi -} - -% Remove a single space (as the delimiter token to the macro call). -{\obeyspaces % - \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} - -{\obeylines % - \gdef\parseargline#1^^M{% - \endgroup % End of the group started in \parsearg. - % - % First remove any @c comment, then any @comment. - % Result of each macro is put in \toks0. - \argremovec #1\c\relax % - \expandafter\argremovecomment \the\toks0 \comment\relax % - % - % Call the caller's macro, saved as \next in \parsearg. - \expandafter\next\expandafter{\the\toks0}% - }% -} - -% Since all \c{,omment} does is throw away the argument, we can let TeX -% do that for us. The \relax here is matched by the \relax in the call -% in \parseargline; it could be more or less anything, its purpose is -% just to delimit the argument to the \c. -\def\argremovec#1\c#2\relax{\toks0 = {#1}} -\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} - -% \argremovec{,omment} might leave us with trailing spaces, though; e.g., -% @end itemize @c foo -% will have two active spaces as part of the argument with the -% `itemize'. Here we remove all active spaces from #1, and assign the -% result to \toks0. -% -% This loses if there are any *other* active characters besides spaces -% in the argument -- _ ^ +, for example -- since they get expanded. -% Fortunately, Texinfo does not define any such commands. (If it ever -% does, the catcode of the characters in questionwill have to be changed -% here.) But this means we cannot call \removeactivespaces as part of -% \argremovec{,omment}, since @c uses \parsearg, and thus the argument -% that \parsearg gets might well have any character at all in it. -% -\def\removeactivespaces#1{% - \begingroup - \ignoreactivespaces - \edef\temp{#1}% - \global\toks0 = \expandafter{\temp}% - \endgroup -} - -% Change the active space to expand to nothing. -% -\begingroup - \obeyspaces - \gdef\ignoreactivespaces{\obeyspaces\let =\empty} -\endgroup - - -\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} - -%% These are used to keep @begin/@end levels from running away -%% Call \inENV within environments (after a \begingroup) -\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} -\def\ENVcheck{% -\ifENV\errmessage{Still within an environment; press RETURN to continue} -\endgroup\fi} % This is not perfect, but it should reduce lossage - -% @begin foo is the same as @foo, for now. -\newhelp\EMsimple{Press RETURN to continue.} - -\outer\def\begin{\parsearg\beginxxx} - -\def\beginxxx #1{% -\expandafter\ifx\csname #1\endcsname\relax -{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else -\csname #1\endcsname\fi} - -% @end foo executes the definition of \Efoo. -% -\def\end{\parsearg\endxxx} -\def\endxxx #1{% - \removeactivespaces{#1}% - \edef\endthing{\the\toks0}% - % - \expandafter\ifx\csname E\endthing\endcsname\relax - \expandafter\ifx\csname \endthing\endcsname\relax - % There's no \foo, i.e., no ``environment'' foo. - \errhelp = \EMsimple - \errmessage{Undefined command `@end \endthing'}% - \else - \unmatchedenderror\endthing - \fi - \else - % Everything's ok; the right environment has been started. - \csname E\endthing\endcsname - \fi -} - -% There is an environment #1, but it hasn't been started. Give an error. -% -\def\unmatchedenderror#1{% - \errhelp = \EMsimple - \errmessage{This `@end #1' doesn't have a matching `@#1'}% -} - -% Define the control sequence \E#1 to give an unmatched @end error. -% -\def\defineunmatchedend#1{% - \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% -} - - -%% Simple single-character @ commands - -% @@ prints an @ -% Kludge this until the fonts are right (grr). -\def\@{{\tt\char64}} - -% This is turned off because it was never documented -% and you can use @w{...} around a quote to suppress ligatures. -%% Define @` and @' to be the same as ` and ' -%% but suppressing ligatures. -%\def\`{{`}} -%\def\'{{'}} - -% Used to generate quoted braces. -\def\mylbrace {{\tt\char123}} -\def\myrbrace {{\tt\char125}} -\let\{=\mylbrace -\let\}=\myrbrace -\begingroup - % Definitions to produce \{ and \} commands for indices, - % and @{ and @} for the aux file. - \catcode`\{ = \other \catcode`\} = \other - \catcode`\[ = 1 \catcode`\] = 2 - \catcode`\! = 0 \catcode`\\ = \other - !gdef!lbracecmd[\{]% - !gdef!rbracecmd[\}]% - !gdef!lbraceatcmd[@{]% - !gdef!rbraceatcmd[@}]% -!endgroup - -% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent -% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. -\let\, = \c -\let\dotaccent = \. -\def\ringaccent#1{{\accent23 #1}} -\let\tieaccent = \t -\let\ubaraccent = \b -\let\udotaccent = \d - -% Other special characters: @questiondown @exclamdown -% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. -\def\questiondown{?`} -\def\exclamdown{!`} - -% Dotless i and dotless j, used for accents. -\def\imacro{i} -\def\jmacro{j} -\def\dotless#1{% - \def\temp{#1}% - \ifx\temp\imacro \ptexi - \else\ifx\temp\jmacro \j - \else \errmessage{@dotless can be used only with i or j}% - \fi\fi -} - -% Be sure we're in horizontal mode when doing a tie, since we make space -% equivalent to this in @example-like environments. Otherwise, a space -% at the beginning of a line will start with \penalty -- and -% since \penalty is valid in vertical mode, we'd end up putting the -% penalty on the vertical list instead of in the new paragraph. -{\catcode`@ = 11 - % Avoid using \@M directly, because that causes trouble - % if the definition is written into an index file. - \global\let\tiepenalty = \@M - \gdef\tie{\leavevmode\penalty\tiepenalty\ } -} - -% @: forces normal size whitespace following. -\def\:{\spacefactor=1000 } - -% @* forces a line break. -\def\*{\hfil\break\hbox{}\ignorespaces} - -% @/ allows a line break. -\let\/=\allowbreak - -% @. is an end-of-sentence period. -\def\.{.\spacefactor=3000 } - -% @! is an end-of-sentence bang. -\def\!{!\spacefactor=3000 } - -% @? is an end-of-sentence query. -\def\?{?\spacefactor=3000 } - -% @w prevents a word break. Without the \leavevmode, @w at the -% beginning of a paragraph, when TeX is still in vertical mode, would -% produce a whole line of output instead of starting the paragraph. -\def\w#1{\leavevmode\hbox{#1}} - -% @group ... @end group forces ... to be all on one page, by enclosing -% it in a TeX vbox. We use \vtop instead of \vbox to construct the box -% to keep its height that of a normal line. According to the rules for -% \topskip (p.114 of the TeXbook), the glue inserted is -% max (\topskip - \ht (first item), 0). If that height is large, -% therefore, no glue is inserted, and the space between the headline and -% the text is small, which looks bad. -% -% Another complication is that the group might be very large. This can -% cause the glue on the previous page to be unduly stretched, because it -% does not have much material. In this case, it's better to add an -% explicit \vfill so that the extra space is at the bottom. The -% threshold for doing this is if the group is more than \vfilllimit -% percent of a page (\vfilllimit can be changed inside of @tex). -% -\newbox\groupbox -\def\vfilllimit{0.7} -% -\def\group{\begingroup - \ifnum\catcode13=\active \else - \errhelp = \groupinvalidhelp - \errmessage{@group invalid in context where filling is enabled}% - \fi - % - % The \vtop we start below produces a box with normal height and large - % depth; thus, TeX puts \baselineskip glue before it, and (when the - % next line of text is done) \lineskip glue after it. (See p.82 of - % the TeXbook.) Thus, space below is not quite equal to space - % above. But it's pretty close. - \def\Egroup{% - \egroup % End the \vtop. - % \dimen0 is the vertical size of the group's box. - \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox - % \dimen2 is how much space is left on the page (more or less). - \dimen2 = \pageheight \advance\dimen2 by -\pagetotal - % if the group doesn't fit on the current page, and it's a big big - % group, force a page break. - \ifdim \dimen0 > \dimen2 - \ifdim \pagetotal < \vfilllimit\pageheight - \page - \fi - \fi - \copy\groupbox - \endgroup % End the \group. - }% - % - \setbox\groupbox = \vtop\bgroup - % We have to put a strut on the last line in case the @group is in - % the midst of an example, rather than completely enclosing it. - % Otherwise, the interline space between the last line of the group - % and the first line afterwards is too small. But we can't put the - % strut in \Egroup, since there it would be on a line by itself. - % Hence this just inserts a strut at the beginning of each line. - \everypar = {\strut}% - % - % Since we have a strut on every line, we don't need any of TeX's - % normal interline spacing. - \offinterlineskip - % - % OK, but now we have to do something about blank - % lines in the input in @example-like environments, which normally - % just turn into \lisppar, which will insert no space now that we've - % turned off the interline space. Simplest is to make them be an - % empty paragraph. - \ifx\par\lisppar - \edef\par{\leavevmode \par}% - % - % Reset ^^M's definition to new definition of \par. - \obeylines - \fi - % - % Do @comment since we are called inside an environment such as - % @example, where each end-of-line in the input causes an - % end-of-line in the output. We don't want the end-of-line after - % the `@group' to put extra space in the output. Since @group - % should appear on a line by itself (according to the Texinfo - % manual), we don't worry about eating any user text. - \comment -} -% -% TeX puts in an \escapechar (i.e., `@') at the beginning of the help -% message, so this ends up printing `@group can only ...'. -% -\newhelp\groupinvalidhelp{% -group can only be used in environments such as @example,^^J% -where each line of input produces a line of output.} - -% @need space-in-mils -% forces a page break if there is not space-in-mils remaining. - -\newdimen\mil \mil=0.001in - -\def\need{\parsearg\needx} - -% Old definition--didn't work. -%\def\needx #1{\par % -%% This method tries to make TeX break the page naturally -%% if the depth of the box does not fit. -%{\baselineskip=0pt% -%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak -%\prevdepth=-1000pt -%}} - -\def\needx#1{% - % Ensure vertical mode, so we don't make a big box in the middle of a - % paragraph. - \par - % - % If the @need value is less than one line space, it's useless. - \dimen0 = #1\mil - \dimen2 = \ht\strutbox - \advance\dimen2 by \dp\strutbox - \ifdim\dimen0 > \dimen2 - % - % Do a \strut just to make the height of this box be normal, so the - % normal leading is inserted relative to the preceding line. - % And a page break here is fine. - \vtop to #1\mil{\strut\vfil}% - % - % TeX does not even consider page breaks if a penalty added to the - % main vertical list is 10000 or more. But in order to see if the - % empty box we just added fits on the page, we must make it consider - % page breaks. On the other hand, we don't want to actually break the - % page after the empty box. So we use a penalty of 9999. - % - % There is an extremely small chance that TeX will actually break the - % page at this \penalty, if there are no other feasible breakpoints in - % sight. (If the user is using lots of big @group commands, which - % almost-but-not-quite fill up a page, TeX will have a hard time doing - % good page breaking, for example.) However, I could not construct an - % example where a page broke at this \penalty; if it happens in a real - % document, then we can reconsider our strategy. - \penalty9999 - % - % Back up by the size of the box, whether we did a page break or not. - \kern -#1\mil - % - % Do not allow a page break right after this kern. - \nobreak - \fi -} - -% @br forces paragraph break - -\let\br = \par - -% @dots{} output an ellipsis using the current font. -% We do .5em per period so that it has the same spacing in a typewriter -% font as three actual period characters. -% -\def\dots{% - \leavevmode - \hbox to 1.5em{% - \hskip 0pt plus 0.25fil minus 0.25fil - .\hss.\hss.% - \hskip 0pt plus 0.5fil minus 0.5fil - }% -} - -% @enddots{} is an end-of-sentence ellipsis. -% -\def\enddots{% - \leavevmode - \hbox to 2em{% - \hskip 0pt plus 0.25fil minus 0.25fil - .\hss.\hss.\hss.% - \hskip 0pt plus 0.5fil minus 0.5fil - }% - \spacefactor=3000 -} - -% @page forces the start of a new page. -% -\def\page{\par\vfill\supereject} - -% @exdent text.... -% outputs text on separate line in roman font, starting at standard page margin - -% This records the amount of indent in the innermost environment. -% That's how much \exdent should take out. -\newskip\exdentamount - -% This defn is used inside fill environments such as @defun. -\def\exdent{\parsearg\exdentyyy} -\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} - -% This defn is used inside nofill environments such as @example. -\def\nofillexdent{\parsearg\nofillexdentyyy} -\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount -\leftline{\hskip\leftskip{\rm#1}}}} - -% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current -% paragraph. For more general purposes, use the \margin insertion -% class. WHICH is `l' or `r'. -% -\newskip\inmarginspacing \inmarginspacing=1cm -\def\strutdepth{\dp\strutbox} -% -\def\doinmargin#1#2{\strut\vadjust{% - \nobreak - \kern-\strutdepth - \vtop to \strutdepth{% - \baselineskip=\strutdepth - \vss - % if you have multiple lines of stuff to put here, you'll need to - % make the vbox yourself of the appropriate size. - \ifx#1l% - \llap{\ignorespaces #2\hskip\inmarginspacing}% - \else - \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% - \fi - \null - }% -}} -\def\inleftmargin{\doinmargin l} -\def\inrightmargin{\doinmargin r} -% -% @inmargin{TEXT [, RIGHT-TEXT]} -% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; -% else use TEXT for both). -% -\def\inmargin#1{\parseinmargin #1,,\finish} -\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0 > 0pt - \def\lefttext{#1}% have both texts - \def\righttext{#2}% - \else - \def\lefttext{#1}% have only one text - \def\righttext{#1}% - \fi - % - \ifodd\pageno - \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin - \else - \def\temp{\inleftmargin\lefttext}% - \fi - \temp -} - -% @include file insert text of that file as input. -% Allow normal characters that we make active in the argument (a file name). -\def\include{\begingroup - \catcode`\\=\other - \catcode`~=\other - \catcode`^=\other - \catcode`_=\other - \catcode`|=\other - \catcode`<=\other - \catcode`>=\other - \catcode`+=\other - \parsearg\includezzz} -% Restore active chars for included file. -\def\includezzz#1{\endgroup\begingroup - % Read the included file in a group so nested @include's work. - \def\thisfile{#1}% - \let\value=\expandablevalue - \input\thisfile -\endgroup} - -\def\thisfile{} - -% @center line -% outputs that line, centered. -% -\def\center{\parsearg\docenter} -\def\docenter#1{{% - \ifhmode \hfil\break \fi - \advance\hsize by -\leftskip - \advance\hsize by -\rightskip - \line{\hfil \ignorespaces#1\unskip \hfil}% - \ifhmode \break \fi -}} - -% @sp n outputs n lines of vertical space - -\def\sp{\parsearg\spxxx} -\def\spxxx #1{\vskip #1\baselineskip} - -% @comment ...line which is ignored... -% @c is the same as @comment -% @ignore ... @end ignore is another way to write a comment - -\def\comment{\begingroup \catcode`\^^M=\other% -\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% -\commentxxx} -{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} - -\let\c=\comment - -% @paragraphindent NCHARS -% We'll use ems for NCHARS, close enough. -% NCHARS can also be the word `asis' or `none'. -% We cannot feasibly implement @paragraphindent asis, though. -% -\def\asisword{asis} % no translation, these are keywords -\def\noneword{none} -% -\def\paragraphindent{\parsearg\doparagraphindent} -\def\doparagraphindent#1{% - \def\temp{#1}% - \ifx\temp\asisword - \else - \ifx\temp\noneword - \defaultparindent = 0pt - \else - \defaultparindent = #1em - \fi - \fi - \parindent = \defaultparindent -} - -% @exampleindent NCHARS -% We'll use ems for NCHARS like @paragraphindent. -% It seems @exampleindent asis isn't necessary, but -% I preserve it to make it similar to @paragraphindent. -\def\exampleindent{\parsearg\doexampleindent} -\def\doexampleindent#1{% - \def\temp{#1}% - \ifx\temp\asisword - \else - \ifx\temp\noneword - \lispnarrowing = 0pt - \else - \lispnarrowing = #1em - \fi - \fi -} - -% @firstparagraphindent WORD -% If WORD is `none', then suppress indentation of the first paragraph -% after a section heading. If WORD is `insert', then do indentat such -% paragraphs. -% -% The paragraph indentation is suppressed or not by calling -% \suppressfirstparagraphindent, which the sectioning commands do. We -% switch the definition of this back and forth according to WORD. By -% default, we suppress indentation. -% -\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} -\newdimen\currentparindent -% -\def\insertword{insert} -% -\def\firstparagraphindent{\parsearg\dofirstparagraphindent} -\def\dofirstparagraphindent#1{% - \def\temp{#1}% - \ifx\temp\noneword - \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent - \else\ifx\temp\insertword - \let\suppressfirstparagraphindent = \relax - \else - \errhelp = \EMsimple - \errmessage{Unknown @firstparagraphindent option `\temp'}% - \fi\fi -} - -% Here is how we actually suppress indentation. Redefine \everypar to -% \kern backwards by \parindent, and then reset itself to empty. -% -% We also make \indent itself not actually do anything until the next -% paragraph. -% -\gdef\dosuppressfirstparagraphindent{% - \gdef\indent{% - \global\let\indent=\ptexindent - \global\everypar = {}% - }% - \global\everypar = {% - \kern-\parindent - \global\let\indent=\ptexindent - \global\everypar = {}% - }% -}% - - -% @asis just yields its argument. Used with @table, for example. -% -\def\asis#1{#1} - -% @math outputs its argument in math mode. -% We don't use $'s directly in the definition of \math because we need -% to set catcodes according to plain TeX first, to allow for subscripts, -% superscripts, special math chars, etc. -% -\let\implicitmath = $%$ font-lock fix -% -% One complication: _ usually means subscripts, but it could also mean -% an actual _ character, as in @math{@var{some_variable} + 1}. So make -% _ within @math be active (mathcode "8000), and distinguish by seeing -% if the current family is \slfam, which is what @var uses. -% -{\catcode\underChar = \active -\gdef\mathunderscore{% - \catcode\underChar=\active - \def_{\ifnum\fam=\slfam \_\else\sb\fi}% -}} -% -% Another complication: we want \\ (and @\) to output a \ character. -% FYI, plain.tex uses \\ as a temporary control sequence (why?), but -% this is not advertised and we don't care. Texinfo does not -% otherwise define @\. -% -% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. -\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} -% -\def\math{% - \tex - \mathcode`\_="8000 \mathunderscore - \let\\ = \mathbackslash - \mathactive - \implicitmath\finishmath} -\def\finishmath#1{#1\implicitmath\Etex} - -% Some active characters (such as <) are spaced differently in math. -% We have to reset their definitions in case the @math was an -% argument to a command which set the catcodes (such as @item or @section). -% -{ - \catcode`^ = \active - \catcode`< = \active - \catcode`> = \active - \catcode`+ = \active - \gdef\mathactive{% - \let^ = \ptexhat - \let< = \ptexless - \let> = \ptexgtr - \let+ = \ptexplus - } -} - -% @bullet and @minus need the same treatment as @math, just above. -\def\bullet{\implicitmath\ptexbullet\implicitmath} -\def\minus{\implicitmath-\implicitmath} - -% @refill is a no-op. -\let\refill=\relax - -% If working on a large document in chapters, it is convenient to -% be able to disable indexing, cross-referencing, and contents, for test runs. -% This is done with @novalidate (before @setfilename). -% -\newif\iflinks \linkstrue % by default we want the aux files. -\let\novalidate = \linksfalse - -% @setfilename is done at the beginning of every texinfo file. -% So open here the files we need to have open while reading the input. -% This makes it possible to make a .fmt file for texinfo. -\def\setfilename{% - \iflinks - \readauxfile - \fi % \openindices needs to do some work in any case. - \openindices - \fixbackslash % Turn off hack to swallow `\input texinfo'. - \global\let\setfilename=\comment % Ignore extra @setfilename cmds. - % - % If texinfo.cnf is present on the system, read it. - % Useful for site-wide @afourpaper, etc. - % Just to be on the safe side, close the input stream before the \input. - \openin 1 texinfo.cnf - \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi - \closein1 - \temp - % - \comment % Ignore the actual filename. -} - -% Called from \setfilename. -% -\def\openindices{% - \newindex{cp}% - \newcodeindex{fn}% - \newcodeindex{vr}% - \newcodeindex{tp}% - \newcodeindex{ky}% - \newcodeindex{pg}% -} - -% @bye. -\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} - - -\message{pdf,} -% adobe `portable' document format -\newcount\tempnum -\newcount\lnkcount -\newtoks\filename -\newcount\filenamelength -\newcount\pgn -\newtoks\toksA -\newtoks\toksB -\newtoks\toksC -\newtoks\toksD -\newbox\boxA -\newcount\countA -\newif\ifpdf -\newif\ifpdfmakepagedest - -\ifx\pdfoutput\undefined - \pdffalse - \let\pdfmkdest = \gobble - \let\pdfurl = \gobble - \let\endlink = \relax - \let\linkcolor = \relax - \let\pdfmakeoutlines = \relax -\else - \pdftrue - \pdfoutput = 1 - \input pdfcolor - \def\dopdfimage#1#2#3{% - \def\imagewidth{#2}% - \def\imageheight{#3}% - % without \immediate, pdftex seg faults when the same image is - % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) - \ifnum\pdftexversion < 14 - \immediate\pdfimage - \else - \immediate\pdfximage - \fi - \ifx\empty\imagewidth\else width \imagewidth \fi - \ifx\empty\imageheight\else height \imageheight \fi - \ifnum\pdftexversion<13 - #1.pdf% - \else - {#1.pdf}% - \fi - \ifnum\pdftexversion < 14 \else - \pdfrefximage \pdflastximage - \fi} - \def\pdfmkdest#1{{\normalturnoffactive \pdfdest name{#1} xyz}} - \def\pdfmkpgn#1{#1} - \let\linkcolor = \Blue % was Cyan, but that seems light? - \def\endlink{\Black\pdfendlink} - % Adding outlines to PDF; macros for calculating structure of outlines - % come from Petr Olsak - \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% - \else \csname#1\endcsname \fi} - \def\advancenumber#1{\tempnum=\expnumber{#1}\relax - \advance\tempnum by1 - \expandafter\xdef\csname#1\endcsname{\the\tempnum}} - \def\pdfmakeoutlines{{% - \openin 1 \jobname.toc - \ifeof 1\else\begingroup - \closein 1 - % Thanh's hack / proper braces in bookmarks - \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace - \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace - % - \def\chapentry ##1##2##3{} - \def\secentry ##1##2##3##4{\advancenumber{chap##2}} - \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}} - \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}} - \let\appendixentry = \chapentry - \let\unnumbchapentry = \chapentry - \let\unnumbsecentry = \secentry - \let\unnumbsubsecentry = \subsecentry - \let\unnumbsubsubsecentry = \subsubsecentry - \input \jobname.toc - \def\chapentry ##1##2##3{% - \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}} - \def\secentry ##1##2##3##4{% - \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}} - \def\subsecentry ##1##2##3##4##5{% - \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}} - \def\subsubsecentry ##1##2##3##4##5##6{% - \pdfoutline goto name{\pdfmkpgn{##6}}{##1}} - \let\appendixentry = \chapentry - \let\unnumbchapentry = \chapentry - \let\unnumbsecentry = \secentry - \let\unnumbsubsecentry = \subsecentry - \let\unnumbsubsubsecentry = \subsubsecentry - % - % Make special characters normal for writing to the pdf file. - % - \indexnofonts - \let\tt=\relax - \turnoffactive - \input \jobname.toc - \endgroup\fi - }} - \def\makelinks #1,{% - \def\params{#1}\def\E{END}% - \ifx\params\E - \let\nextmakelinks=\relax - \else - \let\nextmakelinks=\makelinks - \ifnum\lnkcount>0,\fi - \picknum{#1}% - \startlink attr{/Border [0 0 0]} - goto name{\pdfmkpgn{\the\pgn}}% - \linkcolor #1% - \advance\lnkcount by 1% - \endlink - \fi - \nextmakelinks - } - \def\picknum#1{\expandafter\pn#1} - \def\pn#1{% - \def\p{#1}% - \ifx\p\lbrace - \let\nextpn=\ppn - \else - \let\nextpn=\ppnn - \def\first{#1} - \fi - \nextpn - } - \def\ppn#1{\pgn=#1\gobble} - \def\ppnn{\pgn=\first} - \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} - \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} - \def\skipspaces#1{\def\PP{#1}\def\D{|}% - \ifx\PP\D\let\nextsp\relax - \else\let\nextsp\skipspaces - \ifx\p\space\else\addtokens{\filename}{\PP}% - \advance\filenamelength by 1 - \fi - \fi - \nextsp} - \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} - \ifnum\pdftexversion < 14 - \let \startlink \pdfannotlink - \else - \let \startlink \pdfstartlink - \fi - \def\pdfurl#1{% - \begingroup - \normalturnoffactive\def\@{@}% - \let\value=\expandablevalue - \leavevmode\Red - \startlink attr{/Border [0 0 0]}% - user{/Subtype /Link /A << /S /URI /URI (#1) >>}% - % #1 - \endgroup} - \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} - \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} - \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} - \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} - \def\maketoks{% - \expandafter\poptoks\the\toksA|ENDTOKS| - \ifx\first0\adn0 - \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 - \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 - \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 - \else - \ifnum0=\countA\else\makelink\fi - \ifx\first.\let\next=\done\else - \let\next=\maketoks - \addtokens{\toksB}{\the\toksD} - \ifx\first,\addtokens{\toksB}{\space}\fi - \fi - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi - \next} - \def\makelink{\addtokens{\toksB}% - {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} - \def\pdflink#1{% - \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} - \linkcolor #1\endlink} - \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} -\fi % \ifx\pdfoutput - - -\message{fonts,} -% Font-change commands. - -% Texinfo sort of supports the sans serif font style, which plain TeX does not. -% So we set up a \sf analogous to plain's \rm, etc. -\newfam\sffam -\def\sf{\fam=\sffam \tensf} -\let\li = \sf % Sometimes we call it \li, not \sf. - -% We don't need math for this one. -\def\ttsl{\tenttsl} - -% Default leading. -\newdimen\textleading \textleading = 13.2pt - -% Set the baselineskip to #1, and the lineskip and strut size -% correspondingly. There is no deep meaning behind these magic numbers -% used as factors; they just match (closely enough) what Knuth defined. -% -\def\lineskipfactor{.08333} -\def\strutheightpercent{.70833} -\def\strutdepthpercent {.29167} -% -\def\setleading#1{% - \normalbaselineskip = #1\relax - \normallineskip = \lineskipfactor\normalbaselineskip - \normalbaselines - \setbox\strutbox =\hbox{% - \vrule width0pt height\strutheightpercent\baselineskip - depth \strutdepthpercent \baselineskip - }% -} - -% Set the font macro #1 to the font named #2, adding on the -% specified font prefix (normally `cm'). -% #3 is the font's design size, #4 is a scale factor -\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} - -% Use cm as the default font prefix. -% To specify the font prefix, you must define \fontprefix -% before you read in texinfo.tex. -\ifx\fontprefix\undefined -\def\fontprefix{cm} -\fi -% Support font families that don't use the same naming scheme as CM. -\def\rmshape{r} -\def\rmbshape{bx} %where the normal face is bold -\def\bfshape{b} -\def\bxshape{bx} -\def\ttshape{tt} -\def\ttbshape{tt} -\def\ttslshape{sltt} -\def\itshape{ti} -\def\itbshape{bxti} -\def\slshape{sl} -\def\slbshape{bxsl} -\def\sfshape{ss} -\def\sfbshape{ss} -\def\scshape{csc} -\def\scbshape{csc} - -\newcount\mainmagstep -\ifx\bigger\relax - % not really supported. - \mainmagstep=\magstep1 - \setfont\textrm\rmshape{12}{1000} - \setfont\texttt\ttshape{12}{1000} -\else - \mainmagstep=\magstephalf - \setfont\textrm\rmshape{10}{\mainmagstep} - \setfont\texttt\ttshape{10}{\mainmagstep} -\fi -% Instead of cmb10, you may want to use cmbx10. -% cmbx10 is a prettier font on its own, but cmb10 -% looks better when embedded in a line with cmr10 -% (in Bob's opinion). -\setfont\textbf\bfshape{10}{\mainmagstep} -\setfont\textit\itshape{10}{\mainmagstep} -\setfont\textsl\slshape{10}{\mainmagstep} -\setfont\textsf\sfshape{10}{\mainmagstep} -\setfont\textsc\scshape{10}{\mainmagstep} -\setfont\textttsl\ttslshape{10}{\mainmagstep} -\font\texti=cmmi10 scaled \mainmagstep -\font\textsy=cmsy10 scaled \mainmagstep - -% A few fonts for @defun, etc. -\setfont\defbf\bxshape{10}{\magstep1} %was 1314 -\setfont\deftt\ttshape{10}{\magstep1} -\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} - -% Fonts for indices, footnotes, small examples (9pt). -\setfont\smallrm\rmshape{9}{1000} -\setfont\smalltt\ttshape{9}{1000} -\setfont\smallbf\bfshape{10}{900} -\setfont\smallit\itshape{9}{1000} -\setfont\smallsl\slshape{9}{1000} -\setfont\smallsf\sfshape{9}{1000} -\setfont\smallsc\scshape{10}{900} -\setfont\smallttsl\ttslshape{10}{900} -\font\smalli=cmmi9 -\font\smallsy=cmsy9 - -% Fonts for small examples (8pt). -\setfont\smallerrm\rmshape{8}{1000} -\setfont\smallertt\ttshape{8}{1000} -\setfont\smallerbf\bfshape{10}{800} -\setfont\smallerit\itshape{8}{1000} -\setfont\smallersl\slshape{8}{1000} -\setfont\smallersf\sfshape{8}{1000} -\setfont\smallersc\scshape{10}{800} -\setfont\smallerttsl\ttslshape{10}{800} -\font\smalleri=cmmi8 -\font\smallersy=cmsy8 - -% Fonts for title page: -\setfont\titlerm\rmbshape{12}{\magstep3} -\setfont\titleit\itbshape{10}{\magstep4} -\setfont\titlesl\slbshape{10}{\magstep4} -\setfont\titlett\ttbshape{12}{\magstep3} -\setfont\titlettsl\ttslshape{10}{\magstep4} -\setfont\titlesf\sfbshape{17}{\magstep1} -\let\titlebf=\titlerm -\setfont\titlesc\scbshape{10}{\magstep4} -\font\titlei=cmmi12 scaled \magstep3 -\font\titlesy=cmsy10 scaled \magstep4 -\def\authorrm{\secrm} -\def\authortt{\sectt} - -% Chapter (and unnumbered) fonts (17.28pt). -\setfont\chaprm\rmbshape{12}{\magstep2} -\setfont\chapit\itbshape{10}{\magstep3} -\setfont\chapsl\slbshape{10}{\magstep3} -\setfont\chaptt\ttbshape{12}{\magstep2} -\setfont\chapttsl\ttslshape{10}{\magstep3} -\setfont\chapsf\sfbshape{17}{1000} -\let\chapbf=\chaprm -\setfont\chapsc\scbshape{10}{\magstep3} -\font\chapi=cmmi12 scaled \magstep2 -\font\chapsy=cmsy10 scaled \magstep3 - -% Section fonts (14.4pt). -\setfont\secrm\rmbshape{12}{\magstep1} -\setfont\secit\itbshape{10}{\magstep2} -\setfont\secsl\slbshape{10}{\magstep2} -\setfont\sectt\ttbshape{12}{\magstep1} -\setfont\secttsl\ttslshape{10}{\magstep2} -\setfont\secsf\sfbshape{12}{\magstep1} -\let\secbf\secrm -\setfont\secsc\scbshape{10}{\magstep2} -\font\seci=cmmi12 scaled \magstep1 -\font\secsy=cmsy10 scaled \magstep2 - -% Subsection fonts (13.15pt). -\setfont\ssecrm\rmbshape{12}{\magstephalf} -\setfont\ssecit\itbshape{10}{1315} -\setfont\ssecsl\slbshape{10}{1315} -\setfont\ssectt\ttbshape{12}{\magstephalf} -\setfont\ssecttsl\ttslshape{10}{1315} -\setfont\ssecsf\sfbshape{12}{\magstephalf} -\let\ssecbf\ssecrm -\setfont\ssecsc\scbshape{10}{\magstep1} -\font\sseci=cmmi12 scaled \magstephalf -\font\ssecsy=cmsy10 scaled 1315 -% The smallcaps and symbol fonts should actually be scaled \magstep1.5, -% but that is not a standard magnification. - -% In order for the font changes to affect most math symbols and letters, -% we have to define the \textfont of the standard families. Since -% texinfo doesn't allow for producing subscripts and superscripts except -% in the main text, we don't bother to reset \scriptfont and -% \scriptscriptfont (which would also require loading a lot more fonts). -% -\def\resetmathfonts{% - \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy - \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf - \textfont\ttfam=\tentt \textfont\sffam=\tensf -} - -% The font-changing commands redefine the meanings of \tenSTYLE, instead -% of just \STYLE. We do this so that font changes will continue to work -% in math mode, where it is the current \fam that is relevant in most -% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam -% \tenbf}, for example. By redefining \tenbf, we obviate the need to -% redefine \bf itself. -\def\textfonts{% - \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl - \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc - \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl - \resetmathfonts \setleading{\textleading}} -\def\titlefonts{% - \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl - \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc - \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy - \let\tenttsl=\titlettsl - \resetmathfonts \setleading{25pt}} -\def\titlefont#1{{\titlefonts\rm #1}} -\def\chapfonts{% - \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl - \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc - \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl - \resetmathfonts \setleading{19pt}} -\def\secfonts{% - \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl - \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc - \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl - \resetmathfonts \setleading{16pt}} -\def\subsecfonts{% - \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl - \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc - \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl - \resetmathfonts \setleading{15pt}} -\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? -\def\smallfonts{% - \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl - \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc - \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy - \let\tenttsl=\smallttsl - \resetmathfonts \setleading{10.5pt}} -\def\smallerfonts{% - \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl - \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc - \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy - \let\tenttsl=\smallerttsl - \resetmathfonts \setleading{9.5pt}} - -% Set the fonts to use with the @small... environments. -\let\smallexamplefonts = \smallfonts - -% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample -% can fit this many characters: -% 8.5x11=86 smallbook=72 a4=90 a5=69 -% If we use \smallerfonts (8pt), then we can fit this many characters: -% 8.5x11=90+ smallbook=80 a4=90+ a5=77 -% For me, subjectively, the few extra characters that fit aren't worth -% the additional smallness of 8pt. So I'm making the default 9pt. -% -% By the way, for comparison, here's what fits with @example (10pt): -% 8.5x11=71 smallbook=60 a4=75 a5=58 -% -% I wish we used A4 paper on this side of the Atlantic. -% -% --karl, 24jan03. - - -% Set up the default fonts, so we can use them for creating boxes. -% -\textfonts - -% Define these so they can be easily changed for other fonts. -\def\angleleft{$\langle$} -\def\angleright{$\rangle$} - -% Count depth in font-changes, for error checks -\newcount\fontdepth \fontdepth=0 - -% Fonts for short table of contents. -\setfont\shortcontrm\rmshape{12}{1000} -\setfont\shortcontbf\bxshape{12}{1000} -\setfont\shortcontsl\slshape{12}{1000} -\setfont\shortconttt\ttshape{12}{1000} - -%% Add scribe-like font environments, plus @l for inline lisp (usually sans -%% serif) and @ii for TeX italic - -% \smartitalic{ARG} outputs arg in italics, followed by an italic correction -% unless the following character is such as not to need one. -\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else - \ptexslash\fi\fi\fi} -\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} -\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} - -\let\i=\smartitalic -\let\var=\smartslanted -\let\dfn=\smartslanted -\let\emph=\smartitalic -\let\cite=\smartslanted - -\def\b#1{{\bf #1}} -\let\strong=\b - -% We can't just use \exhyphenpenalty, because that only has effect at -% the end of a paragraph. Restore normal hyphenation at the end of the -% group within which \nohyphenation is presumably called. -% -\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} -\def\restorehyphenation{\hyphenchar\font = `- } - -% Set sfcode to normal for the chars that usually have another value. -% Can't use plain's \frenchspacing because it uses the `\x notation, and -% sometimes \x has an active definition that messes things up. -% -\catcode`@=11 - \def\frenchspacing{% - \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m - \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m - } -\catcode`@=\other - -\def\t#1{% - {\tt \rawbackslash \frenchspacing #1}% - \null -} -\let\ttfont=\t -\def\samp#1{`\tclose{#1}'\null} -\setfont\keyrm\rmshape{8}{1000} -\font\keysy=cmsy9 -\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% - \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% - \vbox{\hrule\kern-0.4pt - \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% - \kern-0.4pt\hrule}% - \kern-.06em\raise0.4pt\hbox{\angleright}}}} -% The old definition, with no lozenge: -%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} -\def\ctrl #1{{\tt \rawbackslash \hat}#1} - -% @file, @option are the same as @samp. -\let\file=\samp -\let\option=\samp - -% @code is a modification of @t, -% which makes spaces the same size as normal in the surrounding text. -\def\tclose#1{% - {% - % Change normal interword space to be same as for the current font. - \spaceskip = \fontdimen2\font - % - % Switch to typewriter. - \tt - % - % But `\ ' produces the large typewriter interword space. - \def\ {{\spaceskip = 0pt{} }}% - % - % Turn off hyphenation. - \nohyphenation - % - \rawbackslash - \frenchspacing - #1% - }% - \null -} - -% We *must* turn on hyphenation at `-' and `_' in \code. -% Otherwise, it is too hard to avoid overfull hboxes -% in the Emacs manual, the Library manual, etc. - -% Unfortunately, TeX uses one parameter (\hyphenchar) to control -% both hyphenation at - and hyphenation within words. -% We must therefore turn them both off (\tclose does that) -% and arrange explicitly to hyphenate at a dash. -% -- rms. -{ - \catcode`\-=\active - \catcode`\_=\active - % - \global\def\code{\begingroup - \catcode`\-=\active \let-\codedash - \catcode`\_=\active \let_\codeunder - \codex - } - % - % If we end up with any active - characters when handling the index, - % just treat them as a normal -. - \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} -} - -\def\realdash{-} -\def\codedash{-\discretionary{}{}{}} -\def\codeunder{% - % this is all so @math{@code{var_name}+1} can work. In math mode, _ - % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) - % will therefore expand the active definition of _, which is us - % (inside @code that is), therefore an endless loop. - \ifusingtt{\ifmmode - \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. - \else\normalunderscore \fi - \discretionary{}{}{}}% - {\_}% -} -\def\codex #1{\tclose{#1}\endgroup} - -% @kbd is like @code, except that if the argument is just one @key command, -% then @kbd has no effect. - -% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), -% `example' (@kbd uses ttsl only inside of @example and friends), -% or `code' (@kbd uses normal tty font always). -\def\kbdinputstyle{\parsearg\kbdinputstylexxx} -\def\kbdinputstylexxx#1{% - \def\arg{#1}% - \ifx\arg\worddistinct - \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% - \else\ifx\arg\wordexample - \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% - \else\ifx\arg\wordcode - \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% - \else - \errhelp = \EMsimple - \errmessage{Unknown @kbdinputstyle option `\arg'}% - \fi\fi\fi -} -\def\worddistinct{distinct} -\def\wordexample{example} -\def\wordcode{code} - -% Default is `distinct.' -\kbdinputstyle distinct - -\def\xkey{\key} -\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% -\ifx\one\xkey\ifx\threex\three \key{#2}% -\else{\tclose{\kbdfont\look}}\fi -\else{\tclose{\kbdfont\look}}\fi} - -% For @url, @env, @command quotes seem unnecessary, so use \code. -\let\url=\code -\let\env=\code -\let\command=\code - -% @uref (abbreviation for `urlref') takes an optional (comma-separated) -% second argument specifying the text to display and an optional third -% arg as text to display instead of (rather than in addition to) the url -% itself. First (mandatory) arg is the url. Perhaps eventually put in -% a hypertex \special here. -% -\def\uref#1{\douref #1,,,\finish} -\def\douref#1,#2,#3,#4\finish{\begingroup - \unsepspaces - \pdfurl{#1}% - \setbox0 = \hbox{\ignorespaces #3}% - \ifdim\wd0 > 0pt - \unhbox0 % third arg given, show only that - \else - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0 > 0pt - \ifpdf - \unhbox0 % PDF: 2nd arg given, show only it - \else - \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url - \fi - \else - \code{#1}% only url given, so show it - \fi - \fi - \endlink -\endgroup} - -% rms does not like angle brackets --karl, 17may97. -% So now @email is just like @uref, unless we are pdf. -% -%\def\email#1{\angleleft{\tt #1}\angleright} -\ifpdf - \def\email#1{\doemail#1,,\finish} - \def\doemail#1,#2,#3\finish{\begingroup - \unsepspaces - \pdfurl{mailto:#1}% - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi - \endlink - \endgroup} -\else - \let\email=\uref -\fi - -% Check if we are currently using a typewriter font. Since all the -% Computer Modern typewriter fonts have zero interword stretch (and -% shrink), and it is reasonable to expect all typewriter fonts to have -% this property, we can check that font parameter. -% -\def\ifmonospace{\ifdim\fontdimen3\font=0pt } - -% Typeset a dimension, e.g., `in' or `pt'. The only reason for the -% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. -% -\def\dmn#1{\thinspace #1} - -\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} - -% @l was never documented to mean ``switch to the Lisp font'', -% and it is not used as such in any manual I can find. We need it for -% Polish suppressed-l. --karl, 22sep96. -%\def\l#1{{\li #1}\null} - -% Explicit font changes: @r, @sc, undocumented @ii. -\def\r#1{{\rm #1}} % roman font -\def\sc#1{{\smallcaps#1}} % smallcaps font -\def\ii#1{{\it #1}} % italic font - -% @acronym downcases the argument and prints in smallcaps. -\def\acronym#1{{\smallcaps \lowercase{#1}}} - -% @pounds{} is a sterling sign. -\def\pounds{{\it\$}} - -% @registeredsymbol - R in a circle. For now, only works in text size; -% we'd have to redo the font mechanism to change the \scriptstyle and -% \scriptscriptstyle font sizes to make it look right in headings. -% Adapted from the plain.tex definition of \copyright. -% -\def\registeredsymbol{% - $^{{\ooalign{\hfil\raise.07ex\hbox{$\scriptstyle\rm R$}\hfil\crcr\Orb}}% - }$% -} - - -\message{page headings,} - -\newskip\titlepagetopglue \titlepagetopglue = 1.5in -\newskip\titlepagebottomglue \titlepagebottomglue = 2pc - -% First the title page. Must do @settitle before @titlepage. -\newif\ifseenauthor -\newif\iffinishedtitlepage - -% Do an implicit @contents or @shortcontents after @end titlepage if the -% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. -% -\newif\ifsetcontentsaftertitlepage - \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue -\newif\ifsetshortcontentsaftertitlepage - \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue - -\def\shorttitlepage{\parsearg\shorttitlepagezzz} -\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% - \endgroup\page\hbox{}\page} - -\def\titlepage{\begingroup \parindent=0pt \textfonts - \let\subtitlerm=\tenrm - \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% - % - \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines - \let\tt=\authortt}% - % - % Leave some space at the very top of the page. - \vglue\titlepagetopglue - % - % Now you can print the title using @title. - \def\title{\parsearg\titlezzz}% - \def\titlezzz##1{\leftline{\titlefonts\rm ##1} - % print a rule at the page bottom also. - \finishedtitlepagefalse - \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% - % No rule at page bottom unless we print one at the top with @title. - \finishedtitlepagetrue - % - % Now you can put text using @subtitle. - \def\subtitle{\parsearg\subtitlezzz}% - \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% - % - % @author should come last, but may come many times. - \def\author{\parsearg\authorzzz}% - \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi - {\authorfont \leftline{##1}}}% - % - % Most title ``pages'' are actually two pages long, with space - % at the top of the second. We don't want the ragged left on the second. - \let\oldpage = \page - \def\page{% - \iffinishedtitlepage\else - \finishtitlepage - \fi - \oldpage - \let\page = \oldpage - \hbox{}}% -% \def\page{\oldpage \hbox{}} -} - -\def\Etitlepage{% - \iffinishedtitlepage\else - \finishtitlepage - \fi - % It is important to do the page break before ending the group, - % because the headline and footline are only empty inside the group. - % If we use the new definition of \page, we always get a blank page - % after the title page, which we certainly don't want. - \oldpage - \endgroup - % - % Need this before the \...aftertitlepage checks so that if they are - % in effect the toc pages will come out with page numbers. - \HEADINGSon - % - % If they want short, they certainly want long too. - \ifsetshortcontentsaftertitlepage - \shortcontents - \contents - \global\let\shortcontents = \relax - \global\let\contents = \relax - \fi - % - \ifsetcontentsaftertitlepage - \contents - \global\let\contents = \relax - \global\let\shortcontents = \relax - \fi -} - -\def\finishtitlepage{% - \vskip4pt \hrule height 2pt width \hsize - \vskip\titlepagebottomglue - \finishedtitlepagetrue -} - -%%% Set up page headings and footings. - -\let\thispage=\folio - -\newtoks\evenheadline % headline on even pages -\newtoks\oddheadline % headline on odd pages -\newtoks\evenfootline % footline on even pages -\newtoks\oddfootline % footline on odd pages - -% Now make Tex use those variables -\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline - \else \the\evenheadline \fi}} -\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline - \else \the\evenfootline \fi}\HEADINGShook} -\let\HEADINGShook=\relax - -% Commands to set those variables. -% For example, this is what @headings on does -% @evenheading @thistitle|@thispage|@thischapter -% @oddheading @thischapter|@thispage|@thistitle -% @evenfooting @thisfile|| -% @oddfooting ||@thisfile - -\def\evenheading{\parsearg\evenheadingxxx} -\def\oddheading{\parsearg\oddheadingxxx} -\def\everyheading{\parsearg\everyheadingxxx} - -\def\evenfooting{\parsearg\evenfootingxxx} -\def\oddfooting{\parsearg\oddfootingxxx} -\def\everyfooting{\parsearg\everyfootingxxx} - -{\catcode`\@=0 % - -\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} -\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% -\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} - -\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} -\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% -\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} - -\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% - -\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} -\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% -\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} - -\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} -\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% - \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% - % - % Leave some space for the footline. Hopefully ok to assume - % @evenfooting will not be used by itself. - \global\advance\pageheight by -\baselineskip - \global\advance\vsize by -\baselineskip -} - -\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} -% -}% unbind the catcode of @. - -% @headings double turns headings on for double-sided printing. -% @headings single turns headings on for single-sided printing. -% @headings off turns them off. -% @headings on same as @headings double, retained for compatibility. -% @headings after turns on double-sided headings after this page. -% @headings doubleafter turns on double-sided headings after this page. -% @headings singleafter turns on single-sided headings after this page. -% By default, they are off at the start of a document, -% and turned `on' after @end titlepage. - -\def\headings #1 {\csname HEADINGS#1\endcsname} - -\def\HEADINGSoff{ -\global\evenheadline={\hfil} \global\evenfootline={\hfil} -\global\oddheadline={\hfil} \global\oddfootline={\hfil}} -\HEADINGSoff -% When we turn headings on, set the page number to 1. -% For double-sided printing, put current file name in lower left corner, -% chapter name on inside top of right hand pages, document -% title on inside top of left hand pages, and page numbers on outside top -% edge of all pages. -\def\HEADINGSdouble{ -\global\pageno=1 -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chapoddpage -} -\let\contentsalignmacro = \chappager - -% For single-sided printing, chapter title goes across top left of page, -% page number on top right. -\def\HEADINGSsingle{ -\global\pageno=1 -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapter\hfil\folio}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chappager -} -\def\HEADINGSon{\HEADINGSdouble} - -\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} -\let\HEADINGSdoubleafter=\HEADINGSafter -\def\HEADINGSdoublex{% -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chapoddpage -} - -\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} -\def\HEADINGSsinglex{% -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapter\hfil\folio}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chappager -} - -% Subroutines used in generating headings -% This produces Day Month Year style of output. -% Only define if not already defined, in case a txi-??.tex file has set -% up a different format (e.g., txi-cs.tex does this). -\ifx\today\undefined -\def\today{% - \number\day\space - \ifcase\month - \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr - \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug - \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec - \fi - \space\number\year} -\fi - -% @settitle line... specifies the title of the document, for headings. -% It generates no output of its own. -\def\thistitle{\putwordNoTitle} -\def\settitle{\parsearg\settitlezzz} -\def\settitlezzz #1{\gdef\thistitle{#1}} - - -\message{tables,} -% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). - -% default indentation of table text -\newdimen\tableindent \tableindent=.8in -% default indentation of @itemize and @enumerate text -\newdimen\itemindent \itemindent=.3in -% margin between end of table item and start of table text. -\newdimen\itemmargin \itemmargin=.1in - -% used internally for \itemindent minus \itemmargin -\newdimen\itemmax - -% Note @table, @vtable, and @vtable define @item, @itemx, etc., with -% these defs. -% They also define \itemindex -% to index the item name in whatever manner is desired (perhaps none). - -\newif\ifitemxneedsnegativevskip - -\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} - -\def\internalBitem{\smallbreak \parsearg\itemzzz} -\def\internalBitemx{\itemxpar \parsearg\itemzzz} - -\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} -\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} - -\def\internalBkitem{\smallbreak \parsearg\kitemzzz} -\def\internalBkitemx{\itemxpar \parsearg\kitemzzz} - -\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% - \itemzzz {#1}} - -\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% - \itemzzz {#1}} - -\def\itemzzz #1{\begingroup % - \advance\hsize by -\rightskip - \advance\hsize by -\tableindent - \setbox0=\hbox{\itemfont{#1}}% - \itemindex{#1}% - \nobreak % This prevents a break before @itemx. - % - % If the item text does not fit in the space we have, put it on a line - % by itself, and do not allow a page break either before or after that - % line. We do not start a paragraph here because then if the next - % command is, e.g., @kindex, the whatsit would get put into the - % horizontal list on a line by itself, resulting in extra blank space. - \ifdim \wd0>\itemmax - % - % Make this a paragraph so we get the \parskip glue and wrapping, - % but leave it ragged-right. - \begingroup - \advance\leftskip by-\tableindent - \advance\hsize by\tableindent - \advance\rightskip by0pt plus1fil - \leavevmode\unhbox0\par - \endgroup - % - % We're going to be starting a paragraph, but we don't want the - % \parskip glue -- logically it's part of the @item we just started. - \nobreak \vskip-\parskip - % - % Stop a page break at the \parskip glue coming up. (Unfortunately - % we can't prevent a possible page break at the following - % \baselineskip glue.) However, if what follows is an environment - % such as @example, there will be no \parskip glue; then - % the negative vskip we just would cause the example and the item to - % crash together. So we use this bizarre value of 10001 as a signal - % to \aboveenvbreak to insert \parskip glue after all. - % (Possibly there are other commands that could be followed by - % @example which need the same treatment, but not section titles; or - % maybe section titles are the only special case and they should be - % penalty 10001...) - \penalty 10001 - \endgroup - \itemxneedsnegativevskipfalse - \else - % The item text fits into the space. Start a paragraph, so that the - % following text (if any) will end up on the same line. - \noindent - % Do this with kerns and \unhbox so that if there is a footnote in - % the item text, it can migrate to the main vertical list and - % eventually be printed. - \nobreak\kern-\tableindent - \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 - \unhbox0 - \nobreak\kern\dimen0 - \endgroup - \itemxneedsnegativevskiptrue - \fi -} - -\def\item{\errmessage{@item while not in a table}} -\def\itemx{\errmessage{@itemx while not in a table}} -\def\kitem{\errmessage{@kitem while not in a table}} -\def\kitemx{\errmessage{@kitemx while not in a table}} -\def\xitem{\errmessage{@xitem while not in a table}} -\def\xitemx{\errmessage{@xitemx while not in a table}} - -% Contains a kludge to get @end[description] to work. -\def\description{\tablez{\dontindex}{1}{}{}{}{}} - -% @table, @ftable, @vtable. -\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} -{\obeylines\obeyspaces% -\gdef\tablex #1^^M{% -\tabley\dontindex#1 \endtabley}} - -\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} -{\obeylines\obeyspaces% -\gdef\ftablex #1^^M{% -\tabley\fnitemindex#1 \endtabley -\def\Eftable{\endgraf\afterenvbreak\endgroup}% -\let\Etable=\relax}} - -\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} -{\obeylines\obeyspaces% -\gdef\vtablex #1^^M{% -\tabley\vritemindex#1 \endtabley -\def\Evtable{\endgraf\afterenvbreak\endgroup}% -\let\Etable=\relax}} - -\def\dontindex #1{} -\def\fnitemindex #1{\doind {fn}{\code{#1}}}% -\def\vritemindex #1{\doind {vr}{\code{#1}}}% - -{\obeyspaces % -\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% -\tablez{#1}{#2}{#3}{#4}{#5}{#6}}} - -\def\tablez #1#2#3#4#5#6{% -\aboveenvbreak % -\begingroup % -\def\Edescription{\Etable}% Necessary kludge. -\let\itemindex=#1% -\ifnum 0#3>0 \advance \leftskip by #3\mil \fi % -\ifnum 0#4>0 \tableindent=#4\mil \fi % -\ifnum 0#5>0 \advance \rightskip by #5\mil \fi % -\def\itemfont{#2}% -\itemmax=\tableindent % -\advance \itemmax by -\itemmargin % -\advance \leftskip by \tableindent % -\exdentamount=\tableindent -\parindent = 0pt -\parskip = \smallskipamount -\ifdim \parskip=0pt \parskip=2pt \fi% -\def\Etable{\endgraf\afterenvbreak\endgroup}% -\let\item = \internalBitem % -\let\itemx = \internalBitemx % -\let\kitem = \internalBkitem % -\let\kitemx = \internalBkitemx % -\let\xitem = \internalBxitem % -\let\xitemx = \internalBxitemx % -} - -% This is the counter used by @enumerate, which is really @itemize - -\newcount \itemno - -\def\itemize{\parsearg\itemizezzz} - -\def\itemizezzz #1{% - \begingroup % ended by the @end itemize - \itemizey {#1}{\Eitemize} -} - -\def\itemizey#1#2{% - \aboveenvbreak - \itemmax=\itemindent - \advance\itemmax by -\itemmargin - \advance\leftskip by \itemindent - \exdentamount=\itemindent - \parindent=0pt - \parskip=\smallskipamount - \ifdim\parskip=0pt \parskip=2pt \fi - \def#2{\endgraf\afterenvbreak\endgroup}% - \def\itemcontents{#1}% - % @itemize with no arg is equivalent to @itemize @bullet. - \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi - \let\item=\itemizeitem -} - -% \splitoff TOKENS\endmark defines \first to be the first token in -% TOKENS, and \rest to be the remainder. -% -\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% - -% Allow an optional argument of an uppercase letter, lowercase letter, -% or number, to specify the first label in the enumerated list. No -% argument is the same as `1'. -% -\def\enumerate{\parsearg\enumeratezzz} -\def\enumeratezzz #1{\enumeratey #1 \endenumeratey} -\def\enumeratey #1 #2\endenumeratey{% - \begingroup % ended by the @end enumerate - % - % If we were given no argument, pretend we were given `1'. - \def\thearg{#1}% - \ifx\thearg\empty \def\thearg{1}\fi - % - % Detect if the argument is a single token. If so, it might be a - % letter. Otherwise, the only valid thing it can be is a number. - % (We will always have one token, because of the test we just made. - % This is a good thing, since \splitoff doesn't work given nothing at - % all -- the first parameter is undelimited.) - \expandafter\splitoff\thearg\endmark - \ifx\rest\empty - % Only one token in the argument. It could still be anything. - % A ``lowercase letter'' is one whose \lccode is nonzero. - % An ``uppercase letter'' is one whose \lccode is both nonzero, and - % not equal to itself. - % Otherwise, we assume it's a number. - % - % We need the \relax at the end of the \ifnum lines to stop TeX from - % continuing to look for a <number>. - % - \ifnum\lccode\expandafter`\thearg=0\relax - \numericenumerate % a number (we hope) - \else - % It's a letter. - \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax - \lowercaseenumerate % lowercase letter - \else - \uppercaseenumerate % uppercase letter - \fi - \fi - \else - % Multiple tokens in the argument. We hope it's a number. - \numericenumerate - \fi -} - -% An @enumerate whose labels are integers. The starting integer is -% given in \thearg. -% -\def\numericenumerate{% - \itemno = \thearg - \startenumeration{\the\itemno}% -} - -% The starting (lowercase) letter is in \thearg. -\def\lowercaseenumerate{% - \itemno = \expandafter`\thearg - \startenumeration{% - % Be sure we're not beyond the end of the alphabet. - \ifnum\itemno=0 - \errmessage{No more lowercase letters in @enumerate; get a bigger - alphabet}% - \fi - \char\lccode\itemno - }% -} - -% The starting (uppercase) letter is in \thearg. -\def\uppercaseenumerate{% - \itemno = \expandafter`\thearg - \startenumeration{% - % Be sure we're not beyond the end of the alphabet. - \ifnum\itemno=0 - \errmessage{No more uppercase letters in @enumerate; get a bigger - alphabet} - \fi - \char\uccode\itemno - }% -} - -% Call itemizey, adding a period to the first argument and supplying the -% common last two arguments. Also subtract one from the initial value in -% \itemno, since @item increments \itemno. -% -\def\startenumeration#1{% - \advance\itemno by -1 - \itemizey{#1.}\Eenumerate\flushcr -} - -% @alphaenumerate and @capsenumerate are abbreviations for giving an arg -% to @enumerate. -% -\def\alphaenumerate{\enumerate{a}} -\def\capsenumerate{\enumerate{A}} -\def\Ealphaenumerate{\Eenumerate} -\def\Ecapsenumerate{\Eenumerate} - -% Definition of @item while inside @itemize. - -\def\itemizeitem{% -\advance\itemno by 1 -{\let\par=\endgraf \smallbreak}% -\ifhmode \errmessage{In hmode at itemizeitem}\fi -{\parskip=0in \hskip 0pt -\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% -\vadjust{\penalty 1200}}% -\flushcr} - -% @multitable macros -% Amy Hendrickson, 8/18/94, 3/6/96 -% -% @multitable ... @end multitable will make as many columns as desired. -% Contents of each column will wrap at width given in preamble. Width -% can be specified either with sample text given in a template line, -% or in percent of \hsize, the current width of text on page. - -% Table can continue over pages but will only break between lines. - -% To make preamble: -% -% Either define widths of columns in terms of percent of \hsize: -% @multitable @columnfractions .25 .3 .45 -% @item ... -% -% Numbers following @columnfractions are the percent of the total -% current hsize to be used for each column. You may use as many -% columns as desired. - - -% Or use a template: -% @multitable {Column 1 template} {Column 2 template} {Column 3 template} -% @item ... -% using the widest term desired in each column. -% -% For those who want to use more than one line's worth of words in -% the preamble, break the line within one argument and it -% will parse correctly, i.e., -% -% @multitable {Column 1 template} {Column 2 template} {Column 3 -% template} -% Not: -% @multitable {Column 1 template} {Column 2 template} -% {Column 3 template} - -% Each new table line starts with @item, each subsequent new column -% starts with @tab. Empty columns may be produced by supplying @tab's -% with nothing between them for as many times as empty columns are needed, -% ie, @tab@tab@tab will produce two empty columns. - -% @item, @tab, @multitable or @end multitable do not need to be on their -% own lines, but it will not hurt if they are. - -% Sample multitable: - -% @multitable {Column 1 template} {Column 2 template} {Column 3 template} -% @item first col stuff @tab second col stuff @tab third col -% @item -% first col stuff -% @tab -% second col stuff -% @tab -% third col -% @item first col stuff @tab second col stuff -% @tab Many paragraphs of text may be used in any column. -% -% They will wrap at the width determined by the template. -% @item@tab@tab This will be in third column. -% @end multitable - -% Default dimensions may be reset by user. -% @multitableparskip is vertical space between paragraphs in table. -% @multitableparindent is paragraph indent in table. -% @multitablecolmargin is horizontal space to be left between columns. -% @multitablelinespace is space to leave between table items, baseline -% to baseline. -% 0pt means it depends on current normal line spacing. -% -\newskip\multitableparskip -\newskip\multitableparindent -\newdimen\multitablecolspace -\newskip\multitablelinespace -\multitableparskip=0pt -\multitableparindent=6pt -\multitablecolspace=12pt -\multitablelinespace=0pt - -% Macros used to set up halign preamble: -% -\let\endsetuptable\relax -\def\xendsetuptable{\endsetuptable} -\let\columnfractions\relax -\def\xcolumnfractions{\columnfractions} -\newif\ifsetpercent - -% #1 is the part of the @columnfraction before the decimal point, which -% is presumably either 0 or the empty string (but we don't check, we -% just throw it away). #2 is the decimal part, which we use as the -% percent of \hsize for this column. -\def\pickupwholefraction#1.#2 {% - \global\advance\colcount by 1 - \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% - \setuptable -} - -\newcount\colcount -\def\setuptable#1{% - \def\firstarg{#1}% - \ifx\firstarg\xendsetuptable - \let\go = \relax - \else - \ifx\firstarg\xcolumnfractions - \global\setpercenttrue - \else - \ifsetpercent - \let\go\pickupwholefraction - \else - \global\advance\colcount by 1 - \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a - % separator; typically that is always in the input, anyway. - \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% - \fi - \fi - \ifx\go\pickupwholefraction - % Put the argument back for the \pickupwholefraction call, so - % we'll always have a period there to be parsed. - \def\go{\pickupwholefraction#1}% - \else - \let\go = \setuptable - \fi% - \fi - \go -} - -% @multitable ... @end multitable definitions: -% -\def\multitable{\parsearg\dotable} -\def\dotable#1{\bgroup - \vskip\parskip - \let\item=\crcrwithfootnotes - % A \tab used to include \hskip1sp. But then the space in a template - % line is not enough. That is bad. So let's go back to just & until - % we encounter the problem it was intended to solve again. --karl, - % nathan@acm.org, 20apr99. - \let\tab=&% - \let\startfootins=\startsavedfootnote - \tolerance=9500 - \hbadness=9500 - \setmultitablespacing - \parskip=\multitableparskip - \parindent=\multitableparindent - \overfullrule=0pt - \global\colcount=0 - \def\Emultitable{% - \global\setpercentfalse - \crcrwithfootnotes\crcr - \egroup\egroup - }% - % - % To parse everything between @multitable and @item: - \setuptable#1 \endsetuptable - % - % \everycr will reset column counter, \colcount, at the end of - % each line. Every column entry will cause \colcount to advance by one. - % The table preamble - % looks at the current \colcount to find the correct column width. - \everycr{\noalign{% - % - % \filbreak%% keeps underfull box messages off when table breaks over pages. - % Maybe so, but it also creates really weird page breaks when the table - % breaks over pages. Wouldn't \vfil be better? Wait until the problem - % manifests itself, so it can be fixed for real --karl. - \global\colcount=0\relax}}% - % - % This preamble sets up a generic column definition, which will - % be used as many times as user calls for columns. - % \vtop will set a single line and will also let text wrap and - % continue for many paragraphs if desired. - \halign\bgroup&\global\advance\colcount by 1\relax - \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname - % - % In order to keep entries from bumping into each other - % we will add a \leftskip of \multitablecolspace to all columns after - % the first one. - % - % If a template has been used, we will add \multitablecolspace - % to the width of each template entry. - % - % If the user has set preamble in terms of percent of \hsize we will - % use that dimension as the width of the column, and the \leftskip - % will keep entries from bumping into each other. Table will start at - % left margin and final column will justify at right margin. - % - % Make sure we don't inherit \rightskip from the outer environment. - \rightskip=0pt - \ifnum\colcount=1 - % The first column will be indented with the surrounding text. - \advance\hsize by\leftskip - \else - \ifsetpercent \else - % If user has not set preamble in terms of percent of \hsize - % we will advance \hsize by \multitablecolspace. - \advance\hsize by \multitablecolspace - \fi - % In either case we will make \leftskip=\multitablecolspace: - \leftskip=\multitablecolspace - \fi - % Ignoring space at the beginning and end avoids an occasional spurious - % blank line, when TeX decides to break the line at the space before the - % box from the multistrut, so the strut ends up on a line by itself. - % For example: - % @multitable @columnfractions .11 .89 - % @item @code{#} - % @tab Legal holiday which is valid in major parts of the whole country. - % Is automatically provided with highlighting sequences respectively marking - % characters. - \noindent\ignorespaces##\unskip\multistrut}\cr -} - -\def\setmultitablespacing{% test to see if user has set \multitablelinespace. -% If so, do nothing. If not, give it an appropriate dimension based on -% current baselineskip. -\ifdim\multitablelinespace=0pt -\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip -\global\advance\multitablelinespace by-\ht0 -%% strut to put in table in case some entry doesn't have descenders, -%% to keep lines equally spaced -\let\multistrut = \strut -\else -%% FIXME: what is \box0 supposed to be? -\gdef\multistrut{\vrule height\multitablelinespace depth\dp0 -width0pt\relax} \fi -%% Test to see if parskip is larger than space between lines of -%% table. If not, do nothing. -%% If so, set to same dimension as multitablelinespace. -\ifdim\multitableparskip>\multitablelinespace -\global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller - %% than skip between lines in the table. -\fi% -\ifdim\multitableparskip=0pt -\global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller - %% than skip between lines in the table. -\fi} - -% In case a @footnote appears inside an alignment, save the footnote -% text to a box and make the \insert when a row of the table is -% finished. Otherwise, the insertion is lost, it never migrates to the -% main vertical list. --kasal, 22jan03. -% -\newbox\savedfootnotes -% -% \dotable \let's \startfootins to this, so that \dofootnote will call -% it instead of starting the insertion right away. -\def\startsavedfootnote{% - \global\setbox\savedfootnotes = \vbox\bgroup - \unvbox\savedfootnotes -} -\def\crcrwithfootnotes{% - \crcr - \ifvoid\savedfootnotes \else - \noalign{\insert\footins{\box\savedfootnotes}}% - \fi -} - -\message{conditionals,} -% Prevent errors for section commands. -% Used in @ignore and in failing conditionals. -\def\ignoresections{% - \let\chapter=\relax - \let\unnumbered=\relax - \let\top=\relax - \let\unnumberedsec=\relax - \let\unnumberedsection=\relax - \let\unnumberedsubsec=\relax - \let\unnumberedsubsection=\relax - \let\unnumberedsubsubsec=\relax - \let\unnumberedsubsubsection=\relax - \let\section=\relax - \let\subsec=\relax - \let\subsubsec=\relax - \let\subsection=\relax - \let\subsubsection=\relax - \let\appendix=\relax - \let\appendixsec=\relax - \let\appendixsection=\relax - \let\appendixsubsec=\relax - \let\appendixsubsection=\relax - \let\appendixsubsubsec=\relax - \let\appendixsubsubsection=\relax - \let\contents=\relax - \let\smallbook=\relax - \let\titlepage=\relax -} - -% Used in nested conditionals, where we have to parse the Texinfo source -% and so want to turn off most commands, in case they are used -% incorrectly. -% -% We use \empty instead of \relax for the @def... commands, so that \end -% doesn't throw an error. For instance: -% @ignore -% @deffn ... -% @end deffn -% @end ignore -% -% The @end deffn is going to get expanded, because we're trying to allow -% nested conditionals. But we don't want to expand the actual @deffn, -% since it might be syntactically correct and intended to be ignored. -% Since \end checks for \relax, using \empty does not cause an error. -% -\def\ignoremorecommands{% - \let\defcodeindex = \relax - \let\defcv = \empty - \let\defcvx = \empty - \let\Edefcv = \empty - \let\deffn = \empty - \let\deffnx = \empty - \let\Edeffn = \empty - \let\defindex = \relax - \let\defivar = \empty - \let\defivarx = \empty - \let\Edefivar = \empty - \let\defmac = \empty - \let\defmacx = \empty - \let\Edefmac = \empty - \let\defmethod = \empty - \let\defmethodx = \empty - \let\Edefmethod = \empty - \let\defop = \empty - \let\defopx = \empty - \let\Edefop = \empty - \let\defopt = \empty - \let\defoptx = \empty - \let\Edefopt = \empty - \let\defspec = \empty - \let\defspecx = \empty - \let\Edefspec = \empty - \let\deftp = \empty - \let\deftpx = \empty - \let\Edeftp = \empty - \let\deftypefn = \empty - \let\deftypefnx = \empty - \let\Edeftypefn = \empty - \let\deftypefun = \empty - \let\deftypefunx = \empty - \let\Edeftypefun = \empty - \let\deftypeivar = \empty - \let\deftypeivarx = \empty - \let\Edeftypeivar = \empty - \let\deftypemethod = \empty - \let\deftypemethodx = \empty - \let\Edeftypemethod = \empty - \let\deftypeop = \empty - \let\deftypeopx = \empty - \let\Edeftypeop = \empty - \let\deftypevar = \empty - \let\deftypevarx = \empty - \let\Edeftypevar = \empty - \let\deftypevr = \empty - \let\deftypevrx = \empty - \let\Edeftypevr = \empty - \let\defun = \empty - \let\defunx = \empty - \let\Edefun = \empty - \let\defvar = \empty - \let\defvarx = \empty - \let\Edefvar = \empty - \let\defvr = \empty - \let\defvrx = \empty - \let\Edefvr = \empty - \let\clear = \relax - \let\down = \relax - \let\evenfooting = \relax - \let\evenheading = \relax - \let\everyfooting = \relax - \let\everyheading = \relax - \let\headings = \relax - \let\include = \relax - \let\item = \relax - \let\lowersections = \relax - \let\oddfooting = \relax - \let\oddheading = \relax - \let\printindex = \relax - \let\pxref = \relax - \let\raisesections = \relax - \let\ref = \relax - \let\set = \relax - \let\setchapternewpage = \relax - \let\setchapterstyle = \relax - \let\settitle = \relax - \let\up = \relax - \let\verbatiminclude = \relax - \let\xref = \relax -} - -% Ignore @ignore, @ifhtml, @ifinfo, and the like. -% -\def\direntry{\doignore{direntry}} -\def\documentdescriptionword{documentdescription} -\def\documentdescription{\doignore{documentdescription}} -\def\html{\doignore{html}} -\def\ifhtml{\doignore{ifhtml}} -\def\ifinfo{\doignore{ifinfo}} -\def\ifnottex{\doignore{ifnottex}} -\def\ifplaintext{\doignore{ifplaintext}} -\def\ifxml{\doignore{ifxml}} -\def\ignore{\doignore{ignore}} -\def\menu{\doignore{menu}} -\def\xml{\doignore{xml}} - -% @dircategory CATEGORY -- specify a category of the dir file -% which this file should belong to. Ignore this in TeX. -\let\dircategory = \comment - -% Ignore text until a line `@end #1'. -% -\def\doignore#1{\begingroup - % Don't complain about control sequences we have declared \outer. - \ignoresections - % - % Define a command to swallow text until we reach `@end #1'. - % This @ is a catcode 12 token (that is the normal catcode of @ in - % this texinfo.tex file). We change the catcode of @ below to match. - \long\def\doignoretext##1@end #1{\enddoignore}% - % - % Make sure that spaces turn into tokens that match what \doignoretext wants. - \catcode\spaceChar = 10 - % - % Ignore braces, too, so mismatched braces don't cause trouble. - \catcode`\{ = 9 - \catcode`\} = 9 - % - % We must not have @c interpreted as a control sequence. - \catcode`\@ = 12 - % - \def\ignoreword{#1}% - \ifx\ignoreword\documentdescriptionword - % The c kludge breaks documentdescription, since - % `documentdescription' contains a `c'. Means not everything will - % be ignored inside @documentdescription, but oh well... - \else - % Make the letter c a comment character so that the rest of the line - % will be ignored. This way, the document can have (for example) - % @c @end ifinfo - % and the @end ifinfo will be properly ignored. - % (We've just changed @ to catcode 12.) - \catcode`\c = 14 - \fi - % - % And now expand the command defined above. - \doignoretext -} - -% What we do to finish off ignored text. -% -\def\enddoignore{\endgroup\ignorespaces}% - -\newif\ifwarnedobs\warnedobsfalse -\def\obstexwarn{% - \ifwarnedobs\relax\else - % We need to warn folks that they may have trouble with TeX 3.0. - % This uses \immediate\write16 rather than \message to get newlines. - \immediate\write16{} - \immediate\write16{WARNING: for users of Unix TeX 3.0!} - \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} - \immediate\write16{If you are running another version of TeX, relax.} - \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} - \immediate\write16{ Then upgrade your TeX installation if you can.} - \immediate\write16{ (See ftp://ftp.gnu.org/non-gnu/TeX.README.)} - \immediate\write16{If you are stuck with version 3.0, run the} - \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} - \immediate\write16{ to use a workaround.} - \immediate\write16{} - \global\warnedobstrue - \fi -} - -% **In TeX 3.0, setting text in \nullfont hangs tex. For a -% workaround (which requires the file ``dummy.tfm'' to be installed), -% uncomment the following line: -%%%%%\font\nullfont=dummy\let\obstexwarn=\relax - -% Ignore text, except that we keep track of conditional commands for -% purposes of nesting, up to an `@end #1' command. -% -\def\nestedignore#1{% - \obstexwarn - % We must actually expand the ignored text to look for the @end - % command, so that nested ignore constructs work. Thus, we put the - % text into a \vbox and then do nothing with the result. To minimize - % the chance of memory overflow, we follow the approach outlined on - % page 401 of the TeXbook. - % - \setbox0 = \vbox\bgroup - % Don't complain about control sequences we have declared \outer. - \ignoresections - % - % Define `@end #1' to end the box, which will in turn undefine the - % @end command again. - \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% - % - % We are going to be parsing Texinfo commands. Most cause no - % trouble when they are used incorrectly, but some commands do - % complicated argument parsing or otherwise get confused, so we - % undefine them. - % - % We can't do anything about stray @-signs, unfortunately; - % they'll produce `undefined control sequence' errors. - \ignoremorecommands - % - % Set the current font to be \nullfont, a TeX primitive, and define - % all the font commands to also use \nullfont. We don't use - % dummy.tfm, as suggested in the TeXbook, because some sites - % might not have that installed. Therefore, math mode will still - % produce output, but that should be an extremely small amount of - % stuff compared to the main input. - % - \nullfont - \let\tenrm=\nullfont \let\tenit=\nullfont \let\tensl=\nullfont - \let\tenbf=\nullfont \let\tentt=\nullfont \let\smallcaps=\nullfont - \let\tensf=\nullfont - % Similarly for index fonts. - \let\smallrm=\nullfont \let\smallit=\nullfont \let\smallsl=\nullfont - \let\smallbf=\nullfont \let\smalltt=\nullfont \let\smallsc=\nullfont - \let\smallsf=\nullfont - % Similarly for smallexample fonts. - \let\smallerrm=\nullfont \let\smallerit=\nullfont \let\smallersl=\nullfont - \let\smallerbf=\nullfont \let\smallertt=\nullfont \let\smallersc=\nullfont - \let\smallersf=\nullfont - % - % Don't complain when characters are missing from the fonts. - \tracinglostchars = 0 - % - % Don't bother to do space factor calculations. - \frenchspacing - % - % Don't report underfull hboxes. - \hbadness = 10000 - % - % Do minimal line-breaking. - \pretolerance = 10000 - % - % Do not execute instructions in @tex. - \def\tex{\doignore{tex}}% - % Do not execute macro definitions. - % `c' is a comment character, so the word `macro' will get cut off. - \def\macro{\doignore{ma}}% -} - -% @set VAR sets the variable VAR to an empty value. -% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. -% -% Since we want to separate VAR from REST-OF-LINE (which might be -% empty), we can't just use \parsearg; we have to insert a space of our -% own to delimit the rest of the line, and then take it out again if we -% didn't need it. Make sure the catcode of space is correct to avoid -% losing inside @example, for instance. -% -\def\set{\begingroup\catcode` =10 - \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. - \parsearg\setxxx} -\def\setxxx#1{\setyyy#1 \endsetyyy} -\def\setyyy#1 #2\endsetyyy{% - \def\temp{#2}% - \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty - \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. - \fi - \endgroup -} -% Can't use \xdef to pre-expand #2 and save some time, since \temp or -% \next or other control sequences that we've defined might get us into -% an infinite loop. Consider `@set foo @cite{bar}'. -\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} - -% @clear VAR clears (i.e., unsets) the variable VAR. -% -\def\clear{\parsearg\clearxxx} -\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} - -% @value{foo} gets the text saved in variable foo. -{ - \catcode`\_ = \active - % - % We might end up with active _ or - characters in the argument if - % we're called from @code, as @code{@value{foo-bar_}}. So \let any - % such active characters to their normal equivalents. - \gdef\value{\begingroup - \catcode`\-=\other \catcode`\_=\other - \indexbreaks \let_\normalunderscore - \valuexxx} -} -\def\valuexxx#1{\expandablevalue{#1}\endgroup} - -% We have this subroutine so that we can handle at least some @value's -% properly in indexes (we \let\value to this in \indexdummies). Ones -% whose names contain - or _ still won't work, but we can't do anything -% about that. The command has to be fully expandable (if the variable -% is set), since the result winds up in the index file. This means that -% if the variable's value contains other Texinfo commands, it's almost -% certain it will fail (although perhaps we could fix that with -% sufficient work to do a one-level expansion on the result, instead of -% complete). -% -\def\expandablevalue#1{% - \expandafter\ifx\csname SET#1\endcsname\relax - {[No value for ``#1'']}% - \message{Variable `#1', used in @value, is not set.}% - \else - \csname SET#1\endcsname - \fi -} - -% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined -% with @set. -% -\def\ifset{\parsearg\doifset} -\def\doifset#1{% - \expandafter\ifx\csname SET#1\endcsname\relax - \let\next=\ifsetfail - \else - \let\next=\ifsetsucceed - \fi - \next -} -\def\ifsetsucceed{\conditionalsucceed{ifset}} -\def\ifsetfail{\nestedignore{ifset}} -\defineunmatchedend{ifset} - -% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been -% defined with @set, or has been undefined with @clear. -% -\def\ifclear{\parsearg\doifclear} -\def\doifclear#1{% - \expandafter\ifx\csname SET#1\endcsname\relax - \let\next=\ifclearsucceed - \else - \let\next=\ifclearfail - \fi - \next -} -\def\ifclearsucceed{\conditionalsucceed{ifclear}} -\def\ifclearfail{\nestedignore{ifclear}} -\defineunmatchedend{ifclear} - -% @iftex, @ifnothtml, @ifnotinfo, @ifnotplaintext always succeed; we -% read the text following, through the first @end iftex (etc.). Make -% `@end iftex' (etc.) valid only after an @iftex. -% -\def\iftex{\conditionalsucceed{iftex}} -\def\ifnothtml{\conditionalsucceed{ifnothtml}} -\def\ifnotinfo{\conditionalsucceed{ifnotinfo}} -\def\ifnotplaintext{\conditionalsucceed{ifnotplaintext}} -\defineunmatchedend{iftex} -\defineunmatchedend{ifnothtml} -\defineunmatchedend{ifnotinfo} -\defineunmatchedend{ifnotplaintext} - -% True conditional. Since \set globally defines its variables, we can -% just start and end a group (to keep the @end definition undefined at -% the outer level). -% -\def\conditionalsucceed#1{\begingroup - \expandafter\def\csname E#1\endcsname{\endgroup}% -} - -% @defininfoenclose. -\let\definfoenclose=\comment - - -\message{indexing,} -% Index generation facilities - -% Define \newwrite to be identical to plain tex's \newwrite -% except not \outer, so it can be used within \newindex. -{\catcode`\@=11 -\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} - -% \newindex {foo} defines an index named foo. -% It automatically defines \fooindex such that -% \fooindex ...rest of line... puts an entry in the index foo. -% It also defines \fooindfile to be the number of the output channel for -% the file that accumulates this index. The file's extension is foo. -% The name of an index should be no more than 2 characters long -% for the sake of vms. -% -\def\newindex#1{% - \iflinks - \expandafter\newwrite \csname#1indfile\endcsname - \openout \csname#1indfile\endcsname \jobname.#1 % Open the file - \fi - \expandafter\xdef\csname#1index\endcsname{% % Define @#1index - \noexpand\doindex{#1}} -} - -% @defindex foo == \newindex{foo} -% -\def\defindex{\parsearg\newindex} - -% Define @defcodeindex, like @defindex except put all entries in @code. -% -\def\defcodeindex{\parsearg\newcodeindex} -% -\def\newcodeindex#1{% - \iflinks - \expandafter\newwrite \csname#1indfile\endcsname - \openout \csname#1indfile\endcsname \jobname.#1 - \fi - \expandafter\xdef\csname#1index\endcsname{% - \noexpand\docodeindex{#1}}% -} - - -% @synindex foo bar makes index foo feed into index bar. -% Do this instead of @defindex foo if you don't want it as a separate index. -% -% @syncodeindex foo bar similar, but put all entries made for index foo -% inside @code. -% -\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} -\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} - -% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), -% #3 the target index (bar). -\def\dosynindex#1#2#3{% - % Only do \closeout if we haven't already done it, else we'll end up - % closing the target index. - \expandafter \ifx\csname donesynindex#2\endcsname \undefined - % The \closeout helps reduce unnecessary open files; the limit on the - % Acorn RISC OS is a mere 16 files. - \expandafter\closeout\csname#2indfile\endcsname - \expandafter\let\csname\donesynindex#2\endcsname = 1 - \fi - % redefine \fooindfile: - \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname - \expandafter\let\csname#2indfile\endcsname=\temp - % redefine \fooindex: - \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% -} - -% Define \doindex, the driver for all \fooindex macros. -% Argument #1 is generated by the calling \fooindex macro, -% and it is "foo", the name of the index. - -% \doindex just uses \parsearg; it calls \doind for the actual work. -% This is because \doind is more useful to call from other macros. - -% There is also \dosubind {index}{topic}{subtopic} -% which makes an entry in a two-level index such as the operation index. - -\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} -\def\singleindexer #1{\doind{\indexname}{#1}} - -% like the previous two, but they put @code around the argument. -\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} -\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} - -% Take care of Texinfo commands that can appear in an index entry. -% Since there are some commands we want to expand, and others we don't, -% we have to laboriously prevent expansion for those that we don't. -% -\def\indexdummies{% - \def\@{@}% change to @@ when we switch to @ as escape char in index files. - \def\ {\realbackslash\space }% - % Need these in case \tex is in effect and \{ is a \delimiter again. - % But can't use \lbracecmd and \rbracecmd because texindex assumes - % braces and backslashes are used only as delimiters. - \let\{ = \mylbrace - \let\} = \myrbrace - % - % \definedummyword defines \#1 as \realbackslash #1\space, thus - % effectively preventing its expansion. This is used only for control - % words, not control letters, because the \space would be incorrect - % for control characters, but is needed to separate the control word - % from whatever follows. - % - % For control letters, we have \definedummyletter, which omits the - % space. - % - % These can be used both for control words that take an argument and - % those that do not. If it is followed by {arg} in the input, then - % that will dutifully get written to the index (or wherever). - % - \def\definedummyword##1{% - \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}% - }% - \def\definedummyletter##1{% - \expandafter\def\csname ##1\endcsname{\realbackslash ##1}% - }% - % - % Do the redefinitions. - \commondummies -} - -% For the aux file, @ is the escape character. So we want to redefine -% everything using @ instead of \realbackslash. When everything uses -% @, this will be simpler. -% -\def\atdummies{% - \def\@{@@}% - \def\ {@ }% - \let\{ = \lbraceatcmd - \let\} = \rbraceatcmd - % - % (See comments in \indexdummies.) - \def\definedummyword##1{% - \expandafter\def\csname ##1\endcsname{@##1\space}% - }% - \def\definedummyletter##1{% - \expandafter\def\csname ##1\endcsname{@##1}% - }% - % - % Do the redefinitions. - \commondummies -} - -% Called from \indexdummies and \atdummies. \definedummyword and -% \definedummyletter must be defined first. -% -\def\commondummies{% - % - \normalturnoffactive - % - % Control letters and accents. - \definedummyletter{_}% - \definedummyletter{,}% - \definedummyletter{"}% - \definedummyletter{`}% - \definedummyletter{'}% - \definedummyletter{^}% - \definedummyletter{~}% - \definedummyletter{=}% - \definedummyword{u}% - \definedummyword{v}% - \definedummyword{H}% - \definedummyword{dotaccent}% - \definedummyword{ringaccent}% - \definedummyword{tieaccent}% - \definedummyword{ubaraccent}% - \definedummyword{udotaccent}% - \definedummyword{dotless}% - % - % Other non-English letters. - \definedummyword{AA}% - \definedummyword{AE}% - \definedummyword{L}% - \definedummyword{OE}% - \definedummyword{O}% - \definedummyword{aa}% - \definedummyword{ae}% - \definedummyword{l}% - \definedummyword{oe}% - \definedummyword{o}% - \definedummyword{ss}% - % - % Although these internal commands shouldn't show up, sometimes they do. - \definedummyword{bf}% - \definedummyword{gtr}% - \definedummyword{hat}% - \definedummyword{less}% - \definedummyword{sf}% - \definedummyword{sl}% - \definedummyword{tclose}% - \definedummyword{tt}% - % - % Texinfo font commands. - \definedummyword{b}% - \definedummyword{i}% - \definedummyword{r}% - \definedummyword{sc}% - \definedummyword{t}% - % - \definedummyword{TeX}% - \definedummyword{acronym}% - \definedummyword{cite}% - \definedummyword{code}% - \definedummyword{command}% - \definedummyword{dfn}% - \definedummyword{dots}% - \definedummyword{emph}% - \definedummyword{env}% - \definedummyword{file}% - \definedummyword{kbd}% - \definedummyword{key}% - \definedummyword{math}% - \definedummyword{option}% - \definedummyword{samp}% - \definedummyword{strong}% - \definedummyword{uref}% - \definedummyword{url}% - \definedummyword{var}% - \definedummyword{w}% - % - % Assorted special characters. - \definedummyword{bullet}% - \definedummyword{copyright}% - \definedummyword{dots}% - \definedummyword{enddots}% - \definedummyword{equiv}% - \definedummyword{error}% - \definedummyword{expansion}% - \definedummyword{minus}% - \definedummyword{pounds}% - \definedummyword{point}% - \definedummyword{print}% - \definedummyword{result}% - % - % Handle some cases of @value -- where the variable name does not - % contain - or _, and the value does not contain any - % (non-fully-expandable) commands. - \let\value = \expandablevalue - % - % Normal spaces, not active ones. - \unsepspaces - % - % No macro expansion. - \turnoffmacros -} - -% If an index command is used in an @example environment, any spaces -% therein should become regular spaces in the raw index file, not the -% expansion of \tie (\leavevmode \penalty \@M \ ). -{\obeyspaces - \gdef\unsepspaces{\obeyspaces\let =\space}} - - -% \indexnofonts is used when outputting the strings to sort the index -% by, and when constructing control sequence names. It eliminates all -% control sequences and just writes whatever the best ASCII sort string -% would be for a given command (usually its argument). -% -\def\indexdummytex{TeX} -\def\indexdummydots{...} -% -\def\indexnofonts{% - \def\ { }% - \def\@{@}% - % how to handle braces? - \def\_{\normalunderscore}% - % - \let\,=\asis - \let\"=\asis - \let\`=\asis - \let\'=\asis - \let\^=\asis - \let\~=\asis - \let\==\asis - \let\u=\asis - \let\v=\asis - \let\H=\asis - \let\dotaccent=\asis - \let\ringaccent=\asis - \let\tieaccent=\asis - \let\ubaraccent=\asis - \let\udotaccent=\asis - \let\dotless=\asis - % - % Other non-English letters. - \def\AA{AA}% - \def\AE{AE}% - \def\L{L}% - \def\OE{OE}% - \def\O{O}% - \def\aa{aa}% - \def\ae{ae}% - \def\l{l}% - \def\oe{oe}% - \def\o{o}% - \def\ss{ss}% - \def\exclamdown{!}% - \def\questiondown{?}% - % - % Don't no-op \tt, since it isn't a user-level command - % and is used in the definitions of the active chars like <, >, |, etc. - % Likewise with the other plain tex font commands. - %\let\tt=\asis - % - % Texinfo font commands. - \let\b=\asis - \let\i=\asis - \let\r=\asis - \let\sc=\asis - \let\t=\asis - % - \let\TeX=\indexdummytex - \let\acronym=\asis - \let\cite=\asis - \let\code=\asis - \let\command=\asis - \let\dfn=\asis - \let\dots=\indexdummydots - \let\emph=\asis - \let\env=\asis - \let\file=\asis - \let\kbd=\asis - \let\key=\asis - \let\math=\asis - \let\option=\asis - \let\samp=\asis - \let\strong=\asis - \let\uref=\asis - \let\url=\asis - \let\var=\asis - \let\w=\asis -} - -\let\indexbackslash=0 %overridden during \printindex. -\let\SETmarginindex=\relax % put index entries in margin (undocumented)? - -% For \ifx comparisons. -\def\emptymacro{\empty} - -% Most index entries go through here, but \dosubind is the general case. -% -\def\doind#1#2{\dosubind{#1}{#2}\empty} - -% Workhorse for all \fooindexes. -% #1 is name of index, #2 is stuff to put there, #3 is subentry -- -% \empty if called from \doind, as we usually are. The main exception -% is with defuns, which call us directly. -% -\def\dosubind#1#2#3{% - % Put the index entry in the margin if desired. - \ifx\SETmarginindex\relax\else - \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% - \fi - {% - \count255=\lastpenalty - {% - \indexdummies % Must do this here, since \bf, etc expand at this stage - \escapechar=`\\ - {% - \let\folio = 0% We will expand all macros now EXCEPT \folio. - \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now - % so it will be output as is; and it will print as backslash. - % - % The main index entry text. - \toks0 = {#2}% - % - % If third arg is present, precede it with space in sort key. - \def\thirdarg{#3}% - \ifx\thirdarg\emptymacro \else - % If the third (subentry) arg is present, add it to the index - % line to write. - \toks0 = \expandafter{\the\toks0 \space #3}% - \fi - % - % Process the index entry with all font commands turned off, to - % get the string to sort by. - {\indexnofonts - \edef\temp{\the\toks0}% need full expansion - \xdef\indexsorttmp{\temp}% - }% - % - % Set up the complete index entry, with both the sort key and - % the original text, including any font commands. We write - % three arguments to \entry to the .?? file (four in the - % subentry case), texindex reduces to two when writing the .??s - % sorted result. - \edef\temp{% - \write\csname#1indfile\endcsname{% - \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% - }% - % - % If a skip is the last thing on the list now, preserve it - % by backing up by \lastskip, doing the \write, then inserting - % the skip again. Otherwise, the whatsit generated by the - % \write will make \lastskip zero. The result is that sequences - % like this: - % @end defun - % @tindex whatever - % @defun ... - % will have extra space inserted, because the \medbreak in the - % start of the @defun won't see the skip inserted by the @end of - % the previous defun. - % - % But don't do any of this if we're not in vertical mode. We - % don't want to do a \vskip and prematurely end a paragraph. - % - % Avoid page breaks due to these extra skips, too. - % - \iflinks - \ifvmode - \skip0 = \lastskip - \ifdim\lastskip = 0pt \else \nobreak\vskip-\skip0 \fi - \fi - % - \temp % do the write - % - \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi - \fi - }% - }% - \penalty\count255 - }% -} - -% The index entry written in the file actually looks like -% \entry {sortstring}{page}{topic} -% or -% \entry {sortstring}{page}{topic}{subtopic} -% The texindex program reads in these files and writes files -% containing these kinds of lines: -% \initial {c} -% before the first topic whose initial is c -% \entry {topic}{pagelist} -% for a topic that is used without subtopics -% \primary {topic} -% for the beginning of a topic that is used with subtopics -% \secondary {subtopic}{pagelist} -% for each subtopic. - -% Define the user-accessible indexing commands -% @findex, @vindex, @kindex, @cindex. - -\def\findex {\fnindex} -\def\kindex {\kyindex} -\def\cindex {\cpindex} -\def\vindex {\vrindex} -\def\tindex {\tpindex} -\def\pindex {\pgindex} - -\def\cindexsub {\begingroup\obeylines\cindexsub} -{\obeylines % -\gdef\cindexsub "#1" #2^^M{\endgroup % -\dosubind{cp}{#2}{#1}}} - -% Define the macros used in formatting output of the sorted index material. - -% @printindex causes a particular index (the ??s file) to get printed. -% It does not print any chapter heading (usually an @unnumbered). -% -\def\printindex{\parsearg\doprintindex} -\def\doprintindex#1{\begingroup - \dobreak \chapheadingskip{10000}% - % - \smallfonts \rm - \tolerance = 9500 - \everypar = {}% don't want the \kern\-parindent from indentation suppression. - \indexbreaks - % - % See if the index file exists and is nonempty. - % Change catcode of @ here so that if the index file contains - % \initial {@} - % as its first line, TeX doesn't complain about mismatched braces - % (because it thinks @} is a control sequence). - \catcode`\@ = 11 - \openin 1 \jobname.#1s - \ifeof 1 - % \enddoublecolumns gets confused if there is no text in the index, - % and it loses the chapter title and the aux file entries for the - % index. The easiest way to prevent this problem is to make sure - % there is some text. - \putwordIndexNonexistent - \else - % - % If the index file exists but is empty, then \openin leaves \ifeof - % false. We have to make TeX try to read something from the file, so - % it can discover if there is anything in it. - \read 1 to \temp - \ifeof 1 - \putwordIndexIsEmpty - \else - % Index files are almost Texinfo source, but we use \ as the escape - % character. It would be better to use @, but that's too big a change - % to make right now. - \def\indexbackslash{\rawbackslashxx}% - \catcode`\\ = 0 - \escapechar = `\\ - \begindoublecolumns - \input \jobname.#1s - \enddoublecolumns - \fi - \fi - \closein 1 -\endgroup} - -% These macros are used by the sorted index file itself. -% Change them to control the appearance of the index. - -\def\initial#1{{% - % Some minor font changes for the special characters. - \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt - % - % Remove any glue we may have, we'll be inserting our own. - \removelastskip - % - % We like breaks before the index initials, so insert a bonus. - \penalty -300 - % - % Typeset the initial. Making this add up to a whole number of - % baselineskips increases the chance of the dots lining up from column - % to column. It still won't often be perfect, because of the stretch - % we need before each entry, but it's better. - % - % No shrink because it confuses \balancecolumns. - \vskip 1.67\baselineskip plus .5\baselineskip - \leftline{\secbf #1}% - \vskip .33\baselineskip plus .1\baselineskip - % - % Do our best not to break after the initial. - \nobreak -}} - -% This typesets a paragraph consisting of #1, dot leaders, and then #2 -% flush to the right margin. It is used for index and table of contents -% entries. The paragraph is indented by \leftskip. -% -\def\entry#1#2{\begingroup - % - % Start a new paragraph if necessary, so our assignments below can't - % affect previous text. - \par - % - % Do not fill out the last line with white space. - \parfillskip = 0in - % - % No extra space above this paragraph. - \parskip = 0in - % - % Do not prefer a separate line ending with a hyphen to fewer lines. - \finalhyphendemerits = 0 - % - % \hangindent is only relevant when the entry text and page number - % don't both fit on one line. In that case, bob suggests starting the - % dots pretty far over on the line. Unfortunately, a large - % indentation looks wrong when the entry text itself is broken across - % lines. So we use a small indentation and put up with long leaders. - % - % \hangafter is reset to 1 (which is the value we want) at the start - % of each paragraph, so we need not do anything with that. - \hangindent = 2em - % - % When the entry text needs to be broken, just fill out the first line - % with blank space. - \rightskip = 0pt plus1fil - % - % A bit of stretch before each entry for the benefit of balancing columns. - \vskip 0pt plus1pt - % - % Start a ``paragraph'' for the index entry so the line breaking - % parameters we've set above will have an effect. - \noindent - % - % Insert the text of the index entry. TeX will do line-breaking on it. - #1% - % The following is kludged to not output a line of dots in the index if - % there are no page numbers. The next person who breaks this will be - % cursed by a Unix daemon. - \def\tempa{{\rm }}% - \def\tempb{#2}% - \edef\tempc{\tempa}% - \edef\tempd{\tempb}% - \ifx\tempc\tempd\ \else% - % - % If we must, put the page number on a line of its own, and fill out - % this line with blank space. (The \hfil is overwhelmed with the - % fill leaders glue in \indexdotfill if the page number does fit.) - \hfil\penalty50 - \null\nobreak\indexdotfill % Have leaders before the page number. - % - % The `\ ' here is removed by the implicit \unskip that TeX does as - % part of (the primitive) \par. Without it, a spurious underfull - % \hbox ensues. - \ifpdf - \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. - \else - \ #2% The page number ends the paragraph. - \fi - \fi% - \par -\endgroup} - -% Like \dotfill except takes at least 1 em. -\def\indexdotfill{\cleaders - \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} - -\def\primary #1{\line{#1\hfil}} - -\newskip\secondaryindent \secondaryindent=0.5cm -\def\secondary#1#2{{% - \parfillskip=0in - \parskip=0in - \hangindent=1in - \hangafter=1 - \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill - \ifpdf - \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. - \else - #2 - \fi - \par -}} - -% Define two-column mode, which we use to typeset indexes. -% Adapted from the TeXbook, page 416, which is to say, -% the manmac.tex format used to print the TeXbook itself. -\catcode`\@=11 - -\newbox\partialpage -\newdimen\doublecolumnhsize - -\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns - % Grab any single-column material above us. - \output = {% - % - % Here is a possibility not foreseen in manmac: if we accumulate a - % whole lot of material, we might end up calling this \output - % routine twice in a row (see the doublecol-lose test, which is - % essentially a couple of indexes with @setchapternewpage off). In - % that case we just ship out what is in \partialpage with the normal - % output routine. Generally, \partialpage will be empty when this - % runs and this will be a no-op. See the indexspread.tex test case. - \ifvoid\partialpage \else - \onepageout{\pagecontents\partialpage}% - \fi - % - \global\setbox\partialpage = \vbox{% - % Unvbox the main output page. - \unvbox\PAGE - \kern-\topskip \kern\baselineskip - }% - }% - \eject % run that output routine to set \partialpage - % - % Use the double-column output routine for subsequent pages. - \output = {\doublecolumnout}% - % - % Change the page size parameters. We could do this once outside this - % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 - % format, but then we repeat the same computation. Repeating a couple - % of assignments once per index is clearly meaningless for the - % execution time, so we may as well do it in one place. - % - % First we halve the line length, less a little for the gutter between - % the columns. We compute the gutter based on the line length, so it - % changes automatically with the paper format. The magic constant - % below is chosen so that the gutter has the same value (well, +-<1pt) - % as it did when we hard-coded it. - % - % We put the result in a separate register, \doublecolumhsize, so we - % can restore it in \pagesofar, after \hsize itself has (potentially) - % been clobbered. - % - \doublecolumnhsize = \hsize - \advance\doublecolumnhsize by -.04154\hsize - \divide\doublecolumnhsize by 2 - \hsize = \doublecolumnhsize - % - % Double the \vsize as well. (We don't need a separate register here, - % since nobody clobbers \vsize.) - \vsize = 2\vsize -} - -% The double-column output routine for all double-column pages except -% the last. -% -\def\doublecolumnout{% - \splittopskip=\topskip \splitmaxdepth=\maxdepth - % Get the available space for the double columns -- the normal - % (undoubled) page height minus any material left over from the - % previous page. - \dimen@ = \vsize - \divide\dimen@ by 2 - \advance\dimen@ by -\ht\partialpage - % - % box0 will be the left-hand column, box2 the right. - \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ - \onepageout\pagesofar - \unvbox255 - \penalty\outputpenalty -} -% -% Re-output the contents of the output page -- any previous material, -% followed by the two boxes we just split, in box0 and box2. -\def\pagesofar{% - \unvbox\partialpage - % - \hsize = \doublecolumnhsize - \wd0=\hsize \wd2=\hsize - \hbox to\pagewidth{\box0\hfil\box2}% -} -% -% All done with double columns. -\def\enddoublecolumns{% - \output = {% - % Split the last of the double-column material. Leave it on the - % current page, no automatic page break. - \balancecolumns - % - % If we end up splitting too much material for the current page, - % though, there will be another page break right after this \output - % invocation ends. Having called \balancecolumns once, we do not - % want to call it again. Therefore, reset \output to its normal - % definition right away. (We hope \balancecolumns will never be - % called on to balance too much material, but if it is, this makes - % the output somewhat more palatable.) - \global\output = {\onepageout{\pagecontents\PAGE}}% - }% - \eject - \endgroup % started in \begindoublecolumns - % - % \pagegoal was set to the doubled \vsize above, since we restarted - % the current page. We're now back to normal single-column - % typesetting, so reset \pagegoal to the normal \vsize (after the - % \endgroup where \vsize got restored). - \pagegoal = \vsize -} -% -% Called at the end of the double column material. -\def\balancecolumns{% - \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. - \dimen@ = \ht0 - \advance\dimen@ by \topskip - \advance\dimen@ by-\baselineskip - \divide\dimen@ by 2 % target to split to - %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% - \splittopskip = \topskip - % Loop until we get a decent breakpoint. - {% - \vbadness = 10000 - \loop - \global\setbox3 = \copy0 - \global\setbox1 = \vsplit3 to \dimen@ - \ifdim\ht3>\dimen@ - \global\advance\dimen@ by 1pt - \repeat - }% - %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% - \setbox0=\vbox to\dimen@{\unvbox1}% - \setbox2=\vbox to\dimen@{\unvbox3}% - % - \pagesofar -} -\catcode`\@ = \other - - -\message{sectioning,} -% Chapters, sections, etc. - -\newcount\chapno -\newcount\secno \secno=0 -\newcount\subsecno \subsecno=0 -\newcount\subsubsecno \subsubsecno=0 - -% This counter is funny since it counts through charcodes of letters A, B, ... -\newcount\appendixno \appendixno = `\@ -% \def\appendixletter{\char\the\appendixno} -% We do the following for the sake of pdftex, which needs the actual -% letter in the expansion, not just typeset. -\def\appendixletter{% - \ifnum\appendixno=`A A% - \else\ifnum\appendixno=`B B% - \else\ifnum\appendixno=`C C% - \else\ifnum\appendixno=`D D% - \else\ifnum\appendixno=`E E% - \else\ifnum\appendixno=`F F% - \else\ifnum\appendixno=`G G% - \else\ifnum\appendixno=`H H% - \else\ifnum\appendixno=`I I% - \else\ifnum\appendixno=`J J% - \else\ifnum\appendixno=`K K% - \else\ifnum\appendixno=`L L% - \else\ifnum\appendixno=`M M% - \else\ifnum\appendixno=`N N% - \else\ifnum\appendixno=`O O% - \else\ifnum\appendixno=`P P% - \else\ifnum\appendixno=`Q Q% - \else\ifnum\appendixno=`R R% - \else\ifnum\appendixno=`S S% - \else\ifnum\appendixno=`T T% - \else\ifnum\appendixno=`U U% - \else\ifnum\appendixno=`V V% - \else\ifnum\appendixno=`W W% - \else\ifnum\appendixno=`X X% - \else\ifnum\appendixno=`Y Y% - \else\ifnum\appendixno=`Z Z% - % The \the is necessary, despite appearances, because \appendixletter is - % expanded while writing the .toc file. \char\appendixno is not - % expandable, thus it is written literally, thus all appendixes come out - % with the same letter (or @) in the toc without it. - \else\char\the\appendixno - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} - -% Each @chapter defines this as the name of the chapter. -% page headings and footings can use it. @section does likewise. -\def\thischapter{} -\def\thissection{} - -\newcount\absseclevel % used to calculate proper heading level -\newcount\secbase\secbase=0 % @raise/lowersections modify this count - -% @raisesections: treat @section as chapter, @subsection as section, etc. -\def\raisesections{\global\advance\secbase by -1} -\let\up=\raisesections % original BFox name - -% @lowersections: treat @chapter as section, @section as subsection, etc. -\def\lowersections{\global\advance\secbase by 1} -\let\down=\lowersections % original BFox name - -% Choose a numbered-heading macro -% #1 is heading level if unmodified by @raisesections or @lowersections -% #2 is text for heading -\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 -\ifcase\absseclevel - \chapterzzz{#2} -\or - \seczzz{#2} -\or - \numberedsubseczzz{#2} -\or - \numberedsubsubseczzz{#2} -\else - \ifnum \absseclevel<0 - \chapterzzz{#2} - \else - \numberedsubsubseczzz{#2} - \fi -\fi -\suppressfirstparagraphindent -} - -% like \numhead, but chooses appendix heading levels -\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 -\ifcase\absseclevel - \appendixzzz{#2} -\or - \appendixsectionzzz{#2} -\or - \appendixsubseczzz{#2} -\or - \appendixsubsubseczzz{#2} -\else - \ifnum \absseclevel<0 - \appendixzzz{#2} - \else - \appendixsubsubseczzz{#2} - \fi -\fi -\suppressfirstparagraphindent -} - -% like \numhead, but chooses numberless heading levels -\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 -\ifcase\absseclevel - \unnumberedzzz{#2} -\or - \unnumberedseczzz{#2} -\or - \unnumberedsubseczzz{#2} -\or - \unnumberedsubsubseczzz{#2} -\else - \ifnum \absseclevel<0 - \unnumberedzzz{#2} - \else - \unnumberedsubsubseczzz{#2} - \fi -\fi -\suppressfirstparagraphindent -} - -% @chapter, @appendix, @unnumbered. -\def\thischaptername{No Chapter Title} -\outer\def\chapter{\parsearg\chapteryyy} -\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz -\def\chapterzzz #1{% - \secno=0 \subsecno=0 \subsubsecno=0 - \global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% - \chapmacro {#1}{\the\chapno}% - \gdef\thissection{#1}% - \gdef\thischaptername{#1}% - % We don't substitute the actual chapter name into \thischapter - % because we don't want its macros evaluated now. - \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% - \writetocentry{chap}{#1}{{\the\chapno}} - \donoderef - \global\let\section = \numberedsec - \global\let\subsection = \numberedsubsec - \global\let\subsubsection = \numberedsubsubsec -} - -% we use \chapno to avoid indenting back -\def\appendixbox#1{% - \setbox0 = \hbox{\putwordAppendix{} \the\chapno}% - \hbox to \wd0{#1\hss}} - -\outer\def\appendix{\parsearg\appendixyyy} -\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz -\def\appendixzzz #1{% - \secno=0 \subsecno=0 \subsubsecno=0 - \global\advance \appendixno by 1 - \message{\putwordAppendix\space \appendixletter}% - \chapmacro {#1}{\appendixbox{\putwordAppendix{} \appendixletter}}% - \gdef\thissection{#1}% - \gdef\thischaptername{#1}% - \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% - \writetocentry{appendix}{#1}{{\appendixletter}} - \appendixnoderef - \global\let\section = \appendixsec - \global\let\subsection = \appendixsubsec - \global\let\subsubsection = \appendixsubsubsec -} - -% @centerchap is like @unnumbered, but the heading is centered. -\outer\def\centerchap{\parsearg\centerchapyyy} -\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} - -% @top is like @unnumbered. -\outer\def\top{\parsearg\unnumberedyyy} - -\outer\def\unnumbered{\parsearg\unnumberedyyy} -\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz -\def\unnumberedzzz #1{% - \secno=0 \subsecno=0 \subsubsecno=0 - % - % This used to be simply \message{#1}, but TeX fully expands the - % argument to \message. Therefore, if #1 contained @-commands, TeX - % expanded them. For example, in `@unnumbered The @cite{Book}', TeX - % expanded @cite (which turns out to cause errors because \cite is meant - % to be executed, not expanded). - % - % Anyway, we don't want the fully-expanded definition of @cite to appear - % as a result of the \message, we just want `@cite' itself. We use - % \the<toks register> to achieve this: TeX expands \the<toks> only once, - % simply yielding the contents of <toks register>. (We also do this for - % the toc entries.) - \toks0 = {#1}\message{(\the\toks0)}% - % - \unnumbchapmacro {#1}% - \gdef\thischapter{#1}\gdef\thissection{#1}% - \writetocentry{unnumbchap}{#1}{{\the\chapno}} - \unnumbnoderef - \global\let\section = \unnumberedsec - \global\let\subsection = \unnumberedsubsec - \global\let\subsubsection = \unnumberedsubsubsec -} - -% Sections. -\outer\def\numberedsec{\parsearg\secyyy} -\def\secyyy #1{\numhead1{#1}} % normally calls seczzz -\def\seczzz #1{% - \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % - \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% - \writetocentry{sec}{#1}{{\the\chapno}{\the\secno}} - \donoderef - \nobreak -} - -\outer\def\appendixsection{\parsearg\appendixsecyyy} -\outer\def\appendixsec{\parsearg\appendixsecyyy} -\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz -\def\appendixsectionzzz #1{% - \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % - \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% - \writetocentry{sec}{#1}{{\appendixletter}{\the\secno}} - \appendixnoderef - \nobreak -} - -\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} -\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz -\def\unnumberedseczzz #1{% - \plainsecheading {#1}\gdef\thissection{#1}% - \writetocentry{unnumbsec}{#1}{{\the\chapno}{\the\secno}} - \unnumbnoderef - \nobreak -} - -% Subsections. -\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} -\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz -\def\numberedsubseczzz #1{% - \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % - \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% - \writetocentry{subsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}} - \donoderef - \nobreak -} - -\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} -\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz -\def\appendixsubseczzz #1{% - \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % - \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% - \writetocentry{subsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}} - \appendixnoderef - \nobreak -} - -\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} -\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz -\def\unnumberedsubseczzz #1{% - \plainsubsecheading {#1}\gdef\thissection{#1}% - \writetocentry{unnumbsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}} - \unnumbnoderef - \nobreak -} - -% Subsubsections. -\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} -\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz -\def\numberedsubsubseczzz #1{% - \gdef\thissection{#1}\global\advance \subsubsecno by 1 % - \subsubsecheading {#1} - {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% - \writetocentry{subsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}} - \donoderef - \nobreak -} - -\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} -\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz -\def\appendixsubsubseczzz #1{% - \gdef\thissection{#1}\global\advance \subsubsecno by 1 % - \subsubsecheading {#1} - {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% - \writetocentry{subsubsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}} - \appendixnoderef - \nobreak -} - -\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} -\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz -\def\unnumberedsubsubseczzz #1{% - \plainsubsubsecheading {#1}\gdef\thissection{#1}% - \writetocentry{unnumbsubsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}} - \unnumbnoderef - \nobreak -} - -% These are variants which are not "outer", so they can appear in @ifinfo. -% Actually, they should now be obsolete; ordinary section commands should work. -\def\infotop{\parsearg\unnumberedzzz} -\def\infounnumbered{\parsearg\unnumberedzzz} -\def\infounnumberedsec{\parsearg\unnumberedseczzz} -\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} -\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} - -\def\infoappendix{\parsearg\appendixzzz} -\def\infoappendixsec{\parsearg\appendixseczzz} -\def\infoappendixsubsec{\parsearg\appendixsubseczzz} -\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} - -\def\infochapter{\parsearg\chapterzzz} -\def\infosection{\parsearg\sectionzzz} -\def\infosubsection{\parsearg\subsectionzzz} -\def\infosubsubsection{\parsearg\subsubsectionzzz} - -% These macros control what the section commands do, according -% to what kind of chapter we are in (ordinary, appendix, or unnumbered). -% Define them by default for a numbered chapter. -\global\let\section = \numberedsec -\global\let\subsection = \numberedsubsec -\global\let\subsubsection = \numberedsubsubsec - -% Define @majorheading, @heading and @subheading - -% NOTE on use of \vbox for chapter headings, section headings, and such: -% 1) We use \vbox rather than the earlier \line to permit -% overlong headings to fold. -% 2) \hyphenpenalty is set to 10000 because hyphenation in a -% heading is obnoxious; this forbids it. -% 3) Likewise, headings look best if no \parindent is used, and -% if justification is not attempted. Hence \raggedright. - - -\def\majorheading{\parsearg\majorheadingzzz} -\def\majorheadingzzz #1{% - {\advance\chapheadingskip by 10pt \chapbreak }% - {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\raggedright - \rm #1\hfill}}\bigskip \par\penalty 200} - -\def\chapheading{\parsearg\chapheadingzzz} -\def\chapheadingzzz #1{\chapbreak % - {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\raggedright - \rm #1\hfill}}\bigskip \par\penalty 200} - -% @heading, @subheading, @subsubheading. -\def\heading{\parsearg\plainsecheading} -\def\subheading{\parsearg\plainsubsecheading} -\def\subsubheading{\parsearg\plainsubsubsecheading} - -% These macros generate a chapter, section, etc. heading only -% (including whitespace, linebreaking, etc. around it), -% given all the information in convenient, parsed form. - -%%% Args are the skip and penalty (usually negative) -\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} - -\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} - -%%% Define plain chapter starts, and page on/off switching for it -% Parameter controlling skip before chapter headings (if needed) - -\newskip\chapheadingskip - -\def\chapbreak{\dobreak \chapheadingskip {-4000}} -\def\chappager{\par\vfill\supereject} -\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} - -\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} - -\def\CHAPPAGoff{% -\global\let\contentsalignmacro = \chappager -\global\let\pchapsepmacro=\chapbreak -\global\let\pagealignmacro=\chappager} - -\def\CHAPPAGon{% -\global\let\contentsalignmacro = \chappager -\global\let\pchapsepmacro=\chappager -\global\let\pagealignmacro=\chappager -\global\def\HEADINGSon{\HEADINGSsingle}} - -\def\CHAPPAGodd{ -\global\let\contentsalignmacro = \chapoddpage -\global\let\pchapsepmacro=\chapoddpage -\global\let\pagealignmacro=\chapoddpage -\global\def\HEADINGSon{\HEADINGSdouble}} - -\CHAPPAGon - -\def\CHAPFplain{ -\global\let\chapmacro=\chfplain -\global\let\unnumbchapmacro=\unnchfplain -\global\let\centerchapmacro=\centerchfplain} - -% Plain chapter opening. -% #1 is the text, #2 the chapter number or empty if unnumbered. -\def\chfplain#1#2{% - \pchapsepmacro - {% - \chapfonts \rm - \def\chapnum{#2}% - \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% - \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright - \hangindent = \wd0 \centerparametersmaybe - \unhbox0 #1\par}% - }% - \nobreak\bigskip % no page break after a chapter title - \nobreak -} - -% Plain opening for unnumbered. -\def\unnchfplain#1{\chfplain{#1}{}} - -% @centerchap -- centered and unnumbered. -\let\centerparametersmaybe = \relax -\def\centerchfplain#1{{% - \def\centerparametersmaybe{% - \advance\rightskip by 3\rightskip - \leftskip = \rightskip - \parfillskip = 0pt - }% - \chfplain{#1}{}% -}} - -\CHAPFplain % The default - -\def\unnchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\raggedright - \rm #1\hfill}}\bigskip \par\nobreak -} - -\def\chfopen #1#2{\chapoddpage {\chapfonts -\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% -\par\penalty 5000 % -} - -\def\centerchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt - \hfill {\rm #1}\hfill}}\bigskip \par\nobreak -} - -\def\CHAPFopen{ -\global\let\chapmacro=\chfopen -\global\let\unnumbchapmacro=\unnchfopen -\global\let\centerchapmacro=\centerchfopen} - - -% Section titles. -\newskip\secheadingskip -\def\secheadingbreak{\dobreak \secheadingskip {-1000}} -\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} -\def\plainsecheading#1{\sectionheading{sec}{}{#1}} - -% Subsection titles. -\newskip \subsecheadingskip -\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} -\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} -\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} - -% Subsubsection titles. -\let\subsubsecheadingskip = \subsecheadingskip -\let\subsubsecheadingbreak = \subsecheadingbreak -\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} -\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} - - -% Print any size section title. -% -% #1 is the section type (sec/subsec/subsubsec), #2 is the section -% number (maybe empty), #3 the text. -\def\sectionheading#1#2#3{% - {% - \expandafter\advance\csname #1headingskip\endcsname by \parskip - \csname #1headingbreak\endcsname - }% - {% - % Switch to the right set of fonts. - \csname #1fonts\endcsname \rm - % - % Only insert the separating space if we have a section number. - \def\secnum{#2}% - \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% - % - \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright - \hangindent = \wd0 % zero if no section number - \unhbox0 #3}% - }% - % Add extra space after the heading -- either a line space or a - % paragraph space, whichever is more. (Some people like to set - % \parskip to large values for some reason.) Don't allow stretch, though. - \nobreak - \ifdim\parskip>\normalbaselineskip - \kern\parskip - \else - \kern\normalbaselineskip - \fi - \nobreak -} - - -\message{toc,} -% Table of contents. -\newwrite\tocfile - -% Write an entry to the toc file, opening it if necessary. -% Called from @chapter, etc. We supply {\folio} at the end of the -% argument, which will end up as the last argument to the \...entry macro. -% -% Usage: \writetocentry{chap}{The Name of The Game}{{\the\chapno}} -% We open the .toc file for writing here instead of at @setfilename (or -% any other fixed time) so that @contents can be anywhere in the document. -% -\newif\iftocfileopened -\def\writetocentry#1#2#3{% - \iftocfileopened\else - \immediate\openout\tocfile = \jobname.toc - \global\tocfileopenedtrue - \fi - % - \iflinks - \toks0 = {#2}% - \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}#3{\folio}}}% - \temp - \fi - % - % Tell \shipout to create a page destination if we're doing pdf, which - % will be the target of the links in the table of contents. We can't - % just do it on every page because the title pages are numbered 1 and - % 2 (the page numbers aren't printed), and so are the first two pages - % of the document. Thus, we'd have two destinations named `1', and - % two named `2'. - \ifpdf \pdfmakepagedesttrue \fi -} - -\newskip\contentsrightmargin \contentsrightmargin=1in -\newcount\savepageno -\newcount\lastnegativepageno \lastnegativepageno = -1 - -% Finish up the main text and prepare to read what we've written -% to \tocfile. -% -\def\startcontents#1{% - % If @setchapternewpage on, and @headings double, the contents should - % start on an odd page, unlike chapters. Thus, we maintain - % \contentsalignmacro in parallel with \pagealignmacro. - % From: Torbjorn Granlund <tege@matematik.su.se> - \contentsalignmacro - \immediate\closeout\tocfile - % - % Don't need to put `Contents' or `Short Contents' in the headline. - % It is abundantly clear what they are. - \unnumbchapmacro{#1}\def\thischapter{}% - \savepageno = \pageno - \begingroup % Set up to handle contents files properly. - \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 - % We can't do this, because then an actual ^ in a section - % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. - %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi - \raggedbottom % Worry more about breakpoints than the bottom. - \advance\hsize by -\contentsrightmargin % Don't use the full line length. - % - % Roman numerals for page numbers. - \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi -} - - -% Normal (long) toc. -\def\contents{% - \startcontents{\putwordTOC}% - \openin 1 \jobname.toc - \ifeof 1 \else - \closein 1 - \input \jobname.toc - \fi - \vfill \eject - \contentsalignmacro % in case @setchapternewpage odd is in effect - \pdfmakeoutlines - \endgroup - \lastnegativepageno = \pageno - \global\pageno = \savepageno -} - -% And just the chapters. -\def\summarycontents{% - \startcontents{\putwordShortTOC}% - % - \let\chapentry = \shortchapentry - \let\appendixentry = \shortappendixentry - \let\unnumbchapentry = \shortunnumberedentry - % We want a true roman here for the page numbers. - \secfonts - \let\rm=\shortcontrm \let\bf=\shortcontbf - \let\sl=\shortcontsl \let\tt=\shortconttt - \rm - \hyphenpenalty = 10000 - \advance\baselineskip by 1pt % Open it up a little. - \def\secentry ##1##2##3##4{} - \def\subsecentry ##1##2##3##4##5{} - \def\subsubsecentry ##1##2##3##4##5##6{} - \let\unnumbsecentry = \secentry - \let\unnumbsubsecentry = \subsecentry - \let\unnumbsubsubsecentry = \subsubsecentry - \openin 1 \jobname.toc - \ifeof 1 \else - \closein 1 - \input \jobname.toc - \fi - \vfill \eject - \contentsalignmacro % in case @setchapternewpage odd is in effect - \endgroup - \lastnegativepageno = \pageno - \global\pageno = \savepageno -} -\let\shortcontents = \summarycontents - -\ifpdf - \pdfcatalog{/PageMode /UseOutlines}% -\fi - -% These macros generate individual entries in the table of contents. -% The first argument is the chapter or section name. -% The last argument is the page number. -% The arguments in between are the chapter number, section number, ... - -% Chapters, in the main contents. -\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} -% -% Chapters, in the short toc. -% See comments in \dochapentry re vbox and related settings. -\def\shortchapentry#1#2#3{% - \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}% -} - -% Appendices, in the main contents. -\def\appendixentry#1#2#3{% - \dochapentry{\appendixbox{\putwordAppendix{} #2}\labelspace#1}{#3}} -% -% Appendices, in the short toc. -\let\shortappendixentry = \shortchapentry - -% Typeset the label for a chapter or appendix for the short contents. -% The arg is, e.g., `Appendix A' for an appendix, or `3' for a chapter. -% We could simplify the code here by writing out an \appendixentry -% command in the toc file for appendices, instead of using \chapentry -% for both, but it doesn't seem worth it. -% -\newdimen\shortappendixwidth -% -\def\shortchaplabel#1{% - % This space should be enough, since a single number is .5em, and the - % widest letter (M) is 1em, at least in the Computer Modern fonts. - % But use \hss just in case. - % (This space doesn't include the extra space that gets added after - % the label; that gets put in by \shortchapentry above.) - \dimen0 = 1em - \hbox to \dimen0{#1\hss}% -} - -% Unnumbered chapters. -\def\unnumbchapentry#1#2#3{\dochapentry{#1}{#3}} -\def\shortunnumberedentry#1#2#3{\tocentry{#1}{\doshortpageno\bgroup#3\egroup}} - -% Sections. -\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} -\def\unnumbsecentry#1#2#3#4{\dosecentry{#1}{#4}} - -% Subsections. -\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} -\def\unnumbsubsecentry#1#2#3#4#5{\dosubsecentry{#1}{#5}} - -% And subsubsections. -\def\subsubsecentry#1#2#3#4#5#6{% - \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} -\def\unnumbsubsubsecentry#1#2#3#4#5#6{\dosubsubsecentry{#1}{#6}} - -% This parameter controls the indentation of the various levels. -\newdimen\tocindent \tocindent = 3pc - -% Now for the actual typesetting. In all these, #1 is the text and #2 is the -% page number. -% -% If the toc has to be broken over pages, we want it to be at chapters -% if at all possible; hence the \penalty. -\def\dochapentry#1#2{% - \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip - \begingroup - \chapentryfonts - \tocentry{#1}{\dopageno\bgroup#2\egroup}% - \endgroup - \nobreak\vskip .25\baselineskip plus.1\baselineskip -} - -\def\dosecentry#1#2{\begingroup - \secentryfonts \leftskip=\tocindent - \tocentry{#1}{\dopageno\bgroup#2\egroup}% -\endgroup} - -\def\dosubsecentry#1#2{\begingroup - \subsecentryfonts \leftskip=2\tocindent - \tocentry{#1}{\dopageno\bgroup#2\egroup}% -\endgroup} - -\def\dosubsubsecentry#1#2{\begingroup - \subsubsecentryfonts \leftskip=3\tocindent - \tocentry{#1}{\dopageno\bgroup#2\egroup}% -\endgroup} - -% Final typesetting of a toc entry; we use the same \entry macro as for -% the index entries, but we want to suppress hyphenation here. (We -% can't do that in the \entry macro, since index entries might consist -% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) -\def\tocentry#1#2{\begingroup - \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks - % Do not use \turnoffactive in these arguments. Since the toc is - % typeset in cmr, characters such as _ would come out wrong; we - % have to do the usual translation tricks. - \entry{#1}{#2}% -\endgroup} - -% Space between chapter (or whatever) number and the title. -\def\labelspace{\hskip1em \relax} - -\def\dopageno#1{{\rm #1}} -\def\doshortpageno#1{{\rm #1}} - -\def\chapentryfonts{\secfonts \rm} -\def\secentryfonts{\textfonts} -\let\subsecentryfonts = \textfonts -\let\subsubsecentryfonts = \textfonts - - -\message{environments,} -% @foo ... @end foo. - -% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. -% -% Since these characters are used in examples, it should be an even number of -% \tt widths. Each \tt character is 1en, so two makes it 1em. -% -\def\point{$\star$} -\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} -\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} -\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} -\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} - -% The @error{} command. -% Adapted from the TeXbook's \boxit. -% -\newbox\errorbox -% -{\tentt \global\dimen0 = 3em}% Width of the box. -\dimen2 = .55pt % Thickness of rules -% The text. (`r' is open on the right, `e' somewhat less so on the left.) -\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} -% -\global\setbox\errorbox=\hbox to \dimen0{\hfil - \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. - \advance\hsize by -2\dimen2 % Rules. - \vbox{ - \hrule height\dimen2 - \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. - \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. - \kern3pt\vrule width\dimen2}% Space to right. - \hrule height\dimen2} - \hfil} -% -\def\error{\leavevmode\lower.7ex\copy\errorbox} - -% @tex ... @end tex escapes into raw Tex temporarily. -% One exception: @ is still an escape character, so that @end tex works. -% But \@ or @@ will get a plain tex @ character. - -\def\tex{\begingroup - \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 - \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 - \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie - \catcode `\%=14 - \catcode `\+=\other - \catcode `\"=\other - \catcode `\==\other - \catcode `\|=\other - \catcode `\<=\other - \catcode `\>=\other - \escapechar=`\\ - % - \let\b=\ptexb - \let\bullet=\ptexbullet - \let\c=\ptexc - \let\,=\ptexcomma - \let\.=\ptexdot - \let\dots=\ptexdots - \let\equiv=\ptexequiv - \let\!=\ptexexclam - \let\i=\ptexi - \let\indent=\ptexindent - \let\{=\ptexlbrace - \let\+=\tabalign - \let\}=\ptexrbrace - \let\/=\ptexslash - \let\*=\ptexstar - \let\t=\ptext - % - \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% - \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% - \def\@{@}% -\let\Etex=\endgroup} - -% Define @lisp ... @end lisp. -% @lisp does a \begingroup so it can rebind things, -% including the definition of @end lisp (which normally is erroneous). - -% Amount to narrow the margins by for @lisp. -\newskip\lispnarrowing \lispnarrowing=0.4in - -% This is the definition that ^^M gets inside @lisp, @example, and other -% such environments. \null is better than a space, since it doesn't -% have any width. -\def\lisppar{\null\endgraf} - -% Make each space character in the input produce a normal interword -% space in the output. Don't allow a line break at this space, as this -% is used only in environments like @example, where each line of input -% should produce a line of output anyway. -% -{\obeyspaces % -\gdef\sepspaces{\obeyspaces\let =\tie}} - -% Define \obeyedspace to be our active space, whatever it is. This is -% for use in \parsearg. -{\sepspaces% -\global\let\obeyedspace= } - -% This space is always present above and below environments. -\newskip\envskipamount \envskipamount = 0pt - -% Make spacing and below environment symmetrical. We use \parskip here -% to help in doing that, since in @example-like environments \parskip -% is reset to zero; thus the \afterenvbreak inserts no space -- but the -% start of the next paragraph will insert \parskip. -% -\def\aboveenvbreak{{% - % =10000 instead of <10000 because of a special case in \itemzzz, q.v. - \ifnum \lastpenalty=10000 \else - \advance\envskipamount by \parskip - \endgraf - \ifdim\lastskip<\envskipamount - \removelastskip - % it's not a good place to break if the last penalty was \nobreak - % or better ... - \ifnum\lastpenalty>10000 \else \penalty-50 \fi - \vskip\envskipamount - \fi - \fi -}} - -\let\afterenvbreak = \aboveenvbreak - -% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. -\let\nonarrowing=\relax - -% @cartouche ... @end cartouche: draw rectangle w/rounded corners around -% environment contents. -\font\circle=lcircle10 -\newdimen\circthick -\newdimen\cartouter\newdimen\cartinner -\newskip\normbskip\newskip\normpskip\newskip\normlskip -\circthick=\fontdimen8\circle -% -\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth -\def\ctr{{\hskip 6pt\circle\char'010}} -\def\cbl{{\circle\char'012\hskip -6pt}} -\def\cbr{{\hskip 6pt\circle\char'011}} -\def\carttop{\hbox to \cartouter{\hskip\lskip - \ctl\leaders\hrule height\circthick\hfil\ctr - \hskip\rskip}} -\def\cartbot{\hbox to \cartouter{\hskip\lskip - \cbl\leaders\hrule height\circthick\hfil\cbr - \hskip\rskip}} -% -\newskip\lskip\newskip\rskip - -\def\cartouche{% -\par % can't be in the midst of a paragraph. -\begingroup - \lskip=\leftskip \rskip=\rightskip - \leftskip=0pt\rightskip=0pt %we want these *outside*. - \cartinner=\hsize \advance\cartinner by-\lskip - \advance\cartinner by-\rskip - \cartouter=\hsize - \advance\cartouter by 18.4pt % allow for 3pt kerns on either -% side, and for 6pt waste from -% each corner char, and rule thickness - \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip - % Flag to tell @lisp, etc., not to narrow margin. - \let\nonarrowing=\comment - \vbox\bgroup - \baselineskip=0pt\parskip=0pt\lineskip=0pt - \carttop - \hbox\bgroup - \hskip\lskip - \vrule\kern3pt - \vbox\bgroup - \hsize=\cartinner - \kern3pt - \begingroup - \baselineskip=\normbskip - \lineskip=\normlskip - \parskip=\normpskip - \vskip -\parskip -\def\Ecartouche{% - \endgroup - \kern3pt - \egroup - \kern3pt\vrule - \hskip\rskip - \egroup - \cartbot - \egroup -\endgroup -}} - - -% This macro is called at the beginning of all the @example variants, -% inside a group. -\def\nonfillstart{% - \aboveenvbreak - \inENV % This group ends at the end of the body - \hfuzz = 12pt % Don't be fussy - \sepspaces % Make spaces be word-separators rather than space tokens. - \let\par = \lisppar % don't ignore blank lines - \obeylines % each line of input is a line of output - \parskip = 0pt - \parindent = 0pt - \emergencystretch = 0pt % don't try to avoid overfull boxes - % @cartouche defines \nonarrowing to inhibit narrowing - % at next level down. - \ifx\nonarrowing\relax - \advance \leftskip by \lispnarrowing - \exdentamount=\lispnarrowing - \let\exdent=\nofillexdent - \let\nonarrowing=\relax - \fi -} - -% Define the \E... control sequence only if we are inside the particular -% environment, so the error checking in \end will work. -% -% To end an @example-like environment, we first end the paragraph (via -% \afterenvbreak's vertical glue), and then the group. That way we keep -% the zero \parskip that the environments set -- \parskip glue will be -% inserted at the beginning of the next paragraph in the document, after -% the environment. -% -\def\nonfillfinish{\afterenvbreak\endgroup} - -% @lisp: indented, narrowed, typewriter font. -\def\lisp{\begingroup - \nonfillstart - \let\Elisp = \nonfillfinish - \tt - \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. - \gobble % eat return -} - -% @example: Same as @lisp. -\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} - -% @smallexample and @smalllisp: use smaller fonts. -% Originally contributed by Pavel@xerox. -\def\smalllisp{\begingroup - \def\Esmalllisp{\nonfillfinish\endgroup}% - \def\Esmallexample{\nonfillfinish\endgroup}% - \smallexamplefonts - \lisp -} -\let\smallexample = \smalllisp - - -% @display: same as @lisp except keep current font. -% -\def\display{\begingroup - \nonfillstart - \let\Edisplay = \nonfillfinish - \gobble -} -% -% @smalldisplay: @display plus smaller fonts. -% -\def\smalldisplay{\begingroup - \def\Esmalldisplay{\nonfillfinish\endgroup}% - \smallexamplefonts \rm - \display -} - -% @format: same as @display except don't narrow margins. -% -\def\format{\begingroup - \let\nonarrowing = t - \nonfillstart - \let\Eformat = \nonfillfinish - \gobble -} -% -% @smallformat: @format plus smaller fonts. -% -\def\smallformat{\begingroup - \def\Esmallformat{\nonfillfinish\endgroup}% - \smallexamplefonts \rm - \format -} - -% @flushleft (same as @format). -% -\def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} - -% @flushright. -% -\def\flushright{\begingroup - \let\nonarrowing = t - \nonfillstart - \let\Eflushright = \nonfillfinish - \advance\leftskip by 0pt plus 1fill - \gobble -} - - -% @quotation does normal linebreaking (hence we can't use \nonfillstart) -% and narrows the margins. -% -\def\quotation{% - \begingroup\inENV %This group ends at the end of the @quotation body - {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip - \parindent=0pt - % We have retained a nonzero parskip for the environment, since we're - % doing normal filling. So to avoid extra space below the environment... - \def\Equotation{\parskip = 0pt \nonfillfinish}% - % - % @cartouche defines \nonarrowing to inhibit narrowing at next level down. - \ifx\nonarrowing\relax - \advance\leftskip by \lispnarrowing - \advance\rightskip by \lispnarrowing - \exdentamount = \lispnarrowing - \let\nonarrowing = \relax - \fi -} - - -% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>} -% If we want to allow any <char> as delimiter, -% we need the curly braces so that makeinfo sees the @verb command, eg: -% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org -% -% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. -% -% [Knuth] p.344; only we need to do the other characters Texinfo sets -% active too. Otherwise, they get lost as the first character on a -% verbatim line. -\def\dospecials{% - \do\ \do\\\do\{\do\}\do\$\do\&% - \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% - \do\<\do\>\do\|\do\@\do+\do\"% -} -% -% [Knuth] p. 380 -\def\uncatcodespecials{% - \def\do##1{\catcode`##1=12}\dospecials} -% -% [Knuth] pp. 380,381,391 -% Disable Spanish ligatures ?` and !` of \tt font -\begingroup - \catcode`\`=\active\gdef`{\relax\lq} -\endgroup -% -% Setup for the @verb command. -% -% Eight spaces for a tab -\begingroup - \catcode`\^^I=\active - \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} -\endgroup -% -\def\setupverb{% - \tt % easiest (and conventionally used) font for verbatim - \def\par{\leavevmode\endgraf}% - \catcode`\`=\active - \tabeightspaces - % Respect line breaks, - % print special symbols as themselves, and - % make each space count - % must do in this order: - \obeylines \uncatcodespecials \sepspaces -} - -% Setup for the @verbatim environment -% -% Real tab expansion -\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount -% -\def\starttabbox{\setbox0=\hbox\bgroup} -\begingroup - \catcode`\^^I=\active - \gdef\tabexpand{% - \catcode`\^^I=\active - \def^^I{\leavevmode\egroup - \dimen0=\wd0 % the width so far, or since the previous tab - \divide\dimen0 by\tabw - \multiply\dimen0 by\tabw % compute previous multiple of \tabw - \advance\dimen0 by\tabw % advance to next multiple of \tabw - \wd0=\dimen0 \box0 \starttabbox - }% - } -\endgroup -\def\setupverbatim{% - % Easiest (and conventionally used) font for verbatim - \tt - \def\par{\leavevmode\egroup\box0\endgraf}% - \catcode`\`=\active - \tabexpand - % Respect line breaks, - % print special symbols as themselves, and - % make each space count - % must do in this order: - \obeylines \uncatcodespecials \sepspaces - \everypar{\starttabbox}% -} - -% Do the @verb magic: verbatim text is quoted by unique -% delimiter characters. Before first delimiter expect a -% right brace, after last delimiter expect closing brace: -% -% \def\doverb'{'<char>#1<char>'}'{#1} -% -% [Knuth] p. 382; only eat outer {} -\begingroup - \catcode`[=1\catcode`]=2\catcode`\{=12\catcode`\}=12 - \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] -\endgroup -% -\def\verb{\begingroup\setupverb\doverb} -% -% -% Do the @verbatim magic: define the macro \doverbatim so that -% the (first) argument ends when '@end verbatim' is reached, ie: -% -% \def\doverbatim#1@end verbatim{#1} -% -% For Texinfo it's a lot easier than for LaTeX, -% because texinfo's \verbatim doesn't stop at '\end{verbatim}': -% we need not redefine '\', '{' and '}'. -% -% Inspired by LaTeX's verbatim command set [latex.ltx] -%% Include LaTeX hack for completeness -- never know -%% \begingroup -%% \catcode`|=0 \catcode`[=1 -%% \catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\ =\active -%% \catcode`\\=12|gdef|doverbatim#1@end verbatim[ -%% #1|endgroup|def|Everbatim[]|end[verbatim]] -%% |endgroup -% -\begingroup - \catcode`\ =\active - \obeylines % - % ignore everything up to the first ^^M, that's the newline at the end - % of the @verbatim input line itself. Otherwise we get an extra blank - % line in the output. - \gdef\doverbatim#1^^M#2@end verbatim{#2\end{verbatim}}% -\endgroup -% -\def\verbatim{% - \def\Everbatim{\nonfillfinish\endgroup}% - \begingroup - \nonfillstart - \advance\leftskip by -\defbodyindent - \begingroup\setupverbatim\doverbatim -} - -% @verbatiminclude FILE - insert text of file in verbatim environment. -% -% Allow normal characters that we make active in the argument (a file name). -\def\verbatiminclude{% - \begingroup - \catcode`\\=\other - \catcode`~=\other - \catcode`^=\other - \catcode`_=\other - \catcode`|=\other - \catcode`<=\other - \catcode`>=\other - \catcode`+=\other - \parsearg\doverbatiminclude -} -\def\setupverbatiminclude{% - \begingroup - \nonfillstart - \advance\leftskip by -\defbodyindent - \begingroup\setupverbatim -} -% -\def\doverbatiminclude#1{% - % Restore active chars for included file. - \endgroup - \begingroup - \let\value=\expandablevalue - \def\thisfile{#1}% - \expandafter\expandafter\setupverbatiminclude\input\thisfile - \endgroup - \nonfillfinish - \endgroup -} - -% @copying ... @end copying. -% Save the text away for @insertcopying later. Many commands won't be -% allowed in this context, but that's ok. -% -% We save the uninterpreted tokens, rather than creating a box. -% Saving the text in a box would be much easier, but then all the -% typesetting commands (@smallbook, font changes, etc.) have to be done -% beforehand -- and a) we want @copying to be done first in the source -% file; b) letting users define the frontmatter in as flexible order as -% possible is very desirable. -% -\def\copying{\begingroup - % Define a command to swallow text until we reach `@end copying'. - % \ is the escape char in this texinfo.tex file, so it is the - % delimiter for the command; @ will be the escape char when we read - % it, but that doesn't matter. - \long\def\docopying##1\end copying{\gdef\copyingtext{##1}\enddocopying}% - % - % We must preserve ^^M's in the input file; see \insertcopying below. - \catcode`\^^M = \active - \docopying -} - -% What we do to finish off the copying text. -% -\def\enddocopying{\endgroup\ignorespaces} - -% @insertcopying. Here we must play games with ^^M's. On the one hand, -% we need them to delimit commands such as `@end quotation', so they -% must be active. On the other hand, we certainly don't want every -% end-of-line to be a \par, as would happen with the normal active -% definition of ^^M. On the third hand, two ^^M's in a row should still -% generate a \par. -% -% Our approach is to make ^^M insert a space and a penalty1 normally; -% then it can also check if \lastpenalty=1. If it does, then manually -% do \par. -% -% This messes up the normal definitions of @c[omment], so we redefine -% it. Similarly for @ignore. (These commands are used in the gcc -% manual for man page generation.) -% -% Seems pretty fragile, most line-oriented commands will presumably -% fail, but for the limited use of getting the copying text (which -% should be quite simple) inserted, we can hope it's ok. -% -{\catcode`\^^M=\active % -\gdef\insertcopying{\begingroup % - \parindent = 0pt % looks wrong on title page - \def^^M{% - \ifnum \lastpenalty=1 % - \par % - \else % - \space \penalty 1 % - \fi % - }% - % - % Fix @c[omment] for catcode 13 ^^M's. - \def\c##1^^M{\ignorespaces}% - \let\comment = \c % - % - % Don't bother jumping through all the hoops that \doignore does, it - % would be very hard since the catcodes are already set. - \long\def\ignore##1\end ignore{\ignorespaces}% - % - \copyingtext % -\endgroup}% -} - -\message{defuns,} -% @defun etc. - -% Allow user to change definition object font (\df) internally -\def\setdeffont#1 {\csname DEF#1\endcsname} - -\newskip\defbodyindent \defbodyindent=.4in -\newskip\defargsindent \defargsindent=50pt -\newskip\deflastargmargin \deflastargmargin=18pt - -\newcount\parencount - -% We want ()&[] to print specially on the defun line. -% -\def\activeparens{% - \catcode`\(=\active \catcode`\)=\active - \catcode`\&=\active - \catcode`\[=\active \catcode`\]=\active -} - -% Make control sequences which act like normal parenthesis chars. -\let\lparen = ( \let\rparen = ) - -{\activeparens % Now, smart parens don't turn on until &foo (see \amprm) - -% Be sure that we always have a definition for `(', etc. For example, -% if the fn name has parens in it, \boldbrax will not be in effect yet, -% so TeX would otherwise complain about undefined control sequence. -\global\let(=\lparen \global\let)=\rparen -\global\let[=\lbrack \global\let]=\rbrack - -\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } -\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} -% This is used to turn on special parens -% but make & act ordinary (given that it's active). -\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} - -% Definitions of (, ) and & used in args for functions. -% This is the definition of ( outside of all parentheses. -\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested - \global\advance\parencount by 1 -} -% -% This is the definition of ( when already inside a level of parens. -\gdef\opnested{\char`\(\global\advance\parencount by 1 } -% -\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. - % also in that case restore the outer-level definition of (. - \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi - \global\advance \parencount by -1 } -% If we encounter &foo, then turn on ()-hacking afterwards -\gdef\amprm#1 {{\rm\&#1}\let(=\oprm \let)=\clrm\ } -% -\gdef\normalparens{\boldbrax\let&=\ampnr} -} % End of definition inside \activeparens -%% These parens (in \boldbrax) actually are a little bolder than the -%% contained text. This is especially needed for [ and ] -\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } -\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } -\let\ampnr = \& -\def\lbrb{{\bf\char`\[}} -\def\rbrb{{\bf\char`\]}} - -% Active &'s sneak into the index arguments, so make sure it's defined. -{ - \catcode`& = \active - \global\let& = \ampnr -} - -% \defname, which formats the name of the @def (not the args). -% #1 is the function name. -% #2 is the type of definition, such as "Function". -% -\def\defname#1#2{% - % How we'll output the type name. Putting it in brackets helps - % distinguish it from the body text that may end up on the next line - % just below it. - \ifempty{#2}% - \def\defnametype{}% - \else - \def\defnametype{[\rm #2]}% - \fi - % - % Get the values of \leftskip and \rightskip as they were outside the @def... - \dimen2=\leftskip - \advance\dimen2 by -\defbodyindent - % - % Figure out values for the paragraph shape. - \setbox0=\hbox{\hskip \deflastargmargin{\defnametype}}% - \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line - \dimen1=\hsize \advance \dimen1 by -\defargsindent % size for continuations - \parshape 2 0in \dimen0 \defargsindent \dimen1 - % - % Output arg 2 ("Function" or some such) but stuck inside a box of - % width 0 so it does not interfere with linebreaking. - \noindent - % - {% Adjust \hsize to exclude the ambient margins, - % so that \rightline will obey them. - \advance \hsize by -\dimen2 - \dimen3 = 0pt % was -1.25pc - \rlap{\rightline{\defnametype\kern\dimen3}}% - }% - % - % Allow all lines to be underfull without complaint: - \tolerance=10000 \hbadness=10000 - \advance\leftskip by -\defbodyindent - \exdentamount=\defbodyindent - {\df #1}\enskip % output function name - % \defunargs will be called next to output the arguments, if any. -} - -% Common pieces to start any @def... -% #1 is the \E... control sequence to end the definition (which we define). -% #2 is the \...x control sequence (which our caller defines). -% #3 is the control sequence to process the header, such as \defunheader. -% -\def\parsebodycommon#1#2#3{% - \begingroup\inENV - % If there are two @def commands in a row, we'll have a \nobreak, - % which is there to keep the function description together with its - % header. But if there's nothing but headers, we want to allow a - % break after all. Check for penalty 10002 (inserted by - % \defargscommonending) instead of 10000, since the sectioning - % commands insert a \penalty10000, and we don't want to allow a break - % between a section heading and a defun. - \ifnum\lastpenalty=10002 \penalty0 \fi - \medbreak - % - % Define the \E... end token that this defining construct specifies - % so that it will exit this group. - \def#1{\endgraf\endgroup\medbreak}% - % - \parindent=0in - \advance\leftskip by \defbodyindent - \exdentamount=\defbodyindent -} - -% Common part of the \...x definitions. -% -\def\defxbodycommon{% - % As with \parsebodycommon above, allow line break if we have multiple - % x headers in a row. It's not a great place, though. - \ifnum\lastpenalty=10000 \penalty1000 \fi - % - \begingroup\obeylines -} - -% Process body of @defun, @deffn, @defmac, etc. -% -\def\defparsebody#1#2#3{% - \parsebodycommon{#1}{#2}{#3}% - \def#2{\defxbodycommon \activeparens \spacesplit#3}% - \catcode\equalChar=\active - \begingroup\obeylines\activeparens - \spacesplit#3% -} - -% #1, #2, #3 are the common arguments (see \parsebodycommon above). -% #4, delimited by the space, is the class name. -% -\def\defmethparsebody#1#2#3#4 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 {\defxbodycommon \activeparens \spacesplit{#3{##1}}}% - \begingroup\obeylines\activeparens - % The \empty here prevents misinterpretation of a construct such as - % @deffn {whatever} {Enharmonic comma} - % See comments at \deftpparsebody, although in our case we don't have - % to remove the \empty afterwards, since it is empty. - \spacesplit{#3{#4}}\empty -} - -% Used for @deftypemethod and @deftypeivar. -% #1, #2, #3 are the common arguments (see \defparsebody). -% #4, delimited by a space, is the class name. -% #5 is the method's return type. -% -\def\deftypemethparsebody#1#2#3#4 #5 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 ##2 {\defxbodycommon \activeparens \spacesplit{#3{##1}{##2}}}% - \begingroup\obeylines\activeparens - \spacesplit{#3{#4}{#5}}% -} - -% Used for @deftypeop. The change from \deftypemethparsebody is an -% extra argument at the beginning which is the `category', instead of it -% being the hardwired string `Method' or `Instance Variable'. We have -% to account for this both in the \...x definition and in parsing the -% input at hand. Thus also need a control sequence (passed as #5) for -% the \E... definition to assign the category name to. -% -\def\deftypeopparsebody#1#2#3#4#5 #6 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 ##2 ##3 {\def#4{##1}% - \defxbodycommon \activeparens \spacesplit{#3{##2}{##3}}}% - \begingroup\obeylines\activeparens - \spacesplit{#3{#5}{#6}}% -} - -% For @defop. -\def\defopparsebody #1#2#3#4#5 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 ##2 {\def#4{##1}% - \defxbodycommon \activeparens \spacesplit{#3{##2}}}% - \begingroup\obeylines\activeparens - \spacesplit{#3{#5}}% -} - -% These parsing functions are similar to the preceding ones -% except that they do not make parens into active characters. -% These are used for "variables" since they have no arguments. -% -\def\defvarparsebody #1#2#3{% - \parsebodycommon{#1}{#2}{#3}% - \def#2{\defxbodycommon \spacesplit#3}% - \catcode\equalChar=\active - \begingroup\obeylines - \spacesplit#3% -} - -% @defopvar. -\def\defopvarparsebody #1#2#3#4#5 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 ##2 {\def#4{##1}% - \defxbodycommon \spacesplit{#3{##2}}}% - \begingroup\obeylines - \spacesplit{#3{#5}}% -} - -\def\defvrparsebody#1#2#3#4 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% - \begingroup\obeylines - \spacesplit{#3{#4}}% -} - -% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the -% type is just `struct', because we lose the braces in `{struct -% termios}' when \spacesplit reads its undelimited argument. Sigh. -% \let\deftpparsebody=\defvrparsebody -% -% So, to get around this, we put \empty in with the type name. That -% way, TeX won't find exactly `{...}' as an undelimited argument, and -% won't strip off the braces. -% -\def\deftpparsebody #1#2#3#4 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% - \begingroup\obeylines - \spacesplit{\parsetpheaderline{#3{#4}}}\empty -} - -% Fine, but then we have to eventually remove the \empty *and* the -% braces (if any). That's what this does. -% -\def\removeemptybraces\empty#1\relax{#1} - -% After \spacesplit has done its work, this is called -- #1 is the final -% thing to call, #2 the type name (which starts with \empty), and #3 -% (which might be empty) the arguments. -% -\def\parsetpheaderline#1#2#3{% - #1{\removeemptybraces#2\relax}{#3}% -}% - -% Split up #2 (the rest of the input line) at the first space token. -% call #1 with two arguments: -% the first is all of #2 before the space token, -% the second is all of #2 after that space token. -% If #2 contains no space token, all of it is passed as the first arg -% and the second is passed as empty. -% -{\obeylines % - \gdef\spacesplit#1#2^^M{\endgroup\spacesplitx{#1}#2 \relax\spacesplitx}% - \long\gdef\spacesplitx#1#2 #3#4\spacesplitx{% - \ifx\relax #3% - #1{#2}{}% - \else % - #1{#2}{#3#4}% - \fi}% -} - -% Define @defun. - -% This is called to end the arguments processing for all the @def... commands. -% -\def\defargscommonending{% - \interlinepenalty = 10000 - \advance\rightskip by 0pt plus 1fil - \endgraf - \nobreak\vskip -\parskip - \penalty 10002 % signal to \parsebodycommon. -} - -% This expands the args and terminates the paragraph they comprise. -% -\def\defunargs#1{\functionparens \sl -% Expand, preventing hyphenation at `-' chars. -% Note that groups don't affect changes in \hyphenchar. -% Set the font temporarily and use \font in case \setfont made \tensl a macro. -{\tensl\hyphenchar\font=0}% -#1% -{\tensl\hyphenchar\font=45}% -\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% - \defargscommonending -} - -\def\deftypefunargs #1{% -% Expand, preventing hyphenation at `-' chars. -% Note that groups don't affect changes in \hyphenchar. -% Use \boldbraxnoamp, not \functionparens, so that & is not special. -\boldbraxnoamp -\tclose{#1}% avoid \code because of side effects on active chars - \defargscommonending -} - -% Do complete processing of one @defun or @defunx line already parsed. - -% @deffn Command forward-char nchars - -\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} - -\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% -\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % -\catcode\equalChar=\other % Turn off change made in \defparsebody -} - -% @defun == @deffn Function - -\def\defun{\defparsebody\Edefun\defunx\defunheader} - -\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index -\begingroup\defname {#1}{\putwordDeffunc}% -\defunargs {#2}\endgroup % -\catcode\equalChar=\other % Turn off change made in \defparsebody -} - -% @deftypefun int foobar (int @var{foo}, float @var{bar}) - -\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} - -% #1 is the data type. #2 is the name and args. -\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} -% #1 is the data type, #2 the name, #3 the args. -\def\deftypefunheaderx #1#2 #3\relax{% -\doind {fn}{\code{#2}}% Make entry in function index -\begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypefun}% -\deftypefunargs {#3}\endgroup % -\catcode\equalChar=\other % Turn off change made in \defparsebody -} - -% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) - -\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} - -% \defheaderxcond#1\relax$.$ -% puts #1 in @code, followed by a space, but does nothing if #1 is null. -\def\defheaderxcond#1#2$.${\ifx#1\relax\else\code{#1#2} \fi} - -% #1 is the classification. #2 is the data type. #3 is the name and args. -\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} -% #1 is the classification, #2 the data type, #3 the name, #4 the args. -\def\deftypefnheaderx #1#2#3 #4\relax{% -\doind {fn}{\code{#3}}% Make entry in function index -\begingroup -\normalparens % notably, turn off `&' magic, which prevents -% at least some C++ text from working -\defname {\defheaderxcond#2\relax$.$#3}{#1}% -\deftypefunargs {#4}\endgroup % -\catcode\equalChar=\other % Turn off change made in \defparsebody -} - -% @defmac == @deffn Macro - -\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} - -\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index -\begingroup\defname {#1}{\putwordDefmac}% -\defunargs {#2}\endgroup % -\catcode\equalChar=\other % Turn off change made in \defparsebody -} - -% @defspec == @deffn Special Form - -\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} - -\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index -\begingroup\defname {#1}{\putwordDefspec}% -\defunargs {#2}\endgroup % -\catcode\equalChar=\other % Turn off change made in \defparsebody -} - -% @defop CATEGORY CLASS OPERATION ARG... -% -\def\defop #1 {\def\defoptype{#1}% -\defopparsebody\Edefop\defopx\defopheader\defoptype} -% -\def\defopheader#1#2#3{% - \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% function index entry - \begingroup - \defname{#2}{\defoptype\ \putwordon\ #1}% - \defunargs{#3}% - \endgroup -} - -% @deftypeop CATEGORY CLASS TYPE OPERATION ARG... -% -\def\deftypeop #1 {\def\deftypeopcategory{#1}% - \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader - \deftypeopcategory} -% -% #1 is the class name, #2 the data type, #3 the operation name, #4 the args. -\def\deftypeopheader#1#2#3#4{% - \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index - \begingroup - \defname{\defheaderxcond#2\relax$.$#3} - {\deftypeopcategory\ \putwordon\ \code{#1}}% - \deftypefunargs{#4}% - \endgroup -} - -% @deftypemethod CLASS TYPE METHOD ARG... -% -\def\deftypemethod{% - \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} -% -% #1 is the class name, #2 the data type, #3 the method name, #4 the args. -\def\deftypemethodheader#1#2#3#4{% - \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index - \begingroup - \defname{\defheaderxcond#2\relax$.$#3}{\putwordMethodon\ \code{#1}}% - \deftypefunargs{#4}% - \endgroup -} - -% @deftypeivar CLASS TYPE VARNAME -% -\def\deftypeivar{% - \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} -% -% #1 is the class name, #2 the data type, #3 the variable name. -\def\deftypeivarheader#1#2#3{% - \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index - \begingroup - \defname{\defheaderxcond#2\relax$.$#3} - {\putwordInstanceVariableof\ \code{#1}}% - \defvarargs{#3}% - \endgroup -} - -% @defmethod == @defop Method -% -\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} -% -% #1 is the class name, #2 the method name, #3 the args. -\def\defmethodheader#1#2#3{% - \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index - \begingroup - \defname{#2}{\putwordMethodon\ \code{#1}}% - \defunargs{#3}% - \endgroup -} - -% @defcv {Class Option} foo-class foo-flag - -\def\defcv #1 {\def\defcvtype{#1}% -\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} - -\def\defcvarheader #1#2#3{% - \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% variable index entry - \begingroup - \defname{#2}{\defcvtype\ \putwordof\ #1}% - \defvarargs{#3}% - \endgroup -} - -% @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME -% -\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} -% -\def\defivarheader#1#2#3{% - \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% entry in var index - \begingroup - \defname{#2}{\putwordInstanceVariableof\ #1}% - \defvarargs{#3}% - \endgroup -} - -% @defvar -% First, define the processing that is wanted for arguments of @defvar. -% This is actually simple: just print them in roman. -% This must expand the args and terminate the paragraph they make up -\def\defvarargs #1{\normalparens #1% - \defargscommonending -} - -% @defvr Counter foo-count - -\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} - -\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% -\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} - -% @defvar == @defvr Variable - -\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} - -\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index -\begingroup\defname {#1}{\putwordDefvar}% -\defvarargs {#2}\endgroup % -} - -% @defopt == @defvr {User Option} - -\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} - -\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index -\begingroup\defname {#1}{\putwordDefopt}% -\defvarargs {#2}\endgroup % -} - -% @deftypevar int foobar - -\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} - -% #1 is the data type. #2 is the name, perhaps followed by text that -% is actually part of the data type, which should not be put into the index. -\def\deftypevarheader #1#2{% -\dovarind#2 \relax% Make entry in variables index -\begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypevar}% - \defargscommonending -\endgroup} -\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} - -% @deftypevr {Global Flag} int enable - -\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} - -\def\deftypevrheader #1#2#3{\dovarind#3 \relax% -\begingroup\defname {\defheaderxcond#2\relax$.$#3}{#1} - \defargscommonending -\endgroup} - -% Now define @deftp -% Args are printed in bold, a slight difference from @defvar. - -\def\deftpargs #1{\bf \defvarargs{#1}} - -% @deftp Class window height width ... - -\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} - -\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% -\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} - -% These definitions are used if you use @defunx (etc.) -% anywhere other than immediately after a @defun or @defunx. -% -\def\defcvx#1 {\errmessage{@defcvx in invalid context}} -\def\deffnx#1 {\errmessage{@deffnx in invalid context}} -\def\defivarx#1 {\errmessage{@defivarx in invalid context}} -\def\defmacx#1 {\errmessage{@defmacx in invalid context}} -\def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} -\def\defoptx #1 {\errmessage{@defoptx in invalid context}} -\def\defopx#1 {\errmessage{@defopx in invalid context}} -\def\defspecx#1 {\errmessage{@defspecx in invalid context}} -\def\deftpx#1 {\errmessage{@deftpx in invalid context}} -\def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} -\def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} -\def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} -\def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} -\def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} -\def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} -\def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} -\def\defunx#1 {\errmessage{@defunx in invalid context}} -\def\defvarx#1 {\errmessage{@defvarx in invalid context}} -\def\defvrx#1 {\errmessage{@defvrx in invalid context}} - - -\message{macros,} -% @macro. - -% To do this right we need a feature of e-TeX, \scantokens, -% which we arrange to emulate with a temporary file in ordinary TeX. -\ifx\eTeXversion\undefined - \newwrite\macscribble - \def\scanmacro#1{% - \begingroup \newlinechar`\^^M - % Undo catcode changes of \startcontents and \doprintindex - \catcode`\@=0 \catcode`\\=\other \escapechar=`\@ - % Append \endinput to make sure that TeX does not see the ending newline. - \toks0={#1\endinput}% - \immediate\openout\macscribble=\jobname.tmp - \immediate\write\macscribble{\the\toks0}% - \immediate\closeout\macscribble - \let\xeatspaces\eatspaces - \input \jobname.tmp - \endgroup -} -\else -\def\scanmacro#1{% -\begingroup \newlinechar`\^^M -% Undo catcode changes of \startcontents and \doprintindex -\catcode`\@=0 \catcode`\\=\other \escapechar=`\@ -\let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} -\fi - -\newcount\paramno % Count of parameters -\newtoks\macname % Macro name -\newif\ifrecursive % Is it recursive? -\def\macrolist{} % List of all defined macros in the form - % \do\macro1\do\macro2... - -% Utility routines. -% Thisdoes \let #1 = #2, except with \csnames. -\def\cslet#1#2{% -\expandafter\expandafter -\expandafter\let -\expandafter\expandafter -\csname#1\endcsname -\csname#2\endcsname} - -% Trim leading and trailing spaces off a string. -% Concepts from aro-bend problem 15 (see CTAN). -{\catcode`\@=11 -\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} -\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} -\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} -\def\unbrace#1{#1} -\unbrace{\gdef\trim@@@ #1 } #2@{#1} -} - -% Trim a single trailing ^^M off a string. -{\catcode`\^^M=\other \catcode`\Q=3% -\gdef\eatcr #1{\eatcra #1Q^^MQ}% -\gdef\eatcra#1^^MQ{\eatcrb#1Q}% -\gdef\eatcrb#1Q#2Q{#1}% -} - -% Macro bodies are absorbed as an argument in a context where -% all characters are catcode 10, 11 or 12, except \ which is active -% (as in normal texinfo). It is necessary to change the definition of \. - -% It's necessary to have hard CRs when the macro is executed. This is -% done by making ^^M (\endlinechar) catcode 12 when reading the macro -% body, and then making it the \newlinechar in \scanmacro. - -\def\macrobodyctxt{% - \catcode`\~=\other - \catcode`\^=\other - \catcode`\_=\other - \catcode`\|=\other - \catcode`\<=\other - \catcode`\>=\other - \catcode`\+=\other - \catcode`\{=\other - \catcode`\}=\other - \catcode`\@=\other - \catcode`\^^M=\other - \usembodybackslash} - -\def\macroargctxt{% - \catcode`\~=\other - \catcode`\^=\other - \catcode`\_=\other - \catcode`\|=\other - \catcode`\<=\other - \catcode`\>=\other - \catcode`\+=\other - \catcode`\@=\other - \catcode`\\=\other} - -% \mbodybackslash is the definition of \ in @macro bodies. -% It maps \foo\ => \csname macarg.foo\endcsname => #N -% where N is the macro parameter number. -% We define \csname macarg.\endcsname to be \realbackslash, so -% \\ in macro replacement text gets you a backslash. - -{\catcode`@=0 @catcode`@\=@active - @gdef@usembodybackslash{@let\=@mbodybackslash} - @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} -} -\expandafter\def\csname macarg.\endcsname{\realbackslash} - -\def\macro{\recursivefalse\parsearg\macroxxx} -\def\rmacro{\recursivetrue\parsearg\macroxxx} - -\def\macroxxx#1{% - \getargs{#1}% now \macname is the macname and \argl the arglist - \ifx\argl\empty % no arguments - \paramno=0% - \else - \expandafter\parsemargdef \argl;% - \fi - \if1\csname ismacro.\the\macname\endcsname - \message{Warning: redefining \the\macname}% - \else - \expandafter\ifx\csname \the\macname\endcsname \relax - \else \errmessage{Macro name \the\macname\space already defined}\fi - \global\cslet{macsave.\the\macname}{\the\macname}% - \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% - % Add the macroname to \macrolist - \toks0 = \expandafter{\macrolist\do}% - \xdef\macrolist{\the\toks0 - \expandafter\noexpand\csname\the\macname\endcsname}% - \fi - \begingroup \macrobodyctxt - \ifrecursive \expandafter\parsermacbody - \else \expandafter\parsemacbody - \fi} - -\def\unmacro{\parsearg\dounmacro} -\def\dounmacro#1{% - \if1\csname ismacro.#1\endcsname - \global\cslet{#1}{macsave.#1}% - \global\expandafter\let \csname ismacro.#1\endcsname=0% - % Remove the macro name from \macrolist: - \begingroup - \expandafter\let\csname#1\endcsname \relax - \let\do\unmacrodo - \xdef\macrolist{\macrolist}% - \endgroup - \else - \errmessage{Macro #1 not defined}% - \fi -} - -% Called by \do from \dounmacro on each macro. The idea is to omit any -% macro definitions that have been changed to \relax. -% -\def\unmacrodo#1{% - \ifx#1\relax - % remove this - \else - \noexpand\do \noexpand #1% - \fi -} - -% This makes use of the obscure feature that if the last token of a -% <parameter list> is #, then the preceding argument is delimited by -% an opening brace, and that opening brace is not consumed. -\def\getargs#1{\getargsxxx#1{}} -\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} -\def\getmacname #1 #2\relax{\macname={#1}} -\def\getmacargs#1{\def\argl{#1}} - -% Parse the optional {params} list. Set up \paramno and \paramlist -% so \defmacro knows what to do. Define \macarg.blah for each blah -% in the params list, to be ##N where N is the position in that list. -% That gets used by \mbodybackslash (above). - -% We need to get `macro parameter char #' into several definitions. -% The technique used is stolen from LaTeX: let \hash be something -% unexpandable, insert that wherever you need a #, and then redefine -% it to # just before using the token list produced. -% -% The same technique is used to protect \eatspaces till just before -% the macro is used. - -\def\parsemargdef#1;{\paramno=0\def\paramlist{}% - \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} -\def\parsemargdefxxx#1,{% - \if#1;\let\next=\relax - \else \let\next=\parsemargdefxxx - \advance\paramno by 1% - \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname - {\xeatspaces{\hash\the\paramno}}% - \edef\paramlist{\paramlist\hash\the\paramno,}% - \fi\next} - -% These two commands read recursive and nonrecursive macro bodies. -% (They're different since rec and nonrec macros end differently.) - -\long\def\parsemacbody#1@end macro% -{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% -\long\def\parsermacbody#1@end rmacro% -{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% - -% This defines the macro itself. There are six cases: recursive and -% nonrecursive macros of zero, one, and many arguments. -% Much magic with \expandafter here. -% \xdef is used so that macro definitions will survive the file -% they're defined in; @include reads the file inside a group. -\def\defmacro{% - \let\hash=##% convert placeholders to macro parameter chars - \ifrecursive - \ifcase\paramno - % 0 - \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\scanmacro{\temp}}% - \or % 1 - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\braceorline - \expandafter\noexpand\csname\the\macname xxx\endcsname}% - \expandafter\xdef\csname\the\macname xxx\endcsname##1{% - \egroup\noexpand\scanmacro{\temp}}% - \else % many - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{\egroup\noexpand\scanmacro{\temp}}% - \fi - \else - \ifcase\paramno - % 0 - \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \or % 1 - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\braceorline - \expandafter\noexpand\csname\the\macname xxx\endcsname}% - \expandafter\xdef\csname\the\macname xxx\endcsname##1{% - \egroup - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \else % many - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \expandafter\noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{% - \egroup - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \fi - \fi} - -\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} - -% \braceorline decides whether the next nonwhitespace character is a -% {. If so it reads up to the closing }, if not, it reads the whole -% line. Whatever was read is then fed to the next control sequence -% as an argument (by \parsebrace or \parsearg) -\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} -\def\braceorlinexxx{% - \ifx\nchar\bgroup\else - \expandafter\parsearg - \fi \next} - -% We mant to disable all macros during \shipout so that they are not -% expanded by \write. -\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% - \edef\next{\macrolist}\expandafter\endgroup\next} - - -% @alias. -% We need some trickery to remove the optional spaces around the equal -% sign. Just make them active and then expand them all to nothing. -\def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} -\def\aliasxxx #1{\aliasyyy#1\relax} -\def\aliasyyy #1=#2\relax{\ignoreactivespaces -\edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% - \expandafter\noexpand\csname#2\endcsname}% -\expandafter\endgroup\next} - - -\message{cross references,} -% @xref etc. - -\newwrite\auxfile - -\newif\ifhavexrefs % True if xref values are known. -\newif\ifwarnedxrefs % True if we warned once that they aren't known. - -% @inforef is relatively simple. -\def\inforef #1{\inforefzzz #1,,,,**} -\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, - node \samp{\ignorespaces#1{}}} - -% @node's job is to define \lastnode. -\def\node{\ENVcheck\parsearg\nodezzz} -\def\nodezzz#1{\nodexxx #1,\finishnodeparse} -\def\nodexxx#1,#2\finishnodeparse{\gdef\lastnode{#1}} -\let\nwnode=\node -\let\lastnode=\relax - -% The sectioning commands (@chapter, etc.) call these. -\def\donoderef{% - \ifx\lastnode\relax\else - \expandafter\expandafter\expandafter\setref{\lastnode}% - {Ysectionnumberandtype}% - \global\let\lastnode=\relax - \fi -} -\def\unnumbnoderef{% - \ifx\lastnode\relax\else - \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% - \global\let\lastnode=\relax - \fi -} -\def\appendixnoderef{% - \ifx\lastnode\relax\else - \expandafter\expandafter\expandafter\setref{\lastnode}% - {Yappendixletterandtype}% - \global\let\lastnode=\relax - \fi -} - - -% @anchor{NAME} -- define xref target at arbitrary point. -% -\newcount\savesfregister -\gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} -\gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} -\gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} - -% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an -% anchor), namely NAME-title (the corresponding @chapter/etc. name), -% NAME-pg (the page number), and NAME-snt (section number and type). -% Called from \foonoderef. -% -% We have to set \indexdummies so commands such as @code in a section -% title aren't expanded. It would be nicer not to expand the titles in -% the first place, but there's so many layers that that is hard to do. -% -% Likewise, use \turnoffactive so that punctuation chars such as underscore -% and backslash work in node names. -% -\def\setref#1#2{{% - \atdummies - \pdfmkdest{#1}% - % - \turnoffactive - \dosetq{#1-title}{Ytitle}% - \dosetq{#1-pg}{Ypagenumber}% - \dosetq{#1-snt}{#2}% -}} - -% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is -% the node name, #2 the name of the Info cross-reference, #3 the printed -% node name, #4 the name of the Info file, #5 the name of the printed -% manual. All but the node name can be omitted. -% -\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} -\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} -\def\ref#1{\xrefX[#1,,,,,,,]} -\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup - \unsepspaces - \def\printedmanual{\ignorespaces #5}% - \def\printednodename{\ignorespaces #3}% - \setbox1=\hbox{\printedmanual}% - \setbox0=\hbox{\printednodename}% - \ifdim \wd0 = 0pt - % No printed node name was explicitly given. - \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax - % Use the node name inside the square brackets. - \def\printednodename{\ignorespaces #1}% - \else - % Use the actual chapter/section title appear inside - % the square brackets. Use the real section title if we have it. - \ifdim \wd1 > 0pt - % It is in another manual, so we don't have it. - \def\printednodename{\ignorespaces #1}% - \else - \ifhavexrefs - % We know the real title if we have the xref values. - \def\printednodename{\refx{#1-title}{}}% - \else - % Otherwise just copy the Info node name. - \def\printednodename{\ignorespaces #1}% - \fi% - \fi - \fi - \fi - % - % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not - % insert empty discretionaries after hyphens, which means that it will - % not find a line break at a hyphen in a node names. Since some manuals - % are best written with fairly long node names, containing hyphens, this - % is a loss. Therefore, we give the text of the node name again, so it - % is as if TeX is seeing it for the first time. - \ifpdf - \leavevmode - \getfilename{#4}% - {\turnoffactive \otherbackslash - \ifnum\filenamelength>0 - \startlink attr{/Border [0 0 0]}% - goto file{\the\filename.pdf} name{#1}% - \else - \startlink attr{/Border [0 0 0]}% - goto name{#1}% - \fi - }% - \linkcolor - \fi - % - \ifdim \wd1 > 0pt - \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% - \else - % _ (for example) has to be the character _ for the purposes of the - % control sequence corresponding to the node, but it has to expand - % into the usual \leavevmode...\vrule stuff for purposes of - % printing. So we \turnoffactive for the \refx-snt, back on for the - % printing, back off for the \refx-pg. - {\turnoffactive \otherbackslash - % Only output a following space if the -snt ref is nonempty; for - % @unnumbered and @anchor, it won't be. - \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% - \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi - }% - % output the `[mynode]' via a macro. - \xrefprintnodename\printednodename - % - % But we always want a comma and a space: - ,\space - % - % output the `page 3'. - \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}% - \fi - \endlink -\endgroup} - -% This macro is called from \xrefX for the `[nodename]' part of xref -% output. It's a separate macro only so it can be changed more easily, -% since not square brackets don't work in some documents. Particularly -% one that Bob is working on :). -% -\def\xrefprintnodename#1{[#1]} - -% \dosetq is called from \setref to do the actual \write (\iflinks). -% -\def\dosetq#1#2{% - {\let\folio=0% - \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% - \iflinks \next \fi - }% -} - -% \internalsetq{foo}{page} expands into -% CHARACTERS @xrdef{foo}{...expansion of \page...} -\def\internalsetq#1#2{@xrdef{#1}{\csname #2\endcsname}} - -% Things to be expanded by \internalsetq. -% -\def\Ypagenumber{\folio} -\def\Ytitle{\thissection} -\def\Ynothing{} -\def\Ysectionnumberandtype{% - \ifnum\secno=0 - \putwordChapter@tie \the\chapno - \else \ifnum\subsecno=0 - \putwordSection@tie \the\chapno.\the\secno - \else \ifnum\subsubsecno=0 - \putwordSection@tie \the\chapno.\the\secno.\the\subsecno - \else - \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno - \fi\fi\fi -} - -\def\Yappendixletterandtype{% - \ifnum\secno=0 - \putwordAppendix@tie @char\the\appendixno{}% - \else \ifnum\subsecno=0 - \putwordSection@tie @char\the\appendixno.\the\secno - \else \ifnum\subsubsecno=0 - \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno - \else - \putwordSection@tie - @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno - \fi\fi\fi -} - -% Use TeX 3.0's \inputlineno to get the line number, for better error -% messages, but if we're using an old version of TeX, don't do anything. -% -\ifx\inputlineno\thisisundefined - \let\linenumber = \empty % Pre-3.0. -\else - \def\linenumber{\the\inputlineno:\space} -\fi - -% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. -% If its value is nonempty, SUFFIX is output afterward. -% -\def\refx#1#2{% - {% - \indexnofonts - \otherbackslash - \expandafter\global\expandafter\let\expandafter\thisrefX - \csname X#1\endcsname - }% - \ifx\thisrefX\relax - % If not defined, say something at least. - \angleleft un\-de\-fined\angleright - \iflinks - \ifhavexrefs - \message{\linenumber Undefined cross reference `#1'.}% - \else - \ifwarnedxrefs\else - \global\warnedxrefstrue - \message{Cross reference values unknown; you must run TeX again.}% - \fi - \fi - \fi - \else - % It's defined, so just use it. - \thisrefX - \fi - #2% Output the suffix in any case. -} - -% This is the macro invoked by entries in the aux file. -% -\def\xrdef#1{\expandafter\gdef\csname X#1\endcsname} - -% Read the last existing aux file, if any. No error if none exists. -\def\readauxfile{\begingroup - \catcode`\^^@=\other - \catcode`\^^A=\other - \catcode`\^^B=\other - \catcode`\^^C=\other - \catcode`\^^D=\other - \catcode`\^^E=\other - \catcode`\^^F=\other - \catcode`\^^G=\other - \catcode`\^^H=\other - \catcode`\^^K=\other - \catcode`\^^L=\other - \catcode`\^^N=\other - \catcode`\^^P=\other - \catcode`\^^Q=\other - \catcode`\^^R=\other - \catcode`\^^S=\other - \catcode`\^^T=\other - \catcode`\^^U=\other - \catcode`\^^V=\other - \catcode`\^^W=\other - \catcode`\^^X=\other - \catcode`\^^Z=\other - \catcode`\^^[=\other - \catcode`\^^\=\other - \catcode`\^^]=\other - \catcode`\^^^=\other - \catcode`\^^_=\other - % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. - % in xref tags, i.e., node names. But since ^^e4 notation isn't - % supported in the main text, it doesn't seem desirable. Furthermore, - % that is not enough: for node names that actually contain a ^ - % character, we would end up writing a line like this: 'xrdef {'hat - % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first - % argument, and \hat is not an expandable control sequence. It could - % all be worked out, but why? Either we support ^^ or we don't. - % - % The other change necessary for this was to define \auxhat: - % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter - % and then to call \auxhat in \setq. - % - \catcode`\^=\other - % - % Special characters. Should be turned off anyway, but... - \catcode`\~=\other - \catcode`\[=\other - \catcode`\]=\other - \catcode`\"=\other - \catcode`\_=\other - \catcode`\|=\other - \catcode`\<=\other - \catcode`\>=\other - \catcode`\$=\other - \catcode`\#=\other - \catcode`\&=\other - \catcode`\%=\other - \catcode`+=\other % avoid \+ for paranoia even though we've turned it off - % - % Make the characters 128-255 be printing characters - {% - \count 1=128 - \def\loop{% - \catcode\count 1=\other - \advance\count 1 by 1 - \ifnum \count 1<256 \loop \fi - }% - }% - % - % Turn off \ as an escape so we do not lose on - % entries which were dumped with control sequences in their names. - % For example, @xrdef{$\leq $-fun}{page ...} made by @defun ^^ - % Reference to such entries still does not work the way one would wish, - % but at least they do not bomb out when the aux file is read in. - \catcode`\\=\other - % - % @ is our escape character in .aux files. - \catcode`\{=1 - \catcode`\}=2 - \catcode`\@=0 - % - \openin 1 \jobname.aux - \ifeof 1 \else - \closein 1 - \input \jobname.aux - \global\havexrefstrue - \global\warnedobstrue - \fi - % Open the new aux file. TeX will close it automatically at exit. - \openout\auxfile=\jobname.aux -\endgroup} - - -% Footnotes. - -\newcount \footnoteno - -% The trailing space in the following definition for supereject is -% vital for proper filling; pages come out unaligned when you do a -% pagealignmacro call if that space before the closing brace is -% removed. (Generally, numeric constants should always be followed by a -% space to prevent strange expansion errors.) -\def\supereject{\par\penalty -20000\footnoteno =0 } - -% @footnotestyle is meaningful for info output only. -\let\footnotestyle=\comment - -\let\ptexfootnote=\footnote - -{\catcode `\@=11 -% -% Auto-number footnotes. Otherwise like plain. -\gdef\footnote{% - \let\indent=\ptexindent - \global\advance\footnoteno by \@ne - \edef\thisfootno{$^{\the\footnoteno}$}% - % - % In case the footnote comes at the end of a sentence, preserve the - % extra spacing after we do the footnote number. - \let\@sf\empty - \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi - % - % Remove inadvertent blank space before typesetting the footnote number. - \unskip - \thisfootno\@sf - \dofootnote -}% - -% Don't bother with the trickery in plain.tex to not require the -% footnote text as a parameter. Our footnotes don't need to be so general. -% -% Oh yes, they do; otherwise, @ifset and anything else that uses -% \parseargline fail inside footnotes because the tokens are fixed when -% the footnote is read. --karl, 16nov96. -% -% The start of the footnote looks usually like this: -\gdef\startfootins{\insert\footins\bgroup} -% -% ... but this macro is redefined inside @multitable. -% -\gdef\dofootnote{% - \startfootins - % We want to typeset this text as a normal paragraph, even if the - % footnote reference occurs in (for example) a display environment. - % So reset some parameters. - \hsize=\pagewidth - \interlinepenalty\interfootnotelinepenalty - \splittopskip\ht\strutbox % top baseline for broken footnotes - \splitmaxdepth\dp\strutbox - \floatingpenalty\@MM - \leftskip\z@skip - \rightskip\z@skip - \spaceskip\z@skip - \xspaceskip\z@skip - \parindent\defaultparindent - % - \smallfonts \rm - % - % Because we use hanging indentation in footnotes, a @noindent appears - % to exdent this text, so make it be a no-op. makeinfo does not use - % hanging indentation so @noindent can still be needed within footnote - % text after an @example or the like (not that this is good style). - \let\noindent = \relax - % - % Hang the footnote text off the number. Use \everypar in case the - % footnote extends for more than one paragraph. - \everypar = {\hang}% - \textindent{\thisfootno}% - % - % Don't crash into the line above the footnote text. Since this - % expands into a box, it must come within the paragraph, lest it - % provide a place where TeX can split the footnote. - \footstrut - \futurelet\next\fo@t -} -}%end \catcode `\@=11 - -% @| inserts a changebar to the left of the current line. It should -% surround any changed text. This approach does *not* work if the -% change spans more than two lines of output. To handle that, we would -% have adopt a much more difficult approach (putting marks into the main -% vertical list for the beginning and end of each change). -% -\def\|{% - % \vadjust can only be used in horizontal mode. - \leavevmode - % - % Append this vertical mode material after the current line in the output. - \vadjust{% - % We want to insert a rule with the height and depth of the current - % leading; that is exactly what \strutbox is supposed to record. - \vskip-\baselineskip - % - % \vadjust-items are inserted at the left edge of the type. So - % the \llap here moves out into the left-hand margin. - \llap{% - % - % For a thicker or thinner bar, change the `1pt'. - \vrule height\baselineskip width1pt - % - % This is the space between the bar and the text. - \hskip 12pt - }% - }% -} - -% For a final copy, take out the rectangles -% that mark overfull boxes (in case you have decided -% that the text looks ok even though it passes the margin). -% -\def\finalout{\overfullrule=0pt} - -% @image. We use the macros from epsf.tex to support this. -% If epsf.tex is not installed and @image is used, we complain. -% -% Check for and read epsf.tex up front. If we read it only at @image -% time, we might be inside a group, and then its definitions would get -% undone and the next image would fail. -\openin 1 = epsf.tex -\ifeof 1 \else - \closein 1 - % Do not bother showing banner with epsf.tex v2.7k (available in - % doc/epsf.tex and on ctan). - \def\epsfannounce{\toks0 = }% - \input epsf.tex -\fi -% -% We will only complain once about lack of epsf.tex. -\newif\ifwarnednoepsf -\newhelp\noepsfhelp{epsf.tex must be installed for images to - work. It is also included in the Texinfo distribution, or you can get - it from ftp://tug.org/tex/epsf.tex.} -% -\def\image#1{% - \ifx\epsfbox\undefined - \ifwarnednoepsf \else - \errhelp = \noepsfhelp - \errmessage{epsf.tex not found, images will be ignored}% - \global\warnednoepsftrue - \fi - \else - \imagexxx #1,,,,,\finish - \fi -} -% -% Arguments to @image: -% #1 is (mandatory) image filename; we tack on .eps extension. -% #2 is (optional) width, #3 is (optional) height. -% #4 is (ignored optional) html alt text. -% #5 is (ignored optional) extension. -% #6 is just the usual extra ignored arg for parsing this stuff. -\newif\ifimagevmode -\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup - \catcode`\^^M = 5 % in case we're inside an example - \normalturnoffactive % allow _ et al. in names - % If the image is by itself, center it. - \ifvmode - \imagevmodetrue - \nobreak\bigskip - % Usually we'll have text after the image which will insert - % \parskip glue, so insert it here too to equalize the space - % above and below. - \nobreak\vskip\parskip - \nobreak - \line\bgroup\hss - \fi - % - % Output the image. - \ifpdf - \dopdfimage{#1}{#2}{#3}% - \else - % \epsfbox itself resets \epsf?size at each figure. - \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi - \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi - \epsfbox{#1.eps}% - \fi - % - \ifimagevmode \hss \egroup \bigbreak \fi % space after the image -\endgroup} - - -\message{localization,} -% and i18n. - -% @documentlanguage is usually given very early, just after -% @setfilename. If done too late, it may not override everything -% properly. Single argument is the language abbreviation. -% It would be nice if we could set up a hyphenation file here. -% -\def\documentlanguage{\parsearg\dodocumentlanguage} -\def\dodocumentlanguage#1{% - \tex % read txi-??.tex file in plain TeX. - % Read the file if it exists. - \openin 1 txi-#1.tex - \ifeof1 - \errhelp = \nolanghelp - \errmessage{Cannot read language file txi-#1.tex}% - \let\temp = \relax - \else - \def\temp{\input txi-#1.tex }% - \fi - \temp - \endgroup -} -\newhelp\nolanghelp{The given language definition file cannot be found or -is empty. Maybe you need to install it? In the current directory -should work if nowhere else does.} - - -% @documentencoding should change something in TeX eventually, most -% likely, but for now just recognize it. -\let\documentencoding = \comment - - -% Page size parameters. -% -\newdimen\defaultparindent \defaultparindent = 15pt - -\chapheadingskip = 15pt plus 4pt minus 2pt -\secheadingskip = 12pt plus 3pt minus 2pt -\subsecheadingskip = 9pt plus 2pt minus 2pt - -% Prevent underfull vbox error messages. -\vbadness = 10000 - -% Don't be so finicky about underfull hboxes, either. -\hbadness = 2000 - -% Following George Bush, just get rid of widows and orphans. -\widowpenalty=10000 -\clubpenalty=10000 - -% Use TeX 3.0's \emergencystretch to help line breaking, but if we're -% using an old version of TeX, don't do anything. We want the amount of -% stretch added to depend on the line length, hence the dependence on -% \hsize. We call this whenever the paper size is set. -% -\def\setemergencystretch{% - \ifx\emergencystretch\thisisundefined - % Allow us to assign to \emergencystretch anyway. - \def\emergencystretch{\dimen0}% - \else - \emergencystretch = .15\hsize - \fi -} - -% Parameters in order: 1) textheight; 2) textwidth; 3) voffset; -% 4) hoffset; 5) binding offset; 6) topskip; 7) physical page height; 8) -% physical page width. -% -% We also call \setleading{\textleading}, so the caller should define -% \textleading. The caller should also set \parskip. -% -\def\internalpagesizes#1#2#3#4#5#6#7#8{% - \voffset = #3\relax - \topskip = #6\relax - \splittopskip = \topskip - % - \vsize = #1\relax - \advance\vsize by \topskip - \outervsize = \vsize - \advance\outervsize by 2\topandbottommargin - \pageheight = \vsize - % - \hsize = #2\relax - \outerhsize = \hsize - \advance\outerhsize by 0.5in - \pagewidth = \hsize - % - \normaloffset = #4\relax - \bindingoffset = #5\relax - % - \ifpdf - \pdfpageheight #7\relax - \pdfpagewidth #8\relax - \fi - % - \setleading{\textleading} - % - \parindent = \defaultparindent - \setemergencystretch -} - -% @letterpaper (the default). -\def\letterpaper{{\globaldefs = 1 - \parskip = 3pt plus 2pt minus 1pt - \textleading = 13.2pt - % - % If page is nothing but text, make it come out even. - \internalpagesizes{46\baselineskip}{6in}% - {\voffset}{.25in}% - {\bindingoffset}{36pt}% - {11in}{8.5in}% -}} - -% Use @smallbook to reset parameters for 7x9.5 (or so) format. -\def\smallbook{{\globaldefs = 1 - \parskip = 2pt plus 1pt - \textleading = 12pt - % - \internalpagesizes{7.5in}{5in}% - {\voffset}{.25in}% - {\bindingoffset}{16pt}% - {9.25in}{7in}% - % - \lispnarrowing = 0.3in - \tolerance = 700 - \hfuzz = 1pt - \contentsrightmargin = 0pt - \defbodyindent = .5cm -}} - -% Use @afourpaper to print on European A4 paper. -\def\afourpaper{{\globaldefs = 1 - \parskip = 3pt plus 2pt minus 1pt - \textleading = 13.2pt - % - % Double-side printing via postscript on Laserjet 4050 - % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. - % To change the settings for a different printer or situation, adjust - % \normaloffset until the front-side and back-side texts align. Then - % do the same for \bindingoffset. You can set these for testing in - % your texinfo source file like this: - % @tex - % \global\normaloffset = -6mm - % \global\bindingoffset = 10mm - % @end tex - \internalpagesizes{51\baselineskip}{160mm} - {\voffset}{\hoffset}% - {\bindingoffset}{44pt}% - {297mm}{210mm}% - % - \tolerance = 700 - \hfuzz = 1pt - \contentsrightmargin = 0pt - \defbodyindent = 5mm -}} - -% Use @afivepaper to print on European A5 paper. -% From romildo@urano.iceb.ufop.br, 2 July 2000. -% He also recommends making @example and @lisp be small. -\def\afivepaper{{\globaldefs = 1 - \parskip = 2pt plus 1pt minus 0.1pt - \textleading = 12.5pt - % - \internalpagesizes{160mm}{120mm}% - {\voffset}{\hoffset}% - {\bindingoffset}{8pt}% - {210mm}{148mm}% - % - \lispnarrowing = 0.2in - \tolerance = 800 - \hfuzz = 1.2pt - \contentsrightmargin = 0pt - \defbodyindent = 2mm - \tableindent = 12mm -}} - -% A specific text layout, 24x15cm overall, intended for A4 paper. -\def\afourlatex{{\globaldefs = 1 - \afourpaper - \internalpagesizes{237mm}{150mm}% - {\voffset}{4.6mm}% - {\bindingoffset}{7mm}% - {297mm}{210mm}% - % - % Must explicitly reset to 0 because we call \afourpaper. - \globaldefs = 0 -}} - -% Use @afourwide to print on A4 paper in landscape format. -\def\afourwide{{\globaldefs = 1 - \afourpaper - \internalpagesizes{241mm}{165mm}% - {\voffset}{-2.95mm}% - {\bindingoffset}{7mm}% - {297mm}{210mm}% - \globaldefs = 0 -}} - -% @pagesizes TEXTHEIGHT[,TEXTWIDTH] -% Perhaps we should allow setting the margins, \topskip, \parskip, -% and/or leading, also. Or perhaps we should compute them somehow. -% -\def\pagesizes{\parsearg\pagesizesxxx} -\def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} -\def\pagesizesyyy#1,#2,#3\finish{{% - \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi - \globaldefs = 1 - % - \parskip = 3pt plus 2pt minus 1pt - \setleading{\textleading}% - % - \dimen0 = #1 - \advance\dimen0 by \voffset - % - \dimen2 = \hsize - \advance\dimen2 by \normaloffset - % - \internalpagesizes{#1}{\hsize}% - {\voffset}{\normaloffset}% - {\bindingoffset}{44pt}% - {\dimen0}{\dimen2}% -}} - -% Set default to letter. -% -\letterpaper - - -\message{and turning on texinfo input format.} - -% Define macros to output various characters with catcode for normal text. -\catcode`\"=\other -\catcode`\~=\other -\catcode`\^=\other -\catcode`\_=\other -\catcode`\|=\other -\catcode`\<=\other -\catcode`\>=\other -\catcode`\+=\other -\catcode`\$=\other -\def\normaldoublequote{"} -\def\normaltilde{~} -\def\normalcaret{^} -\def\normalunderscore{_} -\def\normalverticalbar{|} -\def\normalless{<} -\def\normalgreater{>} -\def\normalplus{+} -\def\normaldollar{$}%$ font-lock fix - -% This macro is used to make a character print one way in ttfont -% where it can probably just be output, and another way in other fonts, -% where something hairier probably needs to be done. -% -% #1 is what to print if we are indeed using \tt; #2 is what to print -% otherwise. Since all the Computer Modern typewriter fonts have zero -% interword stretch (and shrink), and it is reasonable to expect all -% typewriter fonts to have this, we can check that font parameter. -% -\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} - -% Same as above, but check for italic font. Actually this also catches -% non-italic slanted fonts since it is impossible to distinguish them from -% italic fonts. But since this is only used by $ and it uses \sl anyway -% this is not a problem. -\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} - -% Turn off all special characters except @ -% (and those which the user can use as if they were ordinary). -% Most of these we simply print from the \tt font, but for some, we can -% use math or other variants that look better in normal text. - -\catcode`\"=\active -\def\activedoublequote{{\tt\char34}} -\let"=\activedoublequote -\catcode`\~=\active -\def~{{\tt\char126}} -\chardef\hat=`\^ -\catcode`\^=\active -\def^{{\tt \hat}} - -\catcode`\_=\active -\def_{\ifusingtt\normalunderscore\_} -% Subroutine for the previous macro. -\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } - -\catcode`\|=\active -\def|{{\tt\char124}} -\chardef \less=`\< -\catcode`\<=\active -\def<{{\tt \less}} -\chardef \gtr=`\> -\catcode`\>=\active -\def>{{\tt \gtr}} -\catcode`\+=\active -\def+{{\tt \char 43}} -\catcode`\$=\active -\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix - -% Set up an active definition for =, but don't enable it most of the time. -{\catcode`\==\active -\global\def={{\tt \char 61}}} - -\catcode`+=\active -\catcode`\_=\active - -% If a .fmt file is being used, characters that might appear in a file -% name cannot be active until we have parsed the command line. -% So turn them off again, and have \everyjob (or @setfilename) turn them on. -% \otherifyactive is called near the end of this file. -\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} - -\catcode`\@=0 - -% \rawbackslashxx outputs one backslash character in current font, -% as in \char`\\. -\global\chardef\rawbackslashxx=`\\ - -% \rawbackslash defines an active \ to do \rawbackslashxx. -% \otherbackslash defines an active \ to be a literal `\' character with -% catcode other. -{\catcode`\\=\active - @gdef@rawbackslash{@let\=@rawbackslashxx} - @gdef@otherbackslash{@let\=@realbackslash} -} - -% \realbackslash is an actual character `\' with catcode other. -{\catcode`\\=\other @gdef@realbackslash{\}} - -% \normalbackslash outputs one backslash in fixed width font. -\def\normalbackslash{{\tt\rawbackslashxx}} - -\catcode`\\=\active - -% Used sometimes to turn off (effectively) the active characters -% even after parsing them. -@def@turnoffactive{% - @let"=@normaldoublequote - @let\=@realbackslash - @let~=@normaltilde - @let^=@normalcaret - @let_=@normalunderscore - @let|=@normalverticalbar - @let<=@normalless - @let>=@normalgreater - @let+=@normalplus - @let$=@normaldollar %$ font-lock fix -} - -% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of -% the literal character `\'. (Thus, \ is not expandable when this is in -% effect.) -% -@def@normalturnoffactive{@turnoffactive @let\=@normalbackslash} - -% Make _ and + \other characters, temporarily. -% This is canceled by @fixbackslash. -@otherifyactive - -% If a .fmt file is being used, we don't want the `\input texinfo' to show up. -% That is what \eatinput is for; after that, the `\' should revert to printing -% a backslash. -% -@gdef@eatinput input texinfo{@fixbackslash} -@global@let\ = @eatinput - -% On the other hand, perhaps the file did not have a `\input texinfo'. Then -% the first `\{ in the file would cause an error. This macro tries to fix -% that, assuming it is called before the first `\' could plausibly occur. -% Also back turn on active characters that might appear in the input -% file name, in case not using a pre-dumped format. -% -@gdef@fixbackslash{% - @ifx\@eatinput @let\ = @normalbackslash @fi - @catcode`+=@active - @catcode`@_=@active -} - -% Say @foo, not \foo, in error messages. -@escapechar = `@@ - -% These look ok in all fonts, so just make them not special. -@catcode`@& = @other -@catcode`@# = @other -@catcode`@% = @other - -@c Set initial fonts. -@textfonts -@rm - - -@c Local variables: -@c eval: (add-hook 'write-file-hooks 'time-stamp) -@c page-delimiter: "^\\\\message" -@c time-stamp-start: "def\\\\texinfoversion{" -@c time-stamp-format: "%:y-%02m-%02d.%02H" -@c time-stamp-end: "}" -@c End: diff --git a/sm/ChangeLog b/sm/ChangeLog deleted file mode 100644 index c1a8f6411..000000000 --- a/sm/ChangeLog +++ /dev/null @@ -1,1220 +0,0 @@ -2004-06-06 Werner Koch <wk@gnupg.org> - - * certreqgen.c (get_parameter_uint, create_request): Create - an extension for key usage when requested. - -2004-05-12 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Install emergency_cleanup also as an atexit - handler. - - * verify.c (gpgsm_verify): Removed the separate error code - handling for KSBA. We use shared error codes anyway. - - * export.c (export_p12): Removed debugging code. - - * encrypt.c (gpgsm_encrypt): Put the session key in to secure memory. - -2004-05-11 Werner Koch <wk@gnupg.org> - - * sign.c (gpgsm_sign): Include the error source in the final error - message. - * decrypt.c (gpgsm_decrypt): Ditto. - - * fingerprint.c (gpgsm_get_key_algo_info): New. - * sign.c (gpgsm_sign): Don't assume RSA in the status line. - * keylist.c (list_cert_colon): Really print the algorithm and key - length. - (list_cert_raw, list_cert_std): Ditto. - (list_cert_colon): Reorganized to be able to tell whether a root - certificate is trusted. - - * gpgsm.c: New option --debug-allow-core-dump. - - * gpgsm.h (opt): Add member CONFIG_FILENAME. - * gpgsm.c (main): Use it here instead of the local var. - - * server.c (gpgsm_server): Print some additional information with - the hello in verbose mode. - -2004-04-30 Werner Koch <wk@gnupg.org> - - * import.c (check_and_store): Do not update the stats for hidden - imports of issuer certs. - (popen_protect_tool): Request statusmessages from the protect-tool. - (parse_p12): Detect status messages. Add new arg STATS and update them. - (print_imported_summary): Include secret key stats. - -2004-04-28 Werner Koch <wk@gnupg.org> - - * gpgsm.c: New command --keydb-clear-some-cert-flags. - * keydb.c (keydb_clear_some_cert_flags): New. - (keydb_update_keyblock, keydb_set_flags): Change error code - CONFLICT to NOT_LOCKED. - -2004-04-26 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main) <gpgconf>: Do not use /dev/null as default config - filename. - - * call-agent.c (gpgsm_agent_pksign, gpgsm_agent_pkdecrypt) - (gpgsm_agent_genkey, gpgsm_agent_istrusted) - (gpgsm_agent_marktrusted, gpgsm_agent_havekey) - (gpgsm_agent_passwd): Add new arg CTRL and changed all callers. - (start_agent): New arg CTRL. Send progress item when starting a - new agent. - * sign.c (gpgsm_get_default_cert, get_default_signer): New arg - CTRL to be passed down to the agent function. - * decrypt.c (prepare_decryption): Ditto. - * certreqgen.c (proc_parameters, read_parameters): Ditto. - * certcheck.c (gpgsm_create_cms_signature): Ditto. - -2004-04-23 Werner Koch <wk@gnupg.org> - - * keydb.c (keydb_add_resource): Try to compress the file on init. - - * keylist.c (oidtranstbl): New. OIDs collected from several sources. - (print_name_raw, print_names_raw, list_cert_raw): New. - (gpgsm_list_keys): Check the dump mode and pass it down as - necessary. - -2004-04-22 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): New commands --dump-keys, --dump-external-keys, - --dump-secret-keys. - -2004-04-13 Werner Koch <wk@gnupg.org> - - * misc.c (setup_pinentry_env): New. - * import.c (popen_protect_tool): Call it. - * export.c (popen_protect_tool): Call it. - -2004-04-08 Werner Koch <wk@gnupg.org> - - * decrypt.c (gpgsm_decrypt): Return GPG_ERR_NO_DATA if it is not a - encrypted message. - -2004-04-07 Werner Koch <wk@gnupg.org> - - * gpgsm.c: New option --force-crl-refresh. - * call-dirmngr.c (gpgsm_dirmngr_isvalid): Pass option to dirmngr. - -2004-04-05 Werner Koch <wk@gnupg.org> - - * server.c (get_status_string): Add STATUS_NEWSIG. - * verify.c (gpgsm_verify): Print STATUS_NEWSIG for each signature. - - * certchain.c (gpgsm_validate_chain) <gpgsm_cert_use_cer_p>: Do - not just warn if a cert is not suitable; bail out immediately. - -2004-04-01 Werner Koch <wk@gnupg.org> - - * call-dirmngr.c (isvalid_status_cb): New. - (unhexify_fpr): New. Taken from ../g10/call-agent.c - (gpgsm_dirmngr_isvalid): Add new arg CTRL, changed caller to pass - it thru. Detect need to check the respondert cert and do that. - * certchain.c (gpgsm_validate_chain): Add new arg FLAGS. Changed - all callers. - -2004-03-24 Werner Koch <wk@gnupg.org> - - * sign.c (gpgsm_sign): Include a short list of capabilities. - -2004-03-17 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main) <gpgconf>: Fixed default value quoting. - -2004-03-16 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Implemented --gpgconf-list. - -2004-03-15 Werner Koch <wk@gnupg.org> - - * keylist.c (list_cert_colon): Hack to set the expired flag. - -2004-03-09 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Correctly intitialze USE_OCSP flag. - - * keydb.c (keydb_delete): s/GPG_ERR_CONFLICT/GPG_ERR_NOT_LOCKED/ - -2004-03-04 Werner Koch <wk@gnupg.org> - - * call-dirmngr.c (gpgsm_dirmngr_isvalid): New arg ISSUER_CERT. - - * certchain.c (is_cert_still_valid): New. Code moved from ... - (gpgsm_validate_chain): ... here because we now need to check at - two places and at a later stage, so that we can pass the issuer - cert down to the dirmngr. - -2004-03-03 Werner Koch <wk@gnupg.org> - - * call-agent.c (start_agent): Replaced pinentry setup code by a - call to a new common function. - - * certdump.c (gpgsm_format_keydesc): Make sure the string is - returned as utf-8. - - * export.c (gpgsm_export): Make sure that we don't export more - than one certificate. - -2004-03-02 Werner Koch <wk@gnupg.org> - - * export.c (create_duptable, destroy_duptable) - (insert_duptable): New. - (gpgsm_export): Avoid duplicates. - -2004-02-26 Werner Koch <wk@gnupg.org> - - * certchain.c (compare_certs): New. - (gpgsm_validate_chain): Fixed infinite certificate checks after - bad signatures. - -2004-02-24 Werner Koch <wk@gnupg.org> - - * keylist.c (list_cert_colon): Print the fingerprint as the - cert-id for root certificates. - -2004-02-21 Werner Koch <wk@gnupg.org> - - * keylist.c (list_internal_keys): Return error codes. - (list_external_keys, gpgsm_list_keys): Ditto. - * server.c (do_listkeys): Ditto. - - * gpgsm.c (main): Display a key description for --passwd. - * call-agent.c (gpgsm_agent_passwd): New arg DESC. - -2004-02-20 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): New option --debug-ignore-expiration. - * certchain.c (gpgsm_validate_chain): Use it here. - - * certlist.c (cert_usage_p): Apply extKeyUsage. - -2004-02-19 Werner Koch <wk@gnupg.org> - - * export.c (export_p12, popen_protect_tool) - (gpgsm_p12_export): New. - * gpgsm.c (main): New command --export-secret-key-p12. - -2004-02-18 Werner Koch <wk@gnupg.org> - - * gpgsm.c (set_debug): Set the new --debug-level flags. - (main): New option --gpgconf-list. - (main): Do not setup -u and -r keys when not required. - (main): Setup the used character set. - - * keydb.c (keydb_add_resource): Print a hint to start the - gpg-agent. - -2004-02-17 Werner Koch <wk@gnupg.org> - - * gpgsm.c: Fixed value parsing for --with-validation. - * call-agent.c (start_agent): Ignore an empty GPG_AGENT_INFO. - * call-dirmngr.c (start_dirmngr): Likewise for DIRMNGR_INFO. - - * gpgsm.c: New option --with-md5-fingerprint. - * keylist.c (list_cert_std): Print MD5 fpr. - - * gpgsm.c: New options --with-validation. - * server.c (option_handler): New option "with-validation". - * keylist.c (list_cert_std, list_internal_keys): New args CTRL and - WITH_VALIDATION. Changed callers to set it. - (list_external_cb, list_external_keys): Pass CTRL to the callback. - (list_cert_colon): Add arg CTRL. Check validation if requested. - * certchain.c (unknown_criticals, allowed_ca, check_cert_policy) - (gpgsm_validate_chain): New args LISTMODE and FP. - (do_list): New helper for info output. - (find_up): New arg FIND_NEXT. - (gpgsm_validate_chain): After a bad signature try again with other - CA certificates. - - * import.c (print_imported_status): New arg NEW_CERT. Print - additional STATUS_IMPORT_OK becuase that is what gpgme expects. - (check_and_store): Always call above function after import. - * server.c (get_status_string): Added STATUS_IMPORT_OK. - -2004-02-13 Werner Koch <wk@gnupg.org> - - * certcheck.c (gpgsm_create_cms_signature): Format a description - for use by the pinentry. - * decrypt.c (gpgsm_decrypt): Ditto. Free HEXKEYGRIP. - * certdump.c (format_name_cookie, format_name_writer) - (gpgsm_format_name): New. - (gpgsm_format_serial): New. - (gpgsm_format_keydesc): New. - * call-agent.c (gpgsm_agent_pksign): New arg DESC. - (gpgsm_agent_pkdecrypt): Ditto. - - * encrypt.c (init_dek): Check for too weak algorithms. - - * import.c (parse_p12, popen_protect_tool): New. - - * base64.c (gpgsm_create_reader): New arg ALLOW_MULTI_PEM. - Changed all callers. - (base64_reader_cb): Handle it here. - (gpgsm_reader_eof_seen): New. - (base64_reader_cb): Set a flag for EOF. - (simple_reader_cb): Ditto. - -2004-02-12 Werner Koch <wk@gnupg.org> - - * gpgsm.h, gpgsm.c: New option --protect-tool-program. - * gpgsm.c (run_protect_tool): Use it. - -2004-02-11 Werner Koch <wk@gnupg.org> - - * Makefile.am (AM_CPPFLAGS): Pass directory constants via -D; this - will allow to override directory names at make time. - -2004-02-02 Werner Koch <wk@gnupg.org> - - * import.c (check_and_store): Import certificates even with - missing issuer's cert. Fixed an "depending on the verbose - setting" bug. - - * certchain.c (gpgsm_validate_chain): Mark revoked certs in the - keybox. - - * keylist.c (list_cert_colon): New arg VALIDITY; use it to print a - revoked flag. - (list_internal_keys): Retrieve validity flag. - (list_external_cb): Pass 0 as validity flag. - * keydb.c (keydb_get_flags, keydb_set_flags): New. - (keydb_set_cert_flags): New. - (lock_all): Return a proper error code. - (keydb_lock): New. - (keydb_delete): Don't lock but check that it has been locked. - (keydb_update_keyblock): Ditto. - * delete.c (delete_one): Take a lock. - -2004-01-30 Werner Koch <wk@gnupg.org> - - * certchain.c (check_cert_policy): Fixed read error checking. - (check_cert_policy): With no critical policies issue only a - warning if the policy file does not exists. - - * sign.c (add_certificate_list): Decrement N for the first cert. - -2004-01-29 Werner Koch <wk@gnupg.org> - - * certdump.c (parse_dn_part): Map common OIDs to human readable - labels. Make sure that a value won't get truncated if it includes - a Nul. - -2004-01-28 Werner Koch <wk@gnupg.org> - - * certchain.c (gpgsm_validate_chain): Changed the message printed - for an untrusted root certificate. - -2004-01-27 Werner Koch <wk@gnupg.org> - - * certdump.c (parse_dn_part): Pretty print the nameDistinguisher OID. - (print_dn_part): Do not delimit multiple RDN by " + ". Handle - multi-valued RDNs in a special way, i.e. in the order specified by - the certificate. - (print_dn_parts): Simplified. - -2004-01-16 Werner Koch <wk@gnupg.org> - - * sign.c (gpgsm_sign): Print an error message on all failures. - * decrypt.c (gpgsm_decrypt): Ditto. - -2003-12-17 Werner Koch <wk@gnupg.org> - - * server.c (gpgsm_server): Add arg DEFAULT_RECPLIST. - (cmd_encrypt): Add all enrypt-to marked certs to the list. - * encrypt.c (gpgsm_encrypt): Check that real recipients are - available. - * gpgsm.c (main): Make the --encrypt-to and --no-encrypt-to - options work. Pass the list of recients to gpgsm_server. - * gpgsm.h (certlist_s): Add field IS_ENCRYPT_TO. - (opt): Add NO_ENCRYPT_TO. - * certlist.c (gpgsm_add_to_certlist): New arg IS_ENCRYPT_TO. - Changed all callers and ignore duplicate entries. - (is_cert_in_certlist): New. - (gpgsm_add_cert_to_certlist): New. - - * certdump.c (gpgsm_print_serial): Cleaned up cast use in strtoul. - (gpgsm_dump_serial): Ditto. - - * decrypt.c (gpgsm_decrypt): Replaced ERR by RC. - -2003-12-16 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Set the prefixes for assuan logging. - - * sign.c (gpgsm_sign): Add validation checks for the default - certificate. - - * gpgsm.c: Add -k as alias for --list-keys and -K for - --list-secret-keys. - -2003-12-15 Werner Koch <wk@gnupg.org> - - * encrypt.c (init_dek): Use gry_create_nonce for the IV; there is - not need for real strong random here and it even better protect - the random bits used for the key. - -2003-12-01 Werner Koch <wk@gnupg.org> - - * gpgsm.c, gpgsm.h: New options --{enable,disable}-ocsp. - (gpgsm_init_default_ctrl): Set USE_OCSP to the default value. - * certchain.c (gpgsm_validate_chain): Handle USE_OCSP. - * call-dirmngr.c (gpgsm_dirmngr_isvalid): Add arg USE_OCSP and - proceed accordingly. - -2003-11-19 Werner Koch <wk@gnupg.org> - - * verify.c (gpgsm_verify): Use "0" instead of an empty string for - the VALIDSIG status. - -2003-11-18 Werner Koch <wk@gnupg.org> - - * verify.c (gpgsm_verify): Fixed for changes API of gcry_md_info. - - * certchain.c (unknown_criticals): Fixed an error code test. - -2003-11-12 Werner Koch <wk@gnupg.org> - - Adjusted for API changes in Libksba. - -2003-10-31 Werner Koch <wk@gnupg.org> - - * certchain.c (gpgsm_validate_chain): Changed to use ksba_isotime_t. - * verify.c (strtimestamp_r, gpgsm_verify): Ditto. - * sign.c (gpgsm_sign): Ditto. - * keylist.c (print_time, list_cert_std, list_cert_colon): Ditto. - * certdump.c (gpgsm_print_time, gpgsm_dump_time, gpgsm_dump_cert): - Ditto. - -2003-10-25 Werner Koch <wk@gnupg.org> - - * certreqgen.c (read_parameters): Fixed faulty of !spacep(). - -2003-08-20 Marcus Brinkmann <marcus@g10code.de> - - * encrypt.c (encode_session_key): Allocate enough space. Cast key - byte to unsigned char to prevent sign extension. - (encrypt_dek): Check return value before error. - -2003-08-14 Timo Schulz <twoaday@freakmail.de> - - * encrypt.c (encode_session_key): Use new Libgcrypt interface. - -2003-07-31 Werner Koch <wk@gnupg.org> - - * Makefile.am (gpgsm_LDADD): Added INTLLIBS. - -2003-07-29 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Add secmem features and set the random seed file. - (gpgsm_exit): Update the random seed file and enable debug output. - -2003-07-27 Werner Koch <wk@gnupg.org> - - Adjusted for gcry_mpi_print and gcry_mpi_scan API change. - -2003-06-24 Werner Koch <wk@gnupg.org> - - * server.c (gpgsm_status_with_err_code): New. - * verify.c (gpgsm_verify): Use it here instead of the old - tokenizing version. - - * verify.c (strtimestamp): Renamed to strtimestamp_r - - Adjusted for changes in the libgcrypt API. Some more fixes for the - libgpg-error stuff. - -2003-06-04 Werner Koch <wk@gnupg.org> - - * call-agent.c (init_membuf,put_membuf,get_membuf): Removed. - Include new membuf header and changed used type. - - Renamed error codes from INVALID to INV and removed _ERROR suffixes. - -2003-06-03 Werner Koch <wk@gnupg.org> - - Changed all error codes in all files to the new libgpg-error scheme. - - * gpgsm.h: Include gpg-error.h . - * Makefile.am: Link with libgpg-error. - -2003-04-29 Werner Koch <wk@gnupg.org> - - * Makefile.am: Use libassuan. Don't override LDFLAGS anymore. - * server.c (register_commands): Adjust for new Assuan semantics. - -2002-12-03 Werner Koch <wk@gnupg.org> - - * call-agent.c (gpgsm_agent_passwd): New. - * gpgsm.c (main): New command --passwd and --call-protect-tool - (run_protect_tool): New. - -2002-11-25 Werner Koch <wk@gnupg.org> - - * verify.c (gpgsm_verify): Handle content-type attribute. - -2002-11-13 Werner Koch <wk@gnupg.org> - - * call-agent.c (start_agent): Try to use $GPG_TTY instead of - ttyname. Changed ttyname to test stdin becuase it can be assumed - that output redirection is more common that input redirection. - -2002-11-12 Werner Koch <wk@gnupg.org> - - * gpgsm.c: New command --call-dirmngr. - * call-dirmngr.c (gpgsm_dirmngr_run_command) - (run_command_inq_cb,run_command_cb) - (run_command_status_cb): New. - -2002-11-11 Werner Koch <wk@gnupg.org> - - * certcheck.c (gpgsm_check_cms_signature): Don't double free - s_sig but free s_pkey at leave. - -2002-11-10 Werner Koch <wk@gnupg.org> - - * gpgsm.c: Removed duplicate --list-secret-key entry. - -2002-09-19 Werner Koch <wk@gnupg.org> - - * certcheck.c (gpgsm_check_cert_sig): Add cert hash debugging. - - * certchain.c (find_up): Print info when the cert was not found - by the autorithyKeyIdentifier. - -2002-09-03 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Disable the internal libgcrypt locking. - -2002-08-21 Werner Koch <wk@gnupg.org> - - * import.c (print_imported_summary): Cleaned up. Print new - not_imported value. - (check_and_store): Update non_imported counter. - (print_import_problem): New. - (check_and_store): Print error status message. - * server.c (get_status_string): Added STATUS_IMPORT_PROBLEM. - -2002-08-20 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Use the log file only in server mode. - - * import.c (print_imported_summary): New. - (check_and_store): Update the counters, take new argument. - (import_one): Factored out core of gpgsm_import. - (gpgsm_import): Print counters. - (gpgsm_import_files): New. - * gpgsm.c (main): Use the new function for import. - -2002-08-19 Werner Koch <wk@gnupg.org> - - * decrypt.c (gpgsm_decrypt): Return a better error status token. - * verify.c (gpgsm_verify): Don't error on messages with no signing - time or no message digest. This is only the case for messages - without any signed attributes. - -2002-08-16 Werner Koch <wk@gnupg.org> - - * certpath.c: Renamed to .. - * certchain.c: this. Renamed all all other usages of "path" in the - context of certificates to "chain". - - * call-agent.c (learn_cb): Special treatment when the issuer - certificate is missing. - -2002-08-10 Werner Koch <wk@gnupg.org> - - * Makefile.am (INCLUDES): Add definition for localedir. - - * keylist.c (list_cert_colon): Print the short fingerprint in the - key ID field. - * fingerprint.c (gpgsm_get_short_fingerprint): New. - * verify.c (gpgsm_verify): Print more verbose info for a good - signature. - -2002-08-09 Werner Koch <wk@gnupg.org> - - * decrypt.c (prepare_decryption): Hack to detected already - unpkcsedone keys. - - * gpgsm.c (emergency_cleanup): New. - (main): Initialize the signal handler. - - * sign.c (gpgsm_sign): Reset the hash context for subsequent - signers and release it at the end. - -2002-08-05 Werner Koch <wk@gnupg.org> - - * server.c (cmd_signer): New command "SIGNER" - (register_commands): Register it. - (cmd_sign): Pass the signer list to gpgsm_sign. - * certlist.c (gpgsm_add_to_certlist): Add SECRET argument, check - for secret key if set and changed all callers. - * sign.c (gpgsm_sign): New argument SIGNERLIST and implemt - multiple signers. - * gpgsm.c (main): Support more than one -u. - - * server.c (cmd_recipient): Return reason code 1 for No_Public_Key - which is actually what gets returned from add_to_certlist. - -2002-07-26 Werner Koch <wk@gnupg.org> - - * certcheck.c (gpgsm_check_cert_sig): Implement proper cleanup. - (gpgsm_check_cms_signature): Ditto. - -2002-07-22 Werner Koch <wk@gnupg.org> - - * keydb.c (keydb_add_resource): Register a lock file. - (lock_all, unlock_all): Implemented. - - * delete.c: New. - * gpgsm.c: Made --delete-key work. - * server.c (cmd_delkeys): New. - (register_commands): New command DELKEYS. - - * decrypt.c (gpgsm_decrypt): Print a convenience note when RC2 is - used and a STATUS_ERROR with the algorithm oid. - -2002-07-03 Werner Koch <wk@gnupg.org> - - * server.c (gpgsm_status2): Insert a blank between all optional - arguments when using assuan. - * server.c (cmd_recipient): No more need for extra blank in constants. - * import.c (print_imported_status): Ditto. - * gpgsm.c (main): Ditto. - -2002-07-02 Werner Koch <wk@gnupg.org> - - * verify.c (gpgsm_verify): Extend the STATUS_BADSIG line with - the fingerprint. - - * certpath.c (check_cert_policy): Don't use log_error to print a - warning. - - * keydb.c (keydb_store_cert): Add optional ar EXISTED and changed - all callers. - * call-agent.c (learn_cb): Print info message only for real imports. - - * import.c (gpgsm_import): Moved duplicated code to ... - (check_and_store): new function. Added magic to import the entire - chain. Print status only for real imports and moved printing code - to .. - (print_imported_status): New. - - * call-dirmngr.c (gpgsm_dirmngr_isvalid): print status of dirmngr - call in very verbose mode. - - * gpgsm.c (main): Use the same error codes for STATUS_INV_RECP as - with the server mode. - -2002-06-29 Werner Koch <wk@gnupg.org> - - * gpgsm.c: New option --auto-issuer-key-retrieve. - * certpath.c (find_up): Try to retrieve an issuer key from an - external source and from the ephemeral key DB. - (find_up_store_certs_cb): New. - - * keydb.c (keydb_set_ephemeral): Does now return the old - state. Call the backend only when required. - - * call-dirmngr.c (start_dirmngr): Use GNUPG_DEFAULT_DIRMNGR. - (lookup_status_cb): Issue status only when CTRL is not NULL. - (gpgsm_dirmngr_lookup): Document that CTRL is optional. - - * call-agent.c (start_agent): Use GNUPG_DEFAULT_AGENT. - -2002-06-28 Werner Koch <wk@gnupg.org> - - * server.c (cmd_recipient): Add more reason codes. - -2002-06-27 Werner Koch <wk@gnupg.org> - - * certpath.c (gpgsm_basic_cert_check): Use - --debug-no-path-validation to also bypass this basic check. - - * gpgsm.c (main): Use GNUPG_DEFAULT_HOMEDIR constant. - - * call-agent.c (start_agent): Create and pass the list of FD to - keep in the child to assuan. - * call-dirmngr.c (start_dirmngr): Ditto. - -2002-06-26 Werner Koch <wk@gnupg.org> - - * import.c (gpgsm_import): Print an STATUS_IMPORTED. - - * gpgsm.c: --debug-no-path-validation does not take an argument. - -2002-06-25 Werner Koch <wk@gnupg.org> - - * certdump.c (print_dn_part): Always print a leading slash, - removed NEED_DELIM arg and changed caller. - - * export.c (gpgsm_export): Print LFs to FP and not stdout. - (print_short_info): Ditto. Make use of gpgsm_print_name. - - * server.c (cmd_export): Use output-fd instead of data lines; this - was actually the specified way. - -2002-06-24 Werner Koch <wk@gnupg.org> - - * gpgsm.c: Removed duped help entry for --list-keys. - - * gpgsm.c, gpgsm.h: New option --debug-no-path-validation. - - * certpath.c (gpgsm_validate_path): Use it here instead of the - debug flag hack. - - * certpath.c (check_cert_policy): Return No_Policy_Match if the - policy file could not be opened. - -2002-06-20 Werner Koch <wk@gnupg.org> - - * certlist.c (gpgsm_add_to_certlist): Fixed locating of a - certificate with the required key usage. - - * gpgsm.c (main): Fixed a segv when using --outfile without an - argument. - - * keylist.c (print_capabilities): Also check for non-repudiation - and data encipherment. - * certlist.c (cert_usage_p): Test for signing and encryption was - swapped. Add a case for certification usage, handle - non-repudiation and data encipherment. - (gpgsm_cert_use_cert_p): New. - (gpgsm_add_to_certlist): Added a CTRL argument and changed all - callers to pass it. - * certpath.c (gpgsm_validate_path): Use it here to print a status - message. Added a CTRL argument and changed all callers to pass it. - * decrypt.c (gpgsm_decrypt): Print a status message for wrong key - usage. - * verify.c (gpgsm_verify): Ditto. - * keydb.c (classify_user_id): Allow a colon delimited fingerprint. - -2002-06-19 Werner Koch <wk@gnupg.org> - - * call-agent.c (learn_cb): Use log_info instead of log_error on - successful import. - - * keydb.c (keydb_set_ephemeral): New. - (keydb_store_cert): New are ephemeral, changed all callers. - * keylist.c (list_external_cb): Store cert as ephemeral. - * export.c (gpgsm_export): Kludge to export epehmeral certificates. - - * gpgsm.c (main): New command --list-external-keys. - -2002-06-17 Werner Koch <wk@gnupg.org> - - * certreqgen.c (read_parameters): Improved error handling. - (gpgsm_genkey): Print error message. - -2002-06-13 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): New option --log-file. - -2002-06-12 Werner Koch <wk@gnupg.org> - - * call-dirmngr.c (lookup_status_cb): New. - (gpgsm_dirmngr_lookup): Use the status CB. Add new arg CTRL and - changed caller to pass it. - - * gpgsm.c (open_fwrite): New. - (main): Allow --output for --verify. - - * sign.c (hash_and_copy_data): New. - (gpgsm_sign): Implemented normal (non-detached) signatures. - * gpgsm.c (main): Ditto. - - * certpath.c (gpgsm_validate_path): Special error handling for - no policy match. - -2002-06-10 Werner Koch <wk@gnupg.org> - - * server.c (get_status_string): Add STATUS_ERROR. - - * certpath.c (gpgsm_validate_path): Tweaked the error checking to - return error codes in a more sensitive way. - * verify.c (gpgsm_verify): Send status TRUST_NEVER also for a bad - CA certificate and when the certificate has been revoked. Issue - TRUST_FULLY even when the cert has expired. Append an error token - to these status lines. Issue the new generic error status when a - cert was not found and when leaving the function. - -2002-06-04 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): New command --list-sigs - * keylist.c (list_cert_std): New. Use it whenever colon mode is - not used. - (list_cert_chain): New. - -2002-05-31 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Don't print the "go ahead" message for an - invalid command. - -2002-05-23 Werner Koch <wk@gnupg.org> - - * import.c (gpgsm_import): Add error messages. - -2002-05-21 Werner Koch <wk@gnupg.org> - - * keylist.c (list_internal_keys): Renamed from gpgsm_list_keys. - (list_external_keys): New. - (gpgsm_list_keys): Dispatcher for above. - * call-dirmngr.c (lookup_cb,pattern_from_strlist) - (gpgsm_dirmngr_lookup): New. - * server.c (option_handler): Handle new option --list-mode. - (do_listkeys): Handle options and actually use the mode argument. - (get_status_string): New code TRUNCATED. - - * import.c (gpgsm_import): Try to identify the type of input and - handle certs-only messages. - -2002-05-14 Werner Koch <wk@gnupg.org> - - * gpgsm.c: New option --faked-system-time - * sign.c (gpgsm_sign): And use it here. - * certpath.c (gpgsm_validate_path): Ditto. - -2002-05-03 Werner Koch <wk@gnupg.org> - - * certpath.c (gpgsm_validate_path): Added EXPTIME arg and changed - all callers. - * verify.c (gpgsm_verify): Tweaked usage of log_debug and - log_error. Return EXPSIG status and add expiretime to VALIDSIG. - -2002-04-26 Werner Koch <wk@gnupg.org> - - * gpgsm.h (DBG_AGENT,DBG_AGENT_VALUE): Replaced by DBG_ASSUAN_*. - Changed all users. - - * call-agent.c (start_agent): Be more silent without -v. - * call-dirmngr.c (start_dirmngr): Ditto. - -2002-04-25 Werner Koch <wk@gnupg.org> - - * call-agent.c (start_agent): Make copies of old locales and check - for setlocale. - -2002-04-25 Marcus Brinkmann <marcus@g10code.de> - - * call-agent.c (start_agent): Fix error handling logic so the - locale is always correctly reset. - -2002-04-25 Marcus Brinkmann <marcus@g10code.de> - - * server.c (option_handler): Accept display, ttyname, ttytype, - lc_ctype and lc_messages options. - * gpgsm.c (main): Allocate memory for these options. - * gpgsm.h (struct opt): Make corresponding members non-const. - -2002-04-24 Marcus Brinkmann <marcus@g10code.de> - - * gpgsm.h (struct opt): New members display, ttyname, ttytype, - lc_ctype, lc_messages. - * gpgsm.c (enum cmd_and_opt_values): New members oDisplay, - oTTYname, oTTYtype, oLCctype, oLCmessages. - (opts): New entries for these options. - (main): Handle these new options. - * call-agent.c (start_agent): Set the various display and tty - parameter after resetting. - -2002-04-18 Werner Koch <wk@gnupg.org> - - * certreqgen.c (gpgsm_genkey): Write status output on success. - -2002-04-15 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Check ksba version. - - * certpath.c (find_up): New to use the authorithKeyIdentifier. - Use it in all other functions to locate the signing cert.. - -2002-04-11 Werner Koch <wk@gnupg.org> - - * certlist.c (cert_usable_p): New. - (gpgsm_cert_use_sign_p,gpgsm_cert_use_encrypt_p): New. - (gpgsm_cert_use_verify_p,gpgsm_cert_use_decrypt_p): New. - (gpgsm_add_to_certlist): Check the key usage. - * sign.c (gpgsm_sign): Ditto. - * verify.c (gpgsm_verify): Print a message wehn an unsuitable - certificate was used. - * decrypt.c (gpgsm_decrypt): Ditto - * keylist.c (print_capabilities): Determine values from the cert. - -2002-03-28 Werner Koch <wk@gnupg.org> - - * keylist.c (list_cert_colon): Fixed listing of crt record; the - issuer is not at the right place. Print a chainingID. - * certpath.c (gpgsm_walk_cert_chain): Be a bit more silent on - common errors. - -2002-03-21 Werner Koch <wk@gnupg.org> - - * export.c: New. - * gpgsm.c: Add command --export. - * server.c (cmd_export): New. - -2002-03-13 Werner Koch <wk@gnupg.org> - - * decrypt.c (gpgsm_decrypt): Allow multiple recipients. - -2002-03-12 Werner Koch <wk@gnupg.org> - - * certpath.c (check_cert_policy): Print the policy list. - - * verify.c (gpgsm_verify): Detect certs-only message. - -2002-03-11 Werner Koch <wk@gnupg.org> - - * import.c (gpgsm_import): Print a notice about imported certificates - when in verbose mode. - - * gpgsm.c (main): Print INV_RECP status. - * server.c (cmd_recipient): Ditto. - - * server.c (gpgsm_status2): New. Allows for a list of strings. - (gpgsm_status): Divert to gpgsm_status2. - - * encrypt.c (gpgsm_encrypt): Don't use a default key when no - recipients are given. Print a NO_RECP status. - -2002-03-06 Werner Koch <wk@gnupg.org> - - * server.c (cmd_listkeys, cmd_listsecretkeys): Divert to - (do_listkeys): new. Add pattern parsing. - - * keylist.c (gpgsm_list_keys): Handle selection pattern. - - * gpgsm.c: New command --learn-card - * call-agent.c (learn_cb,gpgsm_agent_learn): New. - - * gpgsm.c (main): Print error messages for non-implemented commands. - - * base64.c (base64_reader_cb): Use case insensitive compare of the - Content-Type string to detect plain base-64. - -2002-03-05 Werner Koch <wk@gnupg.org> - - * gpgsm.c, gpgsm.h: Add local_user. - * sign.c (gpgsm_get_default_cert): New. - (get_default_signer): Use the new function if local_user is not - set otherwise used that value. - * encrypt.c (get_default_recipient): Removed. - (gpgsm_encrypt): Use gpgsm_get_default_cert. - - * verify.c (gpgsm_verify): Better error text for a bad signature - found by comparing the hashs. - -2002-02-27 Werner Koch <wk@gnupg.org> - - * call-dirmngr.c, call-agent.c: Add 2 more arguments to all uses - of assuan_transact. - -2002-02-25 Werner Koch <wk@gnupg.org> - - * server.c (option_handler): Allow to use -2 for "send all certs - except the root cert". - * sign.c (add_certificate_list): Implement it here. - * certpath.c (gpgsm_is_root_cert): New. - -2002-02-19 Werner Koch <wk@gnupg.org> - - * certpath.c (check_cert_policy): New. - (gpgsm_validate_path): And call it from here. - * gpgsm.c (main): New options --policy-file, - --disable-policy-checks and --enable-policy-checks. - * gpgsm.h (opt): Added policy_file, no_policy_checks. - -2002-02-18 Werner Koch <wk@gnupg.org> - - * certpath.c (gpgsm_validate_path): Ask the agent to add the - certificate into the trusted list. - * call-agent.c (gpgsm_agent_marktrusted): New. - -2002-02-07 Werner Koch <wk@gnupg.org> - - * certlist.c (gpgsm_add_to_certlist): Check that the specified - name identifies a certificate unambiguously. - (gpgsm_find_cert): Ditto. - - * server.c (cmd_listkeys): Check that the data stream is available. - (cmd_listsecretkeys): Ditto. - (has_option): New. - (cmd_sign): Fix ambiguousity in option recognition. - - * gpgsm.c (main): Enable --logger-fd. - - * encrypt.c (gpgsm_encrypt): Increased buffer size for better - performance. - - * call-agent.c (gpgsm_agent_pksign): Check the S-Exp received from - the agent. - - * keylist.c (list_cert_colon): Filter out control characters. - -2002-02-06 Werner Koch <wk@gnupg.org> - - * decrypt.c (gpgsm_decrypt): Bail out after an decryption error. - - * server.c (reset_notify): Close input and output FDs. - (cmd_encrypt,cmd_decrypt,cmd_verify,cmd_sign.cmd_import) - (cmd_genkey): Close the FDs and release the recipient list even in - the error case. - -2002-02-01 Marcus Brinkmann <marcus@g10code.de> - - * sign.c (gpgsm_sign): Do not release certificate twice. - -2002-01-29 Werner Koch <wk@gnupg.org> - - * call-agent.c (gpgsm_agent_havekey): New. - * keylist.c (list_cert_colon): New arg HAVE_SECRET, print "crs" - when we know that the secret key is available. - (gpgsm_list_keys): New arg MODE, check whether a secret key is - available. Changed all callers. - * gpgsm.c (main): New command --list-secret-keys. - * server.c (cmd_listsecretkeys): New. - (cmd_listkeys): Return secret keys with "crs" record. - -2002-01-28 Werner Koch <wk@gnupg.org> - - * certreqgen.c (create_request): Store the email address in the req. - -2002-01-25 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Disable core dumps. - - * sign.c (add_certificate_list): New. - (gpgsm_sign): Add the certificates to the CMS object. - * certpath.c (gpgsm_walk_cert_chain): New. - * gpgsm.h (server_control_s): Add included_certs. - * gpgsm.c: Add option --include-certs. - (gpgsm_init_default_ctrl): New. - (main): Call it. - * server.c (gpgsm_server): Ditto. - (option_handler): Support --include-certs. - -2002-01-23 Werner Koch <wk@gnupg.org> - - * certpath.c (gpgsm_validate_path): Print the DN of a missing issuer. - * certdump.c (gpgsm_dump_string): New. - (print_dn): Replaced by above. - -2002-01-22 Werner Koch <wk@gnupg.org> - - * certpath.c (unknown_criticals): New. - (allowed_ca): New. - (gpgsm_validate_path): Check validity, CA attribute, path length - and unknown critical extensions. - -2002-01-21 Werner Koch <wk@gnupg.org> - - * gpgsm.c: Add option --enable-crl-checks. - - * call-agent.c (start_agent): Implemented socket based access. - * call-dirmngr.c (start_dirmngr): Ditto. - -2002-01-20 Werner Koch <wk@gnupg.org> - - * server.c (option_handler): New. - (gpgsm_server): Register it with assuan. - -2002-01-19 Werner Koch <wk@gnupg.org> - - * server.c (gpgsm_server): Use assuan_deinit_server and setup - assuan logging if enabled. - * call-agent.c (inq_ciphertext_cb): Don't show the session key in - an Assuan log file. - - * gpgsm.c (my_strusage): Take bugreport address from configure.ac - -2002-01-15 Werner Koch <wk@gnupg.org> - - * import.c (gpgsm_import): Just do a basic cert check before - storing it. - * certpath.c (gpgsm_basic_cert_check): New. - - * keydb.c (keydb_store_cert): New. - * import.c (store_cert): Removed and change all caller to use - the new function. - * verify.c (store_cert): Ditto. - - * certlist.c (gpgsm_add_to_certlist): Validate the path - - * certpath.c (gpgsm_validate_path): Check the trust list. - * call-agent.c (gpgsm_agent_istrusted): New. - -2002-01-14 Werner Koch <wk@gnupg.org> - - * call-dirmngr.c (inq_certificate): Changed for new interface semantic. - * certlist.c (gpgsm_find_cert): New. - -2002-01-13 Werner Koch <wk@gnupg.org> - - * fingerprint.c (gpgsm_get_certid): Print the serial and not the - hash after the dot. - -2002-01-11 Werner Koch <wk@gnupg.org> - - * call-dirmngr.c: New. - * certpath.c (gpgsm_validate_path): Check the CRL here. - * fingerprint.c (gpgsm_get_certid): New. - * gpgsm.c: New options --dirmngr-program and --disable-crl-checks. - -2002-01-10 Werner Koch <wk@gnupg.org> - - * base64.c (gpgsm_create_writer): Allow to set the object name - -2002-01-08 Werner Koch <wk@gnupg.org> - - * keydb.c (spacep): Removed because it is now in util.c - - * server.c (cmd_genkey): New. - * certreqgen.c: New. The parameter handling code has been taken - from gnupg/g10/keygen.c version 1.0.6. - * call-agent.c (gpgsm_agent_genkey): New. - -2002-01-02 Werner Koch <wk@gnupg.org> - - * server.c (rc_to_assuan_status): Removed and changed all callers - to use map_to_assuan_status. - -2001-12-20 Werner Koch <wk@gnupg.org> - - * verify.c (gpgsm_verify): Implemented non-detached signature - verification. Add OUT_FP arg, initialize a writer and changed all - callers. - * server.c (cmd_verify): Pass an out_fp if one has been set. - - * base64.c (base64_reader_cb): Try to detect an S/MIME body part. - - * certdump.c (print_sexp): Renamed to gpgsm_dump_serial, made - global. - (print_time): Renamed to gpgsm_dump_time, made global. - (gpgsm_dump_serial): Take a real S-Expression as argument and - print the first item. - * keylist.c (list_cert_colon): Ditto. - * keydb.c (keydb_search_issuer_sn): Ditto. - * decrypt.c (print_integer_sexp): Removed and made callers - use gpgsm_dump_serial. - * verify.c (print_time): Removed, made callers use gpgsm_dump_time. - -2001-12-19 Marcus Brinkmann <marcus@g10code.de> - - * call-agent.c (start_agent): Add new argument to assuan_pipe_connect. - -2001-12-18 Werner Koch <wk@gnupg.org> - - * verify.c (print_integer_sexp): Renamed from print_integer and - print the serial number according to the S-Exp rules. - * decrypt.c (print_integer_sexp): Ditto. - -2001-12-17 Werner Koch <wk@gnupg.org> - - * keylist.c (list_cert_colon): Changed for new return value of - get_serial. - * keydb.c (keydb_search_issuer_sn): Ditto. - * certcheck.c (gpgsm_check_cert_sig): Likewise for other S-Exp - returingin functions. - * fingerprint.c (gpgsm_get_keygrip): Ditto. - * encrypt.c (encrypt_dek): Ditto - * certcheck.c (gpgsm_check_cms_signature): Ditto - * decrypt.c (prepare_decryption): Ditto. - * call-agent.c (gpgsm_agent_pkdecrypt): Removed arg ciphertextlen, - use KsbaSexp type and calculate the length. - - * certdump.c (print_sexp): Remaned from print_integer, changed caller. - - * Makefile.am: Use the LIBGCRYPT and LIBKSBA variables. - - * fingerprint.c (gpgsm_get_keygrip): Use the new - gcry_pk_get_keygrip to calculate the grip - note the algorithm and - therefore the grip values changed. - -2001-12-15 Werner Koch <wk@gnupg.org> - - * certcheck.c (gpgsm_check_cms_signature): Removed the faked-key - kludge. - (gpgsm_create_cms_signature): Removed the commented fake key - code. This makes the function pretty simple. - - * gpgsm.c (main): Renamed the default key database to "keyring.kbx". - - * decrypt.c (gpgsm_decrypt): Write STATUS_DECRYPTION_*. - * sign.c (gpgsm_sign): Write a STATUS_SIG_CREATED. - -2001-12-14 Werner Koch <wk@gnupg.org> - - * keylist.c (list_cert_colon): Kludge to show an email address - encoded in the subject's DN. - - * verify.c (gpgsm_verify): Add hash debug helpers - * sign.c (gpgsm_sign): Ditto. - - * base64.c (base64_reader_cb): Reset the linelen when we need to - skip the line and adjusted test; I somehow forgot about DeMorgan. - - * server.c (cmd_encrypt,cmd_decrypt,cmd_sign,cmd_verify) - (cmd_import): Close the FDs on success. - (close_message_fd): New. - (input_notify): Setting autodetect_encoding to 0 after initializing - it to 0 is pretty pointless. Easy to fix. - - * gpgsm.c (main): New option --debug-wait n, so that it is - possible to attach gdb when used in server mode. - - * sign.c (get_default_signer): Use keydb_classify_name here. - -2001-12-14 Marcus Brinkmann <marcus@g10code.de> - - * call-agent.c (LINELENGTH): Removed. - (gpgsm_agent_pksign): Use ASSUAN_LINELENGTH, not LINELENGTH. - (gpgsm_agent_pkdecrypt): Likewise. - -2001-12-13 Werner Koch <wk@gnupg.org> - - * keylist.c (list_cert_colon): Print alternative names of subject - and a few other values. - -2001-12-12 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): New options --assume-{armor,base64,binary}. - * base64.c (base64_reader_cb): Fixed non-autodetection mode. - -2001-12-04 Werner Koch <wk@gnupg.org> - - * call-agent.c (read_from_agent): Check for inquire responses. - (request_reply): Handle them using a new callback arg, changed all - callers. - (gpgsm_agent_pkdecrypt): New. - -2001-11-27 Werner Koch <wk@gnupg.org> - - * base64.c: New. Changed all other functions to use this instead - of direct creation of ksba_reader/writer. - * gpgsm.c (main): Set ctrl.auto_encoding unless --no-armor is used. - -2001-11-26 Werner Koch <wk@gnupg.org> - - * gpgsm.c: New option --agent-program - * call-agent.c (start_agent): Allow to override the default path - to the agent. - - * keydb.c (keydb_add_resource): Create keybox - - * keylist.c (gpgsm_list_keys): Fixed non-server keylisting. - - * server.c (rc_to_assuan_status): New. Use it for all commands. - - - Copyright 2001, 2002, 2003 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. diff --git a/sm/Makefile.am b/sm/Makefile.am deleted file mode 100644 index 1ac7cbe84..000000000 --- a/sm/Makefile.am +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - - -bin_PROGRAMS = gpgsm - -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(KSBA_CFLAGS) - -AM_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/intl -include $(top_srcdir)/am/cmacros.am - - -gpgsm_SOURCES = \ - gpgsm.c gpgsm.h \ - misc.c \ - keydb.c keydb.h \ - server.c \ - call-agent.c \ - call-dirmngr.c \ - fingerprint.c \ - base64.c \ - certlist.c \ - certdump.c \ - certcheck.c \ - certchain.c \ - keylist.c \ - verify.c \ - sign.c \ - encrypt.c \ - decrypt.c \ - import.c \ - export.c \ - delete.c \ - certreqgen.c - - -gpgsm_LDADD = ../jnlib/libjnlib.a ../kbx/libkeybox.a ../common/libcommon.a \ - $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(KSBA_LIBS) -lgpg-error \ - $(INTLLIBS) diff --git a/sm/base64.c b/sm/base64.c deleted file mode 100644 index 4cc6ffa27..000000000 --- a/sm/base64.c +++ /dev/null @@ -1,655 +0,0 @@ -/* base64.c - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" - -#include <ksba.h> - -#include "i18n.h" - -#ifdef HAVE_DOSISH_SYSTEM - #define LF "\r\n" -#else - #define LF "\n" -#endif - -/* data used by the reader callbacks */ -struct reader_cb_parm_s { - FILE *fp; - unsigned char line[1024]; - int linelen; - int readpos; - int have_lf; - unsigned long line_counter; - - int allow_multi_pem; /* Allow processing of multiple PEM objects. */ - int autodetect; /* Try to detect the input encoding. */ - int assume_pem; /* Assume input encoding is PEM. */ - int assume_base64; /* Assume input is base64 encoded. */ - - int identified; - int is_pem; - int is_base64; - int stop_seen; - int might_be_smime; - - int eof_seen; - - struct { - int idx; - unsigned char val; - int stop_seen; - } base64; -}; - -/* data used by the writer callbacks */ -struct writer_cb_parm_s { - FILE *fp; - const char *pem_name; - - int wrote_begin; - int did_finish; - - struct { - int idx; - int quad_count; - unsigned char radbuf[4]; - } base64; - -}; - - -/* context for this module's functions */ -struct base64_context_s { - union { - struct reader_cb_parm_s rparm; - struct writer_cb_parm_s wparm; - } u; -}; - - -/* The base-64 character list */ -static unsigned char bintoasc[64] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; -/* The reverse base-64 list */ -static unsigned char asctobin[256] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff -}; - - -static int -has_only_base64 (const unsigned char *line, int linelen) -{ - if (linelen < 20) - return 0; - for (; linelen; line++, linelen--) - { - if (*line == '\n' || (linelen > 1 && *line == '\r' && line[1] == '\n')) - break; - if ( !strchr (bintoasc, *line) ) - return 0; - } - return 1; /* yes */ -} - -static int -is_empty_line (const unsigned char *line, int linelen) -{ - if (linelen >= 2 && *line == '\r' && line[1] == '\n') - return 1; - if (linelen >= 1 && *line == '\n') - return 1; - return 0; -} - - -static int -base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) -{ - struct reader_cb_parm_s *parm = cb_value; - size_t n; - int c, c2; - - *nread = 0; - if (!buffer) - return -1; /* not supported */ - - next: - if (!parm->linelen) - { - /* read an entire line or up to the size of the buffer */ - parm->line_counter++; - parm->have_lf = 0; - for (n=0; n < DIM(parm->line);) - { - c = getc (parm->fp); - if (c == EOF) - { - parm->eof_seen = 1; - if (ferror (parm->fp)) - return -1; - break; - } - parm->line[n++] = c; - if (c == '\n') - { - parm->have_lf = 1; - /* Fixme: we need to skip overlong lines while detecting - the dashed lines */ - break; - } - } - parm->linelen = n; - if (!n) - return -1; /* eof */ - parm->readpos = 0; - } - - if (!parm->identified) - { - if (!parm->autodetect) - { - if (parm->assume_pem) - { - /* wait for the header line */ - parm->linelen = parm->readpos = 0; - if (!parm->have_lf || strncmp (parm->line, "-----BEGIN ", 11) - || !strncmp (parm->line+11, "PGP ", 4)) - goto next; - parm->is_pem = 1; - } - else if (parm->assume_base64) - parm->is_base64 = 1; - } - else if (parm->line_counter == 1 && !parm->have_lf) - { - /* first line too long - assume DER encoding */ - parm->is_pem = 0; - } - else if (parm->line_counter == 1 && parm->linelen && *parm->line == 0x30) - { - /* the very first byte does pretty much look like a SEQUENCE tag*/ - parm->is_pem = 0; - } - else if ( parm->have_lf && !strncmp (parm->line, "-----BEGIN ", 11) - && strncmp (parm->line+11, "PGP ", 4) ) - { - /* Fixme: we must only compare if the line really starts at - the beginning */ - parm->is_pem = 1; - parm->linelen = parm->readpos = 0; - } - else if ( parm->have_lf && parm->line_counter == 1 - && parm->linelen >= 13 - && !ascii_memcasecmp (parm->line, "Content-Type:", 13)) - { /* might be a S/MIME body */ - parm->might_be_smime = 1; - parm->linelen = parm->readpos = 0; - goto next; - } - else if (parm->might_be_smime == 1 - && is_empty_line (parm->line, parm->linelen)) - { - parm->might_be_smime = 2; - parm->linelen = parm->readpos = 0; - goto next; - } - else if (parm->might_be_smime == 2) - { - parm->might_be_smime = 0; - if ( !has_only_base64 (parm->line, parm->linelen)) - { - parm->linelen = parm->readpos = 0; - goto next; - } - parm->is_pem = 1; - } - else - { - parm->linelen = parm->readpos = 0; - goto next; - } - parm->identified = 1; - parm->base64.stop_seen = 0; - parm->base64.idx = 0; - } - - - n = 0; - if (parm->is_pem || parm->is_base64) - { - if (parm->is_pem && parm->have_lf - && !strncmp (parm->line, "-----END ", 9)) - { - parm->identified = 0; - parm->linelen = parm->readpos = 0; - - /* If the caller want to read multiple PEM objects from one - file, we have to reset our internal state and return a - EOF immediately. The caller is the expected to use - ksba_reader_clear to clear the EOF condition and continue - to read. If we don't want to do that we just return 0 - bytes which will force the ksba_reader to skip until - EOF. */ - if (parm->allow_multi_pem) - { - parm->identified = 0; - parm->autodetect = 0; - parm->assume_pem = 1; - parm->stop_seen = 0; - return -1; /* Send EOF now. */ - } - } - else if (parm->stop_seen) - { /* skip the rest of the line */ - parm->linelen = parm->readpos = 0; - } - else - { - int idx = parm->base64.idx; - unsigned char val = parm->base64.val; - - while (n < count && parm->readpos < parm->linelen ) - { - c = parm->line[parm->readpos++]; - if (c == '\n' || c == ' ' || c == '\r' || c == '\t') - continue; - if (c == '=') - { /* pad character: stop */ - if (idx == 1) - buffer[n++] = val; - parm->stop_seen = 1; - break; - } - if( (c = asctobin[(c2=c)]) == 255 ) - { - log_error (_("invalid radix64 character %02x skipped\n"), - c2); - continue; - } - switch (idx) - { - case 0: - val = c << 2; - break; - case 1: - val |= (c>>4)&3; - buffer[n++] = val; - val = (c<<4)&0xf0; - break; - case 2: - val |= (c>>2)&15; - buffer[n++] = val; - val = (c<<6)&0xc0; - break; - case 3: - val |= c&0x3f; - buffer[n++] = val; - break; - } - idx = (idx+1) % 4; - } - if (parm->readpos == parm->linelen) - parm->linelen = parm->readpos = 0; - - parm->base64.idx = idx; - parm->base64.val = val; - } - } - else - { /* DER encoded */ - while (n < count && parm->readpos < parm->linelen) - buffer[n++] = parm->line[parm->readpos++]; - if (parm->readpos == parm->linelen) - parm->linelen = parm->readpos = 0; - } - - *nread = n; - return 0; -} - - - -static int -simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) -{ - struct reader_cb_parm_s *parm = cb_value; - size_t n; - int c = 0; - - *nread = 0; - if (!buffer) - return -1; /* not supported */ - - for (n=0; n < count; n++) - { - c = getc (parm->fp); - if (c == EOF) - { - parm->eof_seen = 1; - if ( ferror (parm->fp) ) - return -1; - if (n) - break; /* return what we have before an EOF */ - return -1; - } - *(byte *)buffer++ = c; - } - - *nread = n; - return 0; -} - - - - -static int -base64_writer_cb (void *cb_value, const void *buffer, size_t count) -{ - struct writer_cb_parm_s *parm = cb_value; - unsigned char radbuf[4]; - int i, c, idx, quad_count; - const unsigned char *p; - FILE *fp = parm->fp; - - if (!count) - return 0; - - if (!parm->wrote_begin) - { - if (parm->pem_name) - { - fputs ("-----BEGIN ", fp); - fputs (parm->pem_name, fp); - fputs ("-----\n", fp); - } - parm->wrote_begin = 1; - parm->base64.idx = 0; - parm->base64.quad_count = 0; - } - - idx = parm->base64.idx; - quad_count = parm->base64.quad_count; - for (i=0; i < idx; i++) - radbuf[i] = parm->base64.radbuf[i]; - - for (p=buffer; count; p++, count--) - { - radbuf[idx++] = *p; - if (idx > 2) - { - idx = 0; - c = bintoasc[(*radbuf >> 2) & 077]; - putc (c, fp); - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077]; - putc (c, fp); - c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; - putc (c, fp); - c = bintoasc[radbuf[2]&077]; - putc (c, fp); - if (++quad_count >= (64/4)) - { - fputs (LF, fp); - quad_count = 0; - } - } - } - for (i=0; i < idx; i++) - parm->base64.radbuf[i] = radbuf[i]; - parm->base64.idx = idx; - parm->base64.quad_count = quad_count; - - return ferror (fp) ? gpg_error_from_errno (errno) : 0; -} - -static int -base64_finish_write (struct writer_cb_parm_s *parm) -{ - unsigned char radbuf[4]; - int i, c, idx, quad_count; - FILE *fp = parm->fp; - - if (!parm->wrote_begin) - return 0; /* nothing written */ - - /* flush the base64 encoding */ - idx = parm->base64.idx; - quad_count = parm->base64.quad_count; - for (i=0; i < idx; i++) - radbuf[i] = parm->base64.radbuf[i]; - - if (idx) - { - c = bintoasc[(*radbuf>>2)&077]; - putc (c, fp); - if (idx == 1) - { - c = bintoasc[((*radbuf << 4) & 060) & 077]; - putc (c, fp); - putc ('=', fp); - putc ('=', fp); - } - else - { - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077]; - putc (c, fp); - c = bintoasc[((radbuf[1] << 2) & 074) & 077]; - putc (c, fp); - putc ('=', fp); - - } - if (++quad_count >= (64/4)) - { - fputs (LF, fp); - quad_count = 0; - } - } - - if (quad_count) - fputs (LF, fp); - - if (parm->pem_name) - { - fputs ("-----END ", fp); - fputs (parm->pem_name, fp); - fputs ("-----\n", fp); - } - return ferror (fp)? gpg_error (gpg_err_code_from_errno (errno)) : 0; -} - - - - -/* Create a reader for the given file descriptor. Depending on the - control information an input decoding is automagically choosen. - The function returns a Base64Context object which must be passed to - the gpgme_destroy_reader function. The created KsbaReader object - is also returned, but the caller must not call the - ksba_reader_release function on. If ALLOW_MULTI_PEM is true, the - reader expects that the caller uses ksba_reader_clear after EOF - until no more objects were found. */ -int -gpgsm_create_reader (Base64Context *ctx, - CTRL ctrl, FILE *fp, int allow_multi_pem, - ksba_reader_t *r_reader) -{ - int rc; - ksba_reader_t r; - - *r_reader = NULL; - *ctx = xtrycalloc (1, sizeof **ctx); - if (!*ctx) - return OUT_OF_CORE (errno); - (*ctx)->u.rparm.allow_multi_pem = allow_multi_pem; - - rc = ksba_reader_new (&r); - if (rc) - { - xfree (*ctx); *ctx = NULL; - return rc; - } - - (*ctx)->u.rparm.fp = fp; - if (ctrl->is_pem) - { - (*ctx)->u.rparm.assume_pem = 1; - (*ctx)->u.rparm.assume_base64 = 1; - rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); - } - else if (ctrl->is_base64) - { - (*ctx)->u.rparm.assume_base64 = 1; - rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); - } - else if (ctrl->autodetect_encoding) - { - (*ctx)->u.rparm.autodetect = 1; - rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); - } - else - rc = ksba_reader_set_cb (r, simple_reader_cb, &(*ctx)->u.rparm); - - if (rc) - { - ksba_reader_release (r); - xfree (*ctx); *ctx = NULL; - return rc; - } - - *r_reader = r; - return 0; -} - - -int -gpgsm_reader_eof_seen (Base64Context ctx) -{ - return ctx && ctx->u.rparm.eof_seen; -} - -void -gpgsm_destroy_reader (Base64Context ctx) -{ - xfree (ctx); -} - - - -/* Create a writer for the given stream. Depending on the control - information an output encoding is automagically choosen. The - function returns a Base64Context object which must be passed to the - gpgme_destroy_writer function. The created KsbaWriter object is - also returned, but the caller must not call the ksba_reader_release - function on. */ -int -gpgsm_create_writer (Base64Context *ctx, - CTRL ctrl, FILE *fp, ksba_writer_t *r_writer) -{ - int rc; - ksba_writer_t w; - - *r_writer = NULL; - *ctx = xtrycalloc (1, sizeof **ctx); - if (!*ctx) - return OUT_OF_CORE (errno); - - rc = ksba_writer_new (&w); - if (rc) - { - xfree (*ctx); *ctx = NULL; - return rc; - } - - if (ctrl->create_pem || ctrl->create_base64) - { - (*ctx)->u.wparm.fp = fp; - if (ctrl->create_pem) - (*ctx)->u.wparm.pem_name = ctrl->pem_name? ctrl->pem_name - : "CMS OBJECT"; - rc = ksba_writer_set_cb (w, base64_writer_cb, &(*ctx)->u.wparm); - } - else - rc = ksba_writer_set_file (w, fp); - - if (rc) - { - ksba_writer_release (w); - xfree (*ctx); *ctx = NULL; - return rc; - } - - *r_writer = w; - return 0; -} - - -int -gpgsm_finish_writer (Base64Context ctx) -{ - struct writer_cb_parm_s *parm; - - if (!ctx) - return gpg_error (GPG_ERR_INV_VALUE); - parm = &ctx->u.wparm; - if (parm->did_finish) - return 0; /* already done */ - parm->did_finish = 1; - if (!parm->fp) - return 0; /* callback was not used */ - return base64_finish_write (parm); -} - -void -gpgsm_destroy_writer (Base64Context ctx) -{ - xfree (ctx); -} diff --git a/sm/call-agent.c b/sm/call-agent.c deleted file mode 100644 index 2e8c75496..000000000 --- a/sm/call-agent.c +++ /dev/null @@ -1,635 +0,0 @@ -/* call-agent.c - divert operations to the agent - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif - -#include "gpgsm.h" -#include <gcrypt.h> -#include <assuan.h> -#include "i18n.h" -#include "asshelp.h" -#include "keydb.h" /* fixme: Move this to import.c */ -#include "../common/membuf.h" - - -static ASSUAN_CONTEXT agent_ctx = NULL; -static int force_pipe_server = 0; - -struct cipher_parm_s { - ASSUAN_CONTEXT ctx; - const char *ciphertext; - size_t ciphertextlen; -}; - -struct genkey_parm_s { - ASSUAN_CONTEXT ctx; - const char *sexp; - size_t sexplen; -}; - -struct learn_parm_s { - int error; - ASSUAN_CONTEXT ctx; - membuf_t *data; -}; - - - -/* Try to connect to the agent via socket or fork it off and work by - pipes. Handle the server's initial greeting */ -static int -start_agent (ctrl_t ctrl) -{ - int rc = 0; - char *infostr, *p; - assuan_context_t ctx; - - if (agent_ctx) - return 0; /* fixme: We need a context for each thread or serialize - the access to the agent (which is suitable given that - the agent is not MT. */ - - infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO"); - if (!infostr || !*infostr) - { - const char *pgmname; - const char *argv[3]; - int no_close_list[3]; - int i; - - if (opt.verbose) - log_info (_("no running gpg-agent - starting one\n")); - - gpgsm_status (ctrl, STATUS_PROGRESS, "starting_agent ? 0 0"); - - if (fflush (NULL)) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("error flushing pending output: %s\n", strerror (errno)); - return tmperr; - } - - if (!opt.agent_program || !*opt.agent_program) - opt.agent_program = GNUPG_DEFAULT_AGENT; - if ( !(pgmname = strrchr (opt.agent_program, '/'))) - pgmname = opt.agent_program; - else - pgmname++; - - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; - - i=0; - if (log_get_fd () != -1) - no_close_list[i++] = log_get_fd (); - no_close_list[i++] = fileno (stderr); - no_close_list[i] = -1; - - /* connect to the agent and perform initial handshaking */ - rc = assuan_pipe_connect (&ctx, opt.agent_program, (char**)argv, - no_close_list); - } - else - { - int prot; - int pid; - - infostr = xstrdup (infostr); - if ( !(p = strchr (infostr, ':')) || p == infostr) - { - log_error (_("malformed GPG_AGENT_INFO environment variable\n")); - xfree (infostr); - force_pipe_server = 1; - return start_agent (ctrl); - } - *p++ = 0; - pid = atoi (p); - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if (prot != 1) - { - log_error (_("gpg-agent protocol version %d is not supported\n"), - prot); - xfree (infostr); - force_pipe_server = 1; - return start_agent (ctrl); - } - - rc = assuan_socket_connect (&ctx, infostr, pid); - xfree (infostr); - if (rc == ASSUAN_Connect_Failed) - { - log_error (_("can't connect to the agent - trying fall back\n")); - force_pipe_server = 1; - return start_agent (ctrl); - } - } - - if (rc) - { - log_error ("can't connect to the agent: %s\n", assuan_strerror (rc)); - return gpg_error (GPG_ERR_NO_AGENT); - } - agent_ctx = ctx; - - if (DBG_ASSUAN) - log_debug ("connection to agent established\n"); - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - return send_pinentry_environment (agent_ctx, - opt.display, opt.ttyname, opt.ttytype, - opt.lc_ctype, opt.lc_messages); -} - - -static AssuanError -membuf_data_cb (void *opaque, const void *buffer, size_t length) -{ - membuf_t *data = opaque; - - if (buffer) - put_membuf (data, buffer, length); - return 0; -} - - - - -/* Call the agent to do a sign operation using the key identified by - the hex string KEYGRIP. */ -int -gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc, - unsigned char *digest, size_t digestlen, int digestalgo, - char **r_buf, size_t *r_buflen ) -{ - int rc, i; - char *p, line[ASSUAN_LINELENGTH]; - membuf_t data; - size_t len; - - *r_buf = NULL; - rc = start_agent (ctrl); - if (rc) - return rc; - - if (digestlen*2 + 50 > DIM(line)) - return gpg_error (GPG_ERR_GENERAL); - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - snprintf (line, DIM(line)-1, "SIGKEY %s", keygrip); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - if (desc) - { - snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - } - - sprintf (line, "SETHASH %d ", digestalgo); - p = line + strlen (line); - for (i=0; i < digestlen ; i++, p += 2 ) - sprintf (p, "%02X", digest[i]); - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - init_membuf (&data, 1024); - rc = assuan_transact (agent_ctx, "PKSIGN", - membuf_data_cb, &data, NULL, NULL, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - *r_buf = get_membuf (&data, r_buflen); - - if (!gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL)) - { - xfree (*r_buf); *r_buf = NULL; - return gpg_error (GPG_ERR_INV_VALUE); - } - - return *r_buf? 0 : OUT_OF_CORE (errno); -} - - - - -/* Handle a CIPHERTEXT inquiry. Note, we only send the data, - assuan_transact talkes care of flushing and writing the end */ -static AssuanError -inq_ciphertext_cb (void *opaque, const char *keyword) -{ - struct cipher_parm_s *parm = opaque; - AssuanError rc; - - assuan_begin_confidential (parm->ctx); - rc = assuan_send_data (parm->ctx, parm->ciphertext, parm->ciphertextlen); - assuan_end_confidential (parm->ctx); - return rc; -} - - -/* Call the agent to do a decrypt operation using the key identified by - the hex string KEYGRIP. */ -int -gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, - ksba_const_sexp_t ciphertext, - char **r_buf, size_t *r_buflen ) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - membuf_t data; - struct cipher_parm_s cipher_parm; - size_t n, len; - char *buf, *endp; - size_t ciphertextlen; - - if (!keygrip || strlen(keygrip) != 40 || !ciphertext || !r_buf || !r_buflen) - return gpg_error (GPG_ERR_INV_VALUE); - *r_buf = NULL; - - ciphertextlen = gcry_sexp_canon_len (ciphertext, 0, NULL, NULL); - if (!ciphertextlen) - return gpg_error (GPG_ERR_INV_VALUE); - - rc = start_agent (ctrl); - if (rc) - return rc; - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - assert ( DIM(line) >= 50 ); - snprintf (line, DIM(line)-1, "SETKEY %s", keygrip); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - if (desc) - { - snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - } - - init_membuf (&data, 1024); - cipher_parm.ctx = agent_ctx; - cipher_parm.ciphertext = ciphertext; - cipher_parm.ciphertextlen = ciphertextlen; - rc = assuan_transact (agent_ctx, "PKDECRYPT", - membuf_data_cb, &data, - inq_ciphertext_cb, &cipher_parm, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - - put_membuf (&data, "", 1); /* make sure it is 0 terminated */ - buf = get_membuf (&data, &len); - if (!buf) - return gpg_error (GPG_ERR_ENOMEM); - /* FIXME: We would better a return a full S-exp and not just a part */ - assert (len); - len--; /* remove the terminating 0 */ - n = strtoul (buf, &endp, 10); - if (!n || *endp != ':') - return gpg_error (GPG_ERR_INV_SEXP); - endp++; - if (endp-buf+n > len) - return gpg_error (GPG_ERR_INV_SEXP); /* oops len does not - match internal len*/ - memmove (buf, endp, n); - *r_buflen = n; - *r_buf = buf; - return 0; -} - - - - - -/* Handle a KEYPARMS inquiry. Note, we only send the data, - assuan_transact takes care of flushing and writing the end */ -static AssuanError -inq_genkey_parms (void *opaque, const char *keyword) -{ - struct genkey_parm_s *parm = opaque; - AssuanError rc; - - rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen); - return rc; -} - - - -/* Call the agent to generate a newkey */ -int -gpgsm_agent_genkey (ctrl_t ctrl, - ksba_const_sexp_t keyparms, ksba_sexp_t *r_pubkey) -{ - int rc; - struct genkey_parm_s gk_parm; - membuf_t data; - size_t len; - char *buf; - - *r_pubkey = NULL; - rc = start_agent (ctrl); - if (rc) - return rc; - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - init_membuf (&data, 1024); - gk_parm.ctx = agent_ctx; - gk_parm.sexp = keyparms; - gk_parm.sexplen = gcry_sexp_canon_len (keyparms, 0, NULL, NULL); - if (!gk_parm.sexplen) - return gpg_error (GPG_ERR_INV_VALUE); - rc = assuan_transact (agent_ctx, "GENKEY", - membuf_data_cb, &data, - inq_genkey_parms, &gk_parm, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - buf = get_membuf (&data, &len); - if (!buf) - return gpg_error (GPG_ERR_ENOMEM); - if (!gcry_sexp_canon_len (buf, len, NULL, NULL)) - { - xfree (buf); - return gpg_error (GPG_ERR_INV_SEXP); - } - *r_pubkey = buf; - return 0; -} - - -/* Ask the agent whether the certificate is in the list of trusted - keys */ -int -gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert) -{ - int rc; - char *fpr; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (ctrl); - if (rc) - return rc; - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - if (!fpr) - { - log_error ("error getting the fingerprint\n"); - return gpg_error (GPG_ERR_GENERAL); - } - - snprintf (line, DIM(line)-1, "ISTRUSTED %s", fpr); - line[DIM(line)-1] = 0; - xfree (fpr); - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - -/* Ask the agent to mark CERT as a trusted Root-CA one */ -int -gpgsm_agent_marktrusted (ctrl_t ctrl, ksba_cert_t cert) -{ - int rc; - char *fpr, *dn; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (ctrl); - if (rc) - return rc; - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - if (!fpr) - { - log_error ("error getting the fingerprint\n"); - return gpg_error (GPG_ERR_GENERAL); - } - - dn = ksba_cert_get_issuer (cert, 0); - if (!dn) - { - xfree (fpr); - return gpg_error (GPG_ERR_GENERAL); - } - snprintf (line, DIM(line)-1, "MARKTRUSTED %s S %s", fpr, dn); - line[DIM(line)-1] = 0; - ksba_free (dn); - xfree (fpr); - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - - - -/* Ask the agent whether the a corresponding secret key is available - for the given keygrip */ -int -gpgsm_agent_havekey (ctrl_t ctrl, const char *hexkeygrip) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (ctrl); - if (rc) - return rc; - - if (!hexkeygrip || strlen (hexkeygrip) != 40) - return gpg_error (GPG_ERR_INV_VALUE); - - snprintf (line, DIM(line)-1, "HAVEKEY %s", hexkeygrip); - line[DIM(line)-1] = 0; - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - - -static AssuanError -learn_cb (void *opaque, const void *buffer, size_t length) -{ - struct learn_parm_s *parm = opaque; - size_t len; - char *buf; - ksba_cert_t cert; - int rc; - - if (parm->error) - return 0; - - if (buffer) - { - put_membuf (parm->data, buffer, length); - return 0; - } - /* END encountered - process what we have */ - buf = get_membuf (parm->data, &len); - if (!buf) - { - parm->error = gpg_error (GPG_ERR_ENOMEM); - return 0; - } - - - /* FIXME: this should go into import.c */ - rc = ksba_cert_new (&cert); - if (rc) - { - parm->error = rc; - return 0; - } - rc = ksba_cert_init_from_mem (cert, buf, len); - if (rc) - { - log_error ("failed to parse a certificate: %s\n", gpg_strerror (rc)); - ksba_cert_release (cert); - parm->error = rc; - return 0; - } - - rc = gpgsm_basic_cert_check (cert); - if (gpg_err_code (rc) == GPG_ERR_MISSING_CERT) - { /* For later use we store it in the ephemeral database. */ - log_info ("issuer certificate missing - storing as ephemeral\n"); - keydb_store_cert (cert, 1, NULL); - } - else if (rc) - log_error ("invalid certificate: %s\n", gpg_strerror (rc)); - else - { - int existed; - - if (!keydb_store_cert (cert, 0, &existed)) - { - if (opt.verbose > 1 && existed) - log_info ("certificate already in DB\n"); - else if (opt.verbose && !existed) - log_info ("certificate imported\n"); - } - } - - ksba_cert_release (cert); - init_membuf (parm->data, 4096); - return 0; -} - -/* Call the agent to learn about a smartcard */ -int -gpgsm_agent_learn (ctrl_t ctrl) -{ - int rc; - struct learn_parm_s learn_parm; - membuf_t data; - size_t len; - - rc = start_agent (ctrl); - if (rc) - return rc; - - init_membuf (&data, 4096); - learn_parm.error = 0; - learn_parm.ctx = agent_ctx; - learn_parm.data = &data; - rc = assuan_transact (agent_ctx, "LEARN --send", - learn_cb, &learn_parm, - NULL, NULL, NULL, NULL); - xfree (get_membuf (&data, &len)); - if (rc) - return map_assuan_err (rc); - return learn_parm.error; -} - - -/* Ask the agent to change the passphrase of the key identified by - HEXKEYGRIP. If DESC is not NULL, display instead of the default - description message. */ -int -gpgsm_agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (ctrl); - if (rc) - return rc; - - if (!hexkeygrip || strlen (hexkeygrip) != 40) - return gpg_error (GPG_ERR_INV_VALUE); - - if (desc) - { - snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - } - - snprintf (line, DIM(line)-1, "PASSWD %s", hexkeygrip); - line[DIM(line)-1] = 0; - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c deleted file mode 100644 index 15160dc41..000000000 --- a/sm/call-dirmngr.c +++ /dev/null @@ -1,785 +0,0 @@ -/* call-dirmngr.c - communication with the dromngr - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#include <ctype.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <assuan.h> - -#include "i18n.h" -#include "keydb.h" - - -struct membuf { - size_t len; - size_t size; - char *buf; - int out_of_core; -}; - - - -static ASSUAN_CONTEXT dirmngr_ctx = NULL; -static int force_pipe_server = 0; - -struct inq_certificate_parm_s { - ASSUAN_CONTEXT ctx; - ksba_cert_t cert; - ksba_cert_t issuer_cert; -}; - -struct isvalid_status_parm_s { - int seen; - unsigned char fpr[20]; -}; - - -struct lookup_parm_s { - CTRL ctrl; - ASSUAN_CONTEXT ctx; - void (*cb)(void *, ksba_cert_t); - void *cb_value; - struct membuf data; - int error; -}; - -struct run_command_parm_s { - ASSUAN_CONTEXT ctx; -}; - - -/* A simple implementation of a dynamic buffer. Use init_membuf() to - create a buffer, put_membuf to append bytes and get_membuf to - release and return the buffer. Allocation errors are detected but - only returned at the final get_membuf(), this helps not to clutter - the code with out of core checks. */ - -static void -init_membuf (struct membuf *mb, int initiallen) -{ - mb->len = 0; - mb->size = initiallen; - mb->out_of_core = 0; - mb->buf = xtrymalloc (initiallen); - if (!mb->buf) - mb->out_of_core = 1; -} - -static void -put_membuf (struct membuf *mb, const void *buf, size_t len) -{ - if (mb->out_of_core) - return; - - if (mb->len + len >= mb->size) - { - char *p; - - mb->size += len + 1024; - p = xtryrealloc (mb->buf, mb->size); - if (!p) - { - mb->out_of_core = 1; - return; - } - mb->buf = p; - } - memcpy (mb->buf + mb->len, buf, len); - mb->len += len; -} - -static void * -get_membuf (struct membuf *mb, size_t *len) -{ - char *p; - - if (mb->out_of_core) - { - xfree (mb->buf); - mb->buf = NULL; - return NULL; - } - - p = mb->buf; - *len = mb->len; - mb->buf = NULL; - mb->out_of_core = 1; /* don't allow a reuse */ - return p; -} - - - - - -/* Try to connect to the agent via socket or fork it off and work by - pipes. Handle the server's initial greeting */ -static int -start_dirmngr (void) -{ - int rc; - char *infostr, *p; - ASSUAN_CONTEXT ctx; - - if (dirmngr_ctx) - return 0; /* fixme: We need a context for each thread or serialize - the access to the dirmngr */ - /* Note: if you change this to multiple connections, you also need - to take care of the implicit option sending caching. */ - - infostr = force_pipe_server? NULL : getenv ("DIRMNGR_INFO"); - if (!infostr || !*infostr) - { - const char *pgmname; - const char *argv[3]; - int no_close_list[3]; - int i; - - if (opt.verbose) - log_info (_("no running dirmngr - starting one\n")); - - if (fflush (NULL)) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("error flushing pending output: %s\n", strerror (errno)); - return tmperr; - } - - if (!opt.dirmngr_program || !*opt.dirmngr_program) - opt.dirmngr_program = GNUPG_DEFAULT_DIRMNGR; - if ( !(pgmname = strrchr (opt.dirmngr_program, '/'))) - pgmname = opt.dirmngr_program; - else - pgmname++; - - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; - - i=0; - if (log_get_fd () != -1) - no_close_list[i++] = log_get_fd (); - no_close_list[i++] = fileno (stderr); - no_close_list[i] = -1; - - /* connect to the agent and perform initial handshaking */ - rc = assuan_pipe_connect (&ctx, opt.dirmngr_program, (char**)argv, - no_close_list); - } - else - { - int prot; - int pid; - - infostr = xstrdup (infostr); - if ( !(p = strchr (infostr, ':')) || p == infostr) - { - log_error (_("malformed DIRMNGR_INFO environment variable\n")); - xfree (infostr); - force_pipe_server = 1; - return start_dirmngr (); - } - *p++ = 0; - pid = atoi (p); - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if (prot != 1) - { - log_error (_("dirmngr protocol version %d is not supported\n"), - prot); - xfree (infostr); - force_pipe_server = 1; - return start_dirmngr (); - } - - rc = assuan_socket_connect (&ctx, infostr, pid); - xfree (infostr); - if (rc == ASSUAN_Connect_Failed) - { - log_error (_("can't connect to the dirmngr - trying fall back\n")); - force_pipe_server = 1; - return start_dirmngr (); - } - } - - if (rc) - { - log_error ("can't connect to the dirmngr: %s\n", assuan_strerror (rc)); - return gpg_error (GPG_ERR_NO_DIRMNGR); - } - dirmngr_ctx = ctx; - - if (DBG_ASSUAN) - log_debug ("connection to dirmngr established\n"); - return 0; -} - - - -/* Handle a SENDCERT inquiry. */ -static AssuanError -inq_certificate (void *opaque, const char *line) -{ - struct inq_certificate_parm_s *parm = opaque; - AssuanError rc; - const unsigned char *der; - size_t derlen; - int issuer_mode = 0; - - if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8])) - { - line += 8; - } - else if (!strncmp (line, "SENDISSUERCERT", 14) - && (line[14] == ' ' || !line[14])) - { - line += 14; - issuer_mode = 1; - } - else - { - log_error ("unsupported inquiry `%s'\n", line); - return ASSUAN_Inquire_Unknown; - } - - if (!*line) - { /* Send the current certificate. */ - der = ksba_cert_get_image (issuer_mode? parm->issuer_cert : parm->cert, - &derlen); - if (!der) - rc = ASSUAN_Inquire_Error; - else - rc = assuan_send_data (parm->ctx, der, derlen); - } - else if (issuer_mode) - { - log_error ("sending specific issuer certificate back " - "is not yet implemented\n"); - rc = ASSUAN_Inquire_Error; - } - else - { /* Send the given certificate. */ - int err; - ksba_cert_t cert; - - - err = gpgsm_find_cert (line, &cert); - if (err) - { - log_error ("certificate not found: %s\n", gpg_strerror (err)); - rc = ASSUAN_Inquire_Error; - } - else - { - der = ksba_cert_get_image (cert, &derlen); - if (!der) - rc = ASSUAN_Inquire_Error; - else - rc = assuan_send_data (parm->ctx, der, derlen); - ksba_cert_release (cert); - } - } - - return rc; -} - - -/* Take a 20 byte hexencoded string and put it into the the provided - 20 byte buffer FPR in binary format. */ -static int -unhexify_fpr (const char *hexstr, unsigned char *fpr) -{ - const char *s; - int n; - - for (s=hexstr, n=0; hexdigitp (s); s++, n++) - ; - if (*s || (n != 40)) - return 0; /* no fingerprint (invalid or wrong length). */ - n /= 2; - for (s=hexstr, n=0; *s; s += 2, n++) - fpr[n] = xtoi_2 (s); - return 1; /* okay */ -} - - -static assuan_error_t -isvalid_status_cb (void *opaque, const char *line) -{ - struct isvalid_status_parm_s *parm = opaque; - - if (!strncmp (line, "ONLY_VALID_IF_CERT_VALID", 24) - && (line[24]==' ' || !line[24])) - { - parm->seen++; - if (!line[24] || !unhexify_fpr (line+25, parm->fpr)) - parm->seen++; /* Bumb it to indicate an error. */ - } - return 0; -} - - - - -/* Call the directory manager to check whether the certificate is valid - Returns 0 for valid or usually one of the errors: - - GPG_ERR_CERTIFICATE_REVOKED - GPG_ERR_NO_CRL_KNOWN - GPG_ERR_CRL_TOO_OLD - - With USE_OCSP set to true, the dirmngr is asked to do an OCSP - request first. - */ -int -gpgsm_dirmngr_isvalid (ctrl_t ctrl, - ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp) -{ - static int did_options; - int rc; - char *certid; - char line[ASSUAN_LINELENGTH]; - struct inq_certificate_parm_s parm; - struct isvalid_status_parm_s stparm; - - - rc = start_dirmngr (); - if (rc) - return rc; - - if (use_ocsp) - { - certid = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - } - else - { - certid = gpgsm_get_certid (cert); - if (!certid) - { - log_error ("error getting the certificate ID\n"); - return gpg_error (GPG_ERR_GENERAL); - } - } - - if (opt.verbose > 1) - { - char *fpr = gpgsm_get_fingerprint_string (cert, GCRY_MD_SHA1); - log_info ("asking dirmngr about %s%s\n", fpr, - use_ocsp? " (using OCSP)":""); - xfree (fpr); - } - - parm.ctx = dirmngr_ctx; - parm.cert = cert; - parm.issuer_cert = issuer_cert; - - stparm.seen = 0; - memset (stparm.fpr, 0, 20); - - /* FIXME: If --disable-crl-checks has been set, we should pass an - option to dirmngr, so that no fallback CRL check is done after an - ocsp check. */ - - /* It is sufficient to send the options only once because we have - one connection per process only. */ - if (!did_options) - { - if (opt.force_crl_refresh) - assuan_transact (dirmngr_ctx, "OPTION force-crl-refresh=1", - NULL, NULL, NULL, NULL, NULL, NULL); - did_options = 1; - } - snprintf (line, DIM(line)-1, "ISVALID %s", certid); - line[DIM(line)-1] = 0; - xfree (certid); - - rc = assuan_transact (dirmngr_ctx, line, NULL, NULL, - inq_certificate, &parm, - isvalid_status_cb, &stparm); - if (opt.verbose > 1) - log_info ("response of dirmngr: %s\n", rc? assuan_strerror (rc): "okay"); - rc = map_assuan_err (rc); - - if (!rc && stparm.seen) - { - /* Need to also check the certificate validity. */ - if (stparm.seen != 1) - { - log_error ("communication problem with dirmngr detected\n"); - rc = gpg_error (GPG_ERR_INV_CRL); - } - else - { - KEYDB_HANDLE kh; - ksba_cert_t rspcert = NULL; - - /* Fixme: First try to get the certificate from the - dirmngr's cache - it should be there. */ - kh = keydb_new (0); - if (!kh) - rc = gpg_error (GPG_ERR_ENOMEM); - if (!rc) - rc = keydb_search_fpr (kh, stparm.fpr); - if (!rc) - rc = keydb_get_cert (kh, &rspcert); - if (rc) - { - log_error ("unable to find the certificate used " - "by the dirmngr: %s\n", gpg_strerror (rc)); - rc = gpg_error (GPG_ERR_INV_CRL); - } - keydb_release (kh); - - if (!rc) - { - /* fixme: We should refine the check to check for - certificates allowed for CRL/OCPS. */ - rc = gpgsm_cert_use_verify_p (rspcert); - if (rc) - rc = gpg_error (GPG_ERR_INV_CRL); - else - { - /* Note, the flag = 1: This avoids checking this - certificate over and over again. */ - rc = gpgsm_validate_chain (ctrl, rspcert, NULL, 0, NULL, 1); - if (rc) - { - log_error ("invalid certificate used for CRL/OCSP: %s\n", - gpg_strerror (rc)); - rc = gpg_error (GPG_ERR_INV_CRL); - } - } - } - ksba_cert_release (rspcert); - } - } - return rc; -} - - - -/* Lookup helpers*/ -static AssuanError -lookup_cb (void *opaque, const void *buffer, size_t length) -{ - struct lookup_parm_s *parm = opaque; - size_t len; - char *buf; - ksba_cert_t cert; - int rc; - - if (parm->error) - return 0; - - if (buffer) - { - put_membuf (&parm->data, buffer, length); - return 0; - } - /* END encountered - process what we have */ - buf = get_membuf (&parm->data, &len); - if (!buf) - { - parm->error = gpg_error (GPG_ERR_ENOMEM); - return 0; - } - - rc = ksba_cert_new (&cert); - if (rc) - { - parm->error = rc; - return 0; - } - rc = ksba_cert_init_from_mem (cert, buf, len); - if (rc) - { - log_error ("failed to parse a certificate: %s\n", gpg_strerror (rc)); - } - else - { - parm->cb (parm->cb_value, cert); - } - - ksba_cert_release (cert); - init_membuf (&parm->data, 4096); - return 0; -} - -/* Return a properly escaped pattern from NAMES. The only error - return is NULL to indicate a malloc failure. */ -static char * -pattern_from_strlist (STRLIST names) -{ - STRLIST sl; - int n; - const char *s; - char *pattern, *p; - - for (n=0, sl=names; sl; sl = sl->next) - { - for (s=sl->d; *s; s++, n++) - { - if (*s == '%' || *s == ' ' || *s == '+') - n += 2; - } - n++; - } - - p = pattern = xtrymalloc (n+1); - if (!pattern) - return NULL; - - for (n=0, sl=names; sl; sl = sl->next) - { - for (s=sl->d; *s; s++) - { - switch (*s) - { - case '%': - *p++ = '%'; - *p++ = '2'; - *p++ = '5'; - break; - case ' ': - *p++ = '%'; - *p++ = '2'; - *p++ = '0'; - break; - case '+': - *p++ = '%'; - *p++ = '2'; - *p++ = 'B'; - break; - default: - *p++ = *s; - break; - } - } - *p++ = ' '; - } - if (p == pattern) - *pattern = 0; /* is empty */ - else - p[-1] = '\0'; /* remove trailing blank */ - - return pattern; -} - -static AssuanError -lookup_status_cb (void *opaque, const char *line) -{ - struct lookup_parm_s *parm = opaque; - - if (!strncmp (line, "TRUNCATED", 9) && (line[9]==' ' || !line[9])) - { - if (parm->ctrl) - { - for (line +=9; *line == ' '; line++) - ; - gpgsm_status (parm->ctrl, STATUS_TRUNCATED, line); - } - } - return 0; -} - - -/* Run the Directroy Managers lookup command using the pattern - compiled from the strings given in NAMES. The caller must provide - the callback CB which will be passed cert by cert. Note that CTRL - is optional. */ -int -gpgsm_dirmngr_lookup (CTRL ctrl, STRLIST names, - void (*cb)(void*, ksba_cert_t), void *cb_value) -{ - int rc; - char *pattern; - char line[ASSUAN_LINELENGTH]; - struct lookup_parm_s parm; - size_t len; - - rc = start_dirmngr (); - if (rc) - return rc; - - pattern = pattern_from_strlist (names); - if (!pattern) - return OUT_OF_CORE (errno); - snprintf (line, DIM(line)-1, "LOOKUP %s", pattern); - line[DIM(line)-1] = 0; - xfree (pattern); - - parm.ctrl = ctrl; - parm.ctx = dirmngr_ctx; - parm.cb = cb; - parm.cb_value = cb_value; - parm.error = 0; - init_membuf (&parm.data, 4096); - - rc = assuan_transact (dirmngr_ctx, line, lookup_cb, &parm, - NULL, NULL, lookup_status_cb, &parm); - xfree (get_membuf (&parm.data, &len)); - if (rc) - return map_assuan_err (rc); - return parm.error; -} - - - -/* Run Command helpers*/ - -/* Fairly simple callback to write all output of dirmngr to stdout. */ -static AssuanError -run_command_cb (void *opaque, const void *buffer, size_t length) -{ - if (buffer) - { - if ( fwrite (buffer, length, 1, stdout) != 1 ) - log_error ("error writing to stdout: %s\n", strerror (errno)); - } - return 0; -} - -/* Handle inquiries from the dirmngr COMMAND. */ -static AssuanError -run_command_inq_cb (void *opaque, const char *line) -{ - struct run_command_parm_s *parm = opaque; - AssuanError rc = 0; - - if ( !strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]) ) - { /* send the given certificate */ - int err; - ksba_cert_t cert; - const unsigned char *der; - size_t derlen; - - line += 8; - if (!*line) - return ASSUAN_Inquire_Error; - - err = gpgsm_find_cert (line, &cert); - if (err) - { - log_error ("certificate not found: %s\n", gpg_strerror (err)); - rc = ASSUAN_Inquire_Error; - } - else - { - der = ksba_cert_get_image (cert, &derlen); - if (!der) - rc = ASSUAN_Inquire_Error; - else - rc = assuan_send_data (parm->ctx, der, derlen); - ksba_cert_release (cert); - } - } - else if ( !strncmp (line, "PRINTINFO", 9) && (line[9] == ' ' || !line[9]) ) - { /* Simply show the message given in the argument. */ - line += 9; - log_info ("dirmngr: %s\n", line); - } - else - { - log_error ("unsupported inquiry `%s'\n", line); - rc = ASSUAN_Inquire_Unknown; - } - - return rc; -} - -static AssuanError -run_command_status_cb (void *opaque, const char *line) -{ - if (opt.verbose) - { - log_info ("dirmngr status: %s\n", line); - } - return 0; -} - - - -/* Pass COMMAND to dirmngr and print all output generated by Dirmngr - to stdout. A couple of inquiries are defined (see above). ARGC - arguments in ARGV are given to the Dirmngr. Spaces, plus and - percent characters within the argument strings are percent escaped - so that blanks can act as delimiters. */ -int -gpgsm_dirmngr_run_command (CTRL ctrl, const char *command, - int argc, char **argv) -{ - int rc; - int i; - const char *s; - char *line, *p; - size_t len; - struct run_command_parm_s parm; - - rc = start_dirmngr (); - if (rc) - return rc; - - parm.ctx = dirmngr_ctx; - - len = strlen (command) + 1; - for (i=0; i < argc; i++) - len += 1 + 3*strlen (argv[i]); /* enough space for percent escaping */ - line = xtrymalloc (len); - if (!line) - return OUT_OF_CORE (errno); - - p = stpcpy (line, command); - for (i=0; i < argc; i++) - { - *p++ = ' '; - for (s=argv[i]; *s; s++) - { - if (!isascii (*s)) - *p++ = *s; - else if (*s == ' ') - *p++ = '+'; - else if (!isprint (*s) || *s == '+') - { - sprintf (p, "%%%02X", *s); - p += 3; - } - else - *p++ = *s; - } - } - *p = 0; - - rc = assuan_transact (dirmngr_ctx, line, - run_command_cb, NULL, - run_command_inq_cb, &parm, - run_command_status_cb, NULL); - xfree (line); - log_info ("response of dirmngr: %s\n", rc? assuan_strerror (rc): "okay"); - return map_assuan_err (rc); -} diff --git a/sm/certchain.c b/sm/certchain.c deleted file mode 100644 index 3009c21aa..000000000 --- a/sm/certchain.c +++ /dev/null @@ -1,976 +0,0 @@ -/* certchain.c - certificate chain validation - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <stdarg.h> -#include <assert.h> - -#define JNLIB_NEED_LOG_LOGV /* We need log_logv. */ - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */ -#include "i18n.h" - - -/* If LISTMODE is true, print FORMAT in liting mode to FP. If - LISTMODE is false, use the string to print an log_info or, if - IS_ERROR is true, an log_error. */ -static void -do_list (int is_error, int listmode, FILE *fp, const char *format, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, format) ; - if (listmode) - { - if (fp) - { - fputs (" [", fp); - vfprintf (fp, format, arg_ptr); - fputs ("]\n", fp); - } - } - else - { - log_logv (is_error? JNLIB_LOG_ERROR: JNLIB_LOG_INFO, format, arg_ptr); - log_printf ("\n"); - } - va_end (arg_ptr); -} - -/* Return 0 if A and B are equal. */ -static int -compare_certs (ksba_cert_t a, ksba_cert_t b) -{ - const unsigned char *img_a, *img_b; - size_t len_a, len_b; - - img_a = ksba_cert_get_image (a, &len_a); - if (!img_a) - return 1; - img_b = ksba_cert_get_image (b, &len_b); - if (!img_b) - return 1; - return !(len_a == len_b && !memcmp (img_a, img_b, len_a)); -} - - -static int -unknown_criticals (ksba_cert_t cert, int listmode, FILE *fp) -{ - static const char *known[] = { - "2.5.29.15", /* keyUsage */ - "2.5.29.19", /* basic Constraints */ - "2.5.29.32", /* certificatePolicies */ - "2.5.29.37", /* extendedKeyUsage - handled by certlist.c */ - NULL - }; - int rc = 0, i, idx, crit; - const char *oid; - gpg_error_t err; - - for (idx=0; !(err=ksba_cert_get_extension (cert, idx, - &oid, &crit, NULL, NULL));idx++) - { - if (!crit) - continue; - for (i=0; known[i] && strcmp (known[i],oid); i++) - ; - if (!known[i]) - { - do_list (1, listmode, fp, - _("critical certificate extension %s is not supported"), - oid); - rc = gpg_error (GPG_ERR_UNSUPPORTED_CERT); - } - } - if (err && gpg_err_code (err) != GPG_ERR_EOF) - rc = err; - - return rc; -} - -static int -allowed_ca (ksba_cert_t cert, int *chainlen, int listmode, FILE *fp) -{ - gpg_error_t err; - int flag; - - err = ksba_cert_is_ca (cert, &flag, chainlen); - if (err) - return err; - if (!flag) - { - do_list (1, listmode, fp,_("issuer certificate is not marked as a CA")); - return gpg_error (GPG_ERR_BAD_CA_CERT); - } - return 0; -} - - -static int -check_cert_policy (ksba_cert_t cert, int listmode, FILE *fplist) -{ - gpg_error_t err; - char *policies; - FILE *fp; - int any_critical; - - err = ksba_cert_get_cert_policies (cert, &policies); - if (gpg_err_code (err) == GPG_ERR_NO_DATA) - return 0; /* no policy given */ - if (err) - return err; - - /* STRING is a line delimited list of certifiate policies as stored - in the certificate. The line itself is colon delimited where the - first field is the OID of the policy and the second field either - N or C for normal or critical extension */ - - if (opt.verbose > 1 && !listmode) - log_info ("certificate's policy list: %s\n", policies); - - /* The check is very minimal but won't give false positives */ - any_critical = !!strstr (policies, ":C"); - - if (!opt.policy_file) - { - xfree (policies); - if (any_critical) - { - do_list (1, listmode, fplist, - _("critical marked policy without configured policies")); - return gpg_error (GPG_ERR_NO_POLICY_MATCH); - } - return 0; - } - - fp = fopen (opt.policy_file, "r"); - if (!fp) - { - log_error ("failed to open `%s': %s\n", - opt.policy_file, strerror (errno)); - xfree (policies); - /* With no critical policies this is only a warning */ - if (!any_critical) - { - do_list (0, listmode, fplist, - _("note: non-critical certificate policy not allowed")); - return 0; - } - do_list (1, listmode, fplist, - _("certificate policy not allowed")); - return gpg_error (GPG_ERR_NO_POLICY_MATCH); - } - - for (;;) - { - int c; - char *p, line[256]; - char *haystack, *allowed; - - /* read line */ - do - { - if (!fgets (line, DIM(line)-1, fp) ) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - - xfree (policies); - if (feof (fp)) - { - fclose (fp); - /* With no critical policies this is only a warning */ - if (!any_critical) - { - do_list (0, listmode, fplist, - _("note: non-critical certificate policy not allowed")); - return 0; - } - do_list (1, listmode, fplist, - _("certificate policy not allowed")); - return gpg_error (GPG_ERR_NO_POLICY_MATCH); - } - fclose (fp); - return tmperr; - } - - if (!*line || line[strlen(line)-1] != '\n') - { - /* eat until end of line */ - while ( (c=getc (fp)) != EOF && c != '\n') - ; - fclose (fp); - xfree (policies); - return gpg_error (*line? GPG_ERR_LINE_TOO_LONG - : GPG_ERR_INCOMPLETE_LINE); - } - - /* Allow for empty lines and spaces */ - for (p=line; spacep (p); p++) - ; - } - while (!*p || *p == '\n' || *p == '#'); - - /* parse line */ - for (allowed=line; spacep (allowed); allowed++) - ; - p = strpbrk (allowed, " :\n"); - if (!*p || p == allowed) - { - fclose (fp); - xfree (policies); - return gpg_error (GPG_ERR_CONFIGURATION); - } - *p = 0; /* strip the rest of the line */ - /* See whether we find ALLOWED (which is an OID) in POLICIES */ - for (haystack=policies; (p=strstr (haystack, allowed)); haystack = p+1) - { - if ( !(p == policies || p[-1] == '\n') ) - continue; /* Does not match the begin of a line. */ - if (p[strlen (allowed)] != ':') - continue; /* The length does not match. */ - /* Yep - it does match so return okay. */ - fclose (fp); - xfree (policies); - return 0; - } - } -} - - -static void -find_up_store_certs_cb (void *cb_value, ksba_cert_t cert) -{ - if (keydb_store_cert (cert, 1, NULL)) - log_error ("error storing issuer certificate as ephemeral\n"); - ++*(int*)cb_value; -} - - -static int -find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) -{ - ksba_name_t authid; - ksba_sexp_t authidno; - int rc = -1; - - if (!ksba_cert_get_auth_key_id (cert, NULL, &authid, &authidno)) - { - const char *s = ksba_name_enum (authid, 0); - if (s && *authidno) - { - rc = keydb_search_issuer_sn (kh, s, authidno); - if (rc) - keydb_search_reset (kh); - - /* In case of an error try the ephemeral DB. We can't do - that in find-netx mode because we can't keep the search - state then. */ - if (rc == -1 && !find_next) - { - int old = keydb_set_ephemeral (kh, 1); - if (!old) - { - rc = keydb_search_issuer_sn (kh, s, authidno); - if (rc) - keydb_search_reset (kh); - } - keydb_set_ephemeral (kh, old); - } - } - /* Print a note so that the user does not feel too helpless when - an issuer certificate was found and gpgsm prints BAD - signature because it is not the correct one. */ - if (rc == -1) - { - log_info ("issuer certificate (#"); - gpgsm_dump_serial (authidno); - log_printf ("/"); - gpgsm_dump_string (s); - log_printf (") not found\n"); - } - else if (rc) - log_error ("failed to find authorityKeyIdentifier: rc=%d\n", rc); - ksba_name_release (authid); - xfree (authidno); - /* Fixme: don't know how to do dirmngr lookup with serial+issuer. */ - } - - if (rc) /* not found via authorithyKeyIdentifier, try regular issuer name */ - rc = keydb_search_subject (kh, issuer); - if (rc == -1 && !find_next) - { - /* Not found, lets see whether we have one in the ephemeral key DB. */ - int old = keydb_set_ephemeral (kh, 1); - if (!old) - { - keydb_search_reset (kh); - rc = keydb_search_subject (kh, issuer); - } - keydb_set_ephemeral (kh, old); - } - - if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next) - { - STRLIST names = NULL; - int count = 0; - char *pattern; - const char *s; - - if (opt.verbose) - log_info (_("looking up issuer at external location\n")); - /* dirmngr is confused about unknown attributes so as a quick - and ugly hack we locate the CN and use this and the - following. Fixme: we should have far better parsing in the - dirmngr. */ - s = strstr (issuer, "CN="); - if (!s || s == issuer || s[-1] != ',') - s = issuer; - - pattern = xtrymalloc (strlen (s)+2); - if (!pattern) - return OUT_OF_CORE (errno); - strcpy (stpcpy (pattern, "/"), s); - add_to_strlist (&names, pattern); - xfree (pattern); - rc = gpgsm_dirmngr_lookup (NULL, names, find_up_store_certs_cb, &count); - free_strlist (names); - if (opt.verbose) - log_info (_("number of issuers matching: %d\n"), count); - if (rc) - { - log_error ("external key lookup failed: %s\n", gpg_strerror (rc)); - rc = -1; - } - else if (!count) - rc = -1; - else - { - int old; - /* The issuers are currently stored in the ephemeral key - DB, so we temporary switch to ephemeral mode. */ - old = keydb_set_ephemeral (kh, 1); - keydb_search_reset (kh); - rc = keydb_search_subject (kh, issuer); - keydb_set_ephemeral (kh, old); - } - } - return rc; -} - - -/* Return the next certificate up in the chain starting at START. - Returns -1 when there are no more certificates. */ -int -gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next) -{ - int rc = 0; - char *issuer = NULL; - char *subject = NULL; - KEYDB_HANDLE kh = keydb_new (0); - - *r_next = NULL; - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - issuer = ksba_cert_get_issuer (start, 0); - subject = ksba_cert_get_subject (start, 0); - if (!issuer) - { - log_error ("no issuer found in certificate\n"); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - if (!subject) - { - log_error ("no subject found in certificate\n"); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - - if (!strcmp (issuer, subject)) - { - rc = -1; /* we are at the root */ - goto leave; - } - - rc = find_up (kh, start, issuer, 0); - if (rc) - { - /* it is quite common not to have a certificate, so better don't - print an error here */ - if (rc != -1 && opt.verbose > 1) - log_error ("failed to find issuer's certificate: rc=%d\n", rc); - rc = gpg_error (GPG_ERR_MISSING_CERT); - goto leave; - } - - rc = keydb_get_cert (kh, r_next); - if (rc) - { - log_error ("failed to get cert: rc=%d\n", rc); - rc = gpg_error (GPG_ERR_GENERAL); - } - - leave: - xfree (issuer); - xfree (subject); - keydb_release (kh); - return rc; -} - - -/* Check whether the CERT is a root certificate. Returns True if this - is the case. */ -int -gpgsm_is_root_cert (ksba_cert_t cert) -{ - char *issuer; - char *subject; - int yes; - - issuer = ksba_cert_get_issuer (cert, 0); - subject = ksba_cert_get_subject (cert, 0); - yes = (issuer && subject && !strcmp (issuer, subject)); - xfree (issuer); - xfree (subject); - return yes; -} - - -/* This is a helper for gpgsm_validate_chain. */ -static gpg_error_t -is_cert_still_valid (ctrl_t ctrl, int lm, FILE *fp, - ksba_cert_t subject_cert, ksba_cert_t issuer_cert, - int *any_revoked, int *any_no_crl, int *any_crl_too_old) -{ - if (!opt.no_crl_check || ctrl->use_ocsp) - { - gpg_error_t err; - - err = gpgsm_dirmngr_isvalid (ctrl, - subject_cert, issuer_cert, ctrl->use_ocsp); - if (err) - { - /* Fixme: We should change the wording because we may - have used OCSP. */ - switch (gpg_err_code (err)) - { - case GPG_ERR_CERT_REVOKED: - do_list (1, lm, fp, _("certificate has been revoked")); - *any_revoked = 1; - /* Store that in the keybox so that key listings are - able to return the revoked flag. We don't care - about error, though. */ - keydb_set_cert_flags (subject_cert, KEYBOX_FLAG_VALIDITY, 0, - VALIDITY_REVOKED); - break; - case GPG_ERR_NO_CRL_KNOWN: - do_list (1, lm, fp, _("no CRL found for certificate")); - *any_no_crl = 1; - break; - case GPG_ERR_CRL_TOO_OLD: - do_list (1, lm, fp, _("the available CRL is too old")); - if (!lm) - log_info (_("please make sure that the " - "\"dirmngr\" is properly installed\n")); - *any_crl_too_old = 1; - break; - default: - do_list (1, lm, fp, _("checking the CRL failed: %s"), - gpg_strerror (err)); - return err; - } - } - } - return 0; -} - - - -/* Validate a chain and optionally return the nearest expiration time - in R_EXPTIME. With LISTMODE set to 1 a special listmode is - activated where only information about the certificate is printed - to FP and no output is send to the usual log stream. - - Defined flag bits: 0 - do not do any dirmngr isvalid checks. -*/ -int -gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, - int listmode, FILE *fp, unsigned int flags) -{ - int rc = 0, depth = 0, maxdepth; - char *issuer = NULL; - char *subject = NULL; - KEYDB_HANDLE kh = keydb_new (0); - ksba_cert_t subject_cert = NULL, issuer_cert = NULL; - ksba_isotime_t current_time; - ksba_isotime_t exptime; - int any_expired = 0; - int any_revoked = 0; - int any_no_crl = 0; - int any_crl_too_old = 0; - int any_no_policy_match = 0; - int lm = listmode; - - gnupg_get_isotime (current_time); - if (r_exptime) - *r_exptime = 0; - *exptime = 0; - - if (opt.no_chain_validation && !listmode) - { - log_info ("WARNING: bypassing certificate chain validation\n"); - return 0; - } - - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - if (DBG_X509 && !listmode) - gpgsm_dump_cert ("subject", cert); - - subject_cert = cert; - maxdepth = 50; - - for (;;) - { - xfree (issuer); - xfree (subject); - issuer = ksba_cert_get_issuer (subject_cert, 0); - subject = ksba_cert_get_subject (subject_cert, 0); - - if (!issuer) - { - do_list (1, lm, fp, _("no issuer found in certificate")); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - - { - ksba_isotime_t not_before, not_after; - - rc = ksba_cert_get_validity (subject_cert, 0, not_before); - if (!rc) - rc = ksba_cert_get_validity (subject_cert, 1, not_after); - if (rc) - { - do_list (1, lm, fp, _("certificate with invalid validity: %s"), - gpg_strerror (rc)); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - - if (*not_after) - { - if (!*exptime) - gnupg_copy_time (exptime, not_after); - else if (strcmp (not_after, exptime) < 0 ) - gnupg_copy_time (exptime, not_after); - } - - if (*not_before && strcmp (current_time, not_before) < 0 ) - { - do_list (1, lm, fp, _("certificate not yet valid")); - if (!lm) - { - log_info ("(valid from "); - gpgsm_dump_time (not_before); - log_printf (")\n"); - } - rc = gpg_error (GPG_ERR_CERT_TOO_YOUNG); - goto leave; - } - if (*not_after && strcmp (current_time, not_after) > 0 ) - { - do_list (opt.ignore_expiration?0:1, lm, fp, - _("certificate has expired")); - if (!lm) - { - log_info ("(expired at "); - gpgsm_dump_time (not_after); - log_printf (")\n"); - } - if (opt.ignore_expiration) - log_info ("WARNING: ignoring expiration\n"); - else - any_expired = 1; - } - } - - rc = unknown_criticals (subject_cert, listmode, fp); - if (rc) - goto leave; - - if (!opt.no_policy_check) - { - rc = check_cert_policy (subject_cert, listmode, fp); - if (gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH) - { - any_no_policy_match = 1; - rc = 1; - } - else if (rc) - goto leave; - } - - - /* Is this a self-signed certificate? */ - if (subject && !strcmp (issuer, subject)) - { /* Yes. */ - if (gpgsm_check_cert_sig (subject_cert, subject_cert) ) - { - do_list (1, lm, fp, - _("selfsigned certificate has a BAD signature")); - rc = gpg_error (depth? GPG_ERR_BAD_CERT_CHAIN - : GPG_ERR_BAD_CERT); - goto leave; - } - rc = allowed_ca (subject_cert, NULL, listmode, fp); - if (rc) - goto leave; - - rc = gpgsm_agent_istrusted (ctrl, subject_cert); - if (!rc) - ; - else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED) - { - do_list (0, lm, fp, _("root certificate is not marked trusted")); - if (!lm) - { - int rc2; - char *fpr = gpgsm_get_fingerprint_string (subject_cert, - GCRY_MD_SHA1); - log_info (_("fingerprint=%s\n"), fpr? fpr : "?"); - xfree (fpr); - rc2 = gpgsm_agent_marktrusted (ctrl, subject_cert); - if (!rc2) - { - log_info (_("root certificate has now" - " been marked as trusted\n")); - rc = 0; - } - else - { - gpgsm_dump_cert ("issuer", subject_cert); - log_info ("after checking the fingerprint, you may want " - "to add it manually to the list of trusted " - "certificates.\n"); - } - } - } - else - { - log_error (_("checking the trust list failed: %s\n"), - gpg_strerror (rc)); - } - - /* Check for revocations etc. */ - if ((flags & 1)) - rc = 0; - else - rc = is_cert_still_valid (ctrl, lm, fp, - subject_cert, subject_cert, - &any_revoked, &any_no_crl, - &any_crl_too_old); - if (rc) - goto leave; - - break; /* Okay: a self-signed certicate is an end-point. */ - } - - depth++; - if (depth > maxdepth) - { - do_list (1, lm, fp, _("certificate chain too long\n")); - rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN); - goto leave; - } - - /* find the next cert up the tree */ - keydb_search_reset (kh); - rc = find_up (kh, subject_cert, issuer, 0); - if (rc) - { - if (rc == -1) - { - do_list (0, lm, fp, _("issuer certificate not found")); - if (!lm) - { - log_info ("issuer certificate: #/"); - gpgsm_dump_string (issuer); - log_printf ("\n"); - } - } - else - log_error ("failed to find issuer's certificate: rc=%d\n", rc); - rc = gpg_error (GPG_ERR_MISSING_CERT); - goto leave; - } - - ksba_cert_release (issuer_cert); issuer_cert = NULL; - rc = keydb_get_cert (kh, &issuer_cert); - if (rc) - { - log_error ("failed to get cert: rc=%d\n", rc); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - try_another_cert: - if (DBG_X509) - { - log_debug ("got issuer's certificate:\n"); - gpgsm_dump_cert ("issuer", issuer_cert); - } - - rc = gpgsm_check_cert_sig (issuer_cert, subject_cert); - if (rc) - { - do_list (0, lm, fp, _("certificate has a BAD signature")); - if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE) - { - /* We now try to find other issuer certificates which - might have been used. This is rquired because some - CAs are reusing the issuer and subject DN for new - root certificates. */ - rc = find_up (kh, subject_cert, issuer, 1); - if (!rc) - { - ksba_cert_t tmp_cert; - - rc = keydb_get_cert (kh, &tmp_cert); - if (rc || !compare_certs (issuer_cert, tmp_cert)) - { - /* The find next did not work or returned an - identical certificate. We better stop here - to avoid infinite checks. */ - rc = gpg_error (GPG_ERR_BAD_SIGNATURE); - ksba_cert_release (tmp_cert); - } - else - { - do_list (0, lm, fp, _("found another possible matching " - "CA certificate - trying again")); - ksba_cert_release (issuer_cert); - issuer_cert = tmp_cert; - goto try_another_cert; - } - } - } - - /* We give a more descriptive error code than the one - returned from the signature checking. */ - rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN); - goto leave; - } - - { - int chainlen; - rc = allowed_ca (issuer_cert, &chainlen, listmode, fp); - if (rc) - goto leave; - if (chainlen >= 0 && (depth - 1) > chainlen) - { - do_list (1, lm, fp, - _("certificate chain longer than allowed by CA (%d)"), - chainlen); - rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN); - goto leave; - } - } - - if (!listmode) - { - rc = gpgsm_cert_use_cert_p (issuer_cert); - if (rc) - { - char numbuf[50]; - sprintf (numbuf, "%d", rc); - gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage", - numbuf, NULL); - goto leave; - } - } - - /* Check for revocations etc. */ - if ((flags & 1)) - rc = 0; - else - rc = is_cert_still_valid (ctrl, lm, fp, - subject_cert, issuer_cert, - &any_revoked, &any_no_crl, &any_crl_too_old); - if (rc) - goto leave; - - - if (opt.verbose && !listmode) - log_info ("certificate is good\n"); - - keydb_search_reset (kh); - subject_cert = issuer_cert; - issuer_cert = NULL; - } - - if (!listmode) - { - if (opt.no_policy_check) - log_info ("policies not checked due to %s option\n", - "--disable-policy-checks"); - if (opt.no_crl_check && !ctrl->use_ocsp) - log_info ("CRLs not checked due to %s option\n", - "--disable-crl-checks"); - } - - if (!rc) - { /* If we encountered an error somewhere during the checks, set - the error code to the most critical one */ - if (any_revoked) - rc = gpg_error (GPG_ERR_CERT_REVOKED); - else if (any_no_crl) - rc = gpg_error (GPG_ERR_NO_CRL_KNOWN); - else if (any_crl_too_old) - rc = gpg_error (GPG_ERR_CRL_TOO_OLD); - else if (any_no_policy_match) - rc = gpg_error (GPG_ERR_NO_POLICY_MATCH); - else if (any_expired) - rc = gpg_error (GPG_ERR_CERT_EXPIRED); - } - - leave: - if (r_exptime) - gnupg_copy_time (r_exptime, exptime); - xfree (issuer); - keydb_release (kh); - ksba_cert_release (issuer_cert); - if (subject_cert != cert) - ksba_cert_release (subject_cert); - return rc; -} - - -/* Check that the given certificate is valid but DO NOT check any - constraints. We assume that the issuers certificate is already in - the DB and that this one is valid; which it should be because it - has been checked using this function. */ -int -gpgsm_basic_cert_check (ksba_cert_t cert) -{ - int rc = 0; - char *issuer = NULL; - char *subject = NULL; - KEYDB_HANDLE kh = keydb_new (0); - ksba_cert_t issuer_cert = NULL; - - if (opt.no_chain_validation) - { - log_info ("WARNING: bypassing basic certificate checks\n"); - return 0; - } - - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - issuer = ksba_cert_get_issuer (cert, 0); - subject = ksba_cert_get_subject (cert, 0); - if (!issuer) - { - log_error ("no issuer found in certificate\n"); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - - if (subject && !strcmp (issuer, subject)) - { - if (gpgsm_check_cert_sig (cert, cert) ) - { - log_error ("selfsigned certificate has a BAD signature\n"); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - } - else - { - /* find the next cert up the tree */ - keydb_search_reset (kh); - rc = find_up (kh, cert, issuer, 0); - if (rc) - { - if (rc == -1) - { - log_info ("issuer certificate (#/"); - gpgsm_dump_string (issuer); - log_printf (") not found\n"); - } - else - log_error ("failed to find issuer's certificate: rc=%d\n", rc); - rc = gpg_error (GPG_ERR_MISSING_CERT); - goto leave; - } - - ksba_cert_release (issuer_cert); issuer_cert = NULL; - rc = keydb_get_cert (kh, &issuer_cert); - if (rc) - { - log_error ("failed to get cert: rc=%d\n", rc); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - if (gpgsm_check_cert_sig (issuer_cert, cert) ) - { - log_error ("certificate has a BAD signature\n"); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - if (opt.verbose) - log_info ("certificate is good\n"); - } - - leave: - xfree (issuer); - keydb_release (kh); - ksba_cert_release (issuer_cert); - return rc; -} - diff --git a/sm/certcheck.c b/sm/certcheck.c deleted file mode 100644 index b5ed9914a..000000000 --- a/sm/certcheck.c +++ /dev/null @@ -1,303 +0,0 @@ -/* certcheck.c - check one certificate - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - - -static int -do_encode_md (gcry_md_hd_t md, int algo, unsigned int nbits, - gcry_mpi_t *r_val) -{ - int nframe = (nbits+7) / 8; - byte *frame; - int i, n; - byte asn[100]; - size_t asnlen; - size_t len; - - asnlen = DIM(asn); - if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen)) - { - log_error ("no object identifier for algo %d\n", algo); - return gpg_error (GPG_ERR_INTERNAL); - } - - len = gcry_md_get_algo_dlen (algo); - - if ( len + asnlen + 4 > nframe ) - { - log_error ("can't encode a %d bit MD into a %d bits frame\n", - (int)(len*8), (int)nbits); - return gpg_error (GPG_ERR_INTERNAL); - } - - /* We encode the MD in this way: - * - * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes) - * - * PAD consists of FF bytes. - */ - frame = xtrymalloc (nframe); - if (!frame) - return OUT_OF_CORE (errno); - n = 0; - frame[n++] = 0; - frame[n++] = 1; /* block type */ - i = nframe - len - asnlen -3 ; - assert ( i > 1 ); - memset ( frame+n, 0xff, i ); n += i; - frame[n++] = 0; - memcpy ( frame+n, asn, asnlen ); n += asnlen; - memcpy ( frame+n, gcry_md_read(md, algo), len ); n += len; - assert ( n == nframe ); - if (DBG_X509) - { - int j; - log_debug ("encoded hash:"); - for (j=0; j < nframe; j++) - log_printf (" %02X", frame[j]); - log_printf ("\n"); - } - - gcry_mpi_scan (r_val, GCRYMPI_FMT_USG, frame, n, &nframe); - xfree (frame); - return 0; -} - - -/* - Check the signature on CERT using the ISSUER-CERT. This function - does only test the cryptographic signature and nothing else. It is - assumed that the ISSUER_CERT is valid. */ -int -gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert) -{ - const char *algoid; - gcry_md_hd_t md; - int rc, algo; - gcry_mpi_t frame; - ksba_sexp_t p; - size_t n; - gcry_sexp_t s_sig, s_hash, s_pkey; - - algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert))); - if (!algo) - { - log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?"); - return gpg_error (GPG_ERR_GENERAL); - } - rc = gcry_md_open (&md, algo, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - return rc; - } - if (DBG_HASHING) - gcry_md_start_debug (md, "hash.cert"); - - rc = ksba_cert_hash (cert, 1, HASH_FNC, md); - if (rc) - { - log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (rc)); - gcry_md_close (md); - return rc; - } - gcry_md_final (md); - - p = ksba_cert_get_sig_val (cert); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - gcry_md_close (md); - ksba_free (p); - return gpg_error (GPG_ERR_BUG); - } - if (DBG_X509) - { - int j; - log_debug ("signature value:"); - for (j=0; j < n; j++) - log_printf (" %02X", p[j]); - log_printf ("\n"); - } - - rc = gcry_sexp_sscan ( &s_sig, NULL, p, n); - ksba_free (p); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - gcry_md_close (md); - return rc; - } - - p = ksba_cert_get_public_key (issuer_cert); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - gcry_md_close (md); - ksba_free (p); - gcry_sexp_release (s_sig); - return gpg_error (GPG_ERR_BUG); - } - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); - ksba_free (p); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - gcry_md_close (md); - gcry_sexp_release (s_sig); - return rc; - } - - rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame); - if (rc) - { - gcry_md_close (md); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_pkey); - return rc; - } - - /* put hash into the S-Exp s_hash */ - if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) ) - BUG (); - gcry_mpi_release (frame); - - - rc = gcry_pk_verify (s_sig, s_hash, s_pkey); - if (DBG_CRYPTO) - log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc)); - gcry_md_close (md); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_pkey); - return rc; -} - - - -int -gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, - gcry_md_hd_t md, int algo) -{ - int rc; - ksba_sexp_t p; - gcry_mpi_t frame; - gcry_sexp_t s_sig, s_hash, s_pkey; - size_t n; - - n = gcry_sexp_canon_len (sigval, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - return gpg_error (GPG_ERR_BUG); - } - rc = gcry_sexp_sscan (&s_sig, NULL, sigval, n); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - return rc; - } - - p = ksba_cert_get_public_key (cert); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - ksba_free (p); - gcry_sexp_release (s_sig); - return gpg_error (GPG_ERR_BUG); - } - if (DBG_X509) - log_printhex ("public key: ", p, n); - - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); - ksba_free (p); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - gcry_sexp_release (s_sig); - return rc; - } - - - rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame); - if (rc) - { - gcry_sexp_release (s_sig); - gcry_sexp_release (s_pkey); - return rc; - } - /* put hash into the S-Exp s_hash */ - if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) ) - BUG (); - gcry_mpi_release (frame); - - rc = gcry_pk_verify (s_sig, s_hash, s_pkey); - if (DBG_CRYPTO) - log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc)); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_pkey); - return rc; -} - - - -int -gpgsm_create_cms_signature (ctrl_t ctrl, ksba_cert_t cert, - gcry_md_hd_t md, int mdalgo, char **r_sigval) -{ - int rc; - char *grip, *desc; - size_t siglen; - - grip = gpgsm_get_keygrip_hexstring (cert); - if (!grip) - return gpg_error (GPG_ERR_BAD_CERT); - - desc = gpgsm_format_keydesc (cert); - - rc = gpgsm_agent_pksign (ctrl, grip, desc, gcry_md_read(md, mdalgo), - gcry_md_get_algo_dlen (mdalgo), mdalgo, - r_sigval, &siglen); - xfree (desc); - xfree (grip); - return rc; -} - - - diff --git a/sm/certdump.c b/sm/certdump.c deleted file mode 100644 index 21581dca3..000000000 --- a/sm/certdump.c +++ /dev/null @@ -1,696 +0,0 @@ -/* certdump.c - Dump a certificate for debugging - * Copyright (C) 2001, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif -#ifdef HAVE_LANGINFO_CODESET -#include <langinfo.h> -#endif - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - -struct dn_array_s { - char *key; - char *value; - int multivalued; - int done; -}; - - -/* print the first element of an S-Expression */ -void -gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p) -{ - unsigned long n; - char *endp; - - if (!p) - fputs (_("none"), fp); - else if (*p != '(') - fputs ("[Internal error - not an S-expression]", fp); - else - { - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p!=':') - fputs ("[Internal Error - invalid S-expression]", fp); - else - { - for (p++; n; n--, p++) - fprintf (fp, "%02X", *p); - } - } -} - - -void -gpgsm_dump_serial (ksba_const_sexp_t p) -{ - unsigned long n; - char *endp; - - if (!p) - log_printf ("none"); - else if (*p != '(') - log_printf ("ERROR - not an S-expression"); - else - { - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p!=':') - log_printf ("ERROR - invalid S-expression"); - else - { - for (p++; n; n--, p++) - log_printf ("%02X", *p); - } - } -} - - -char * -gpgsm_format_serial (ksba_const_sexp_t p) -{ - unsigned long n; - char *endp; - char *buffer; - int i; - - if (!p) - return NULL; - - if (*p != '(') - BUG (); /* Not a valid S-expression. */ - - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p!=':') - BUG (); /* Not a valid S-expression. */ - p++; - - buffer = xtrymalloc (n*2+1); - if (buffer) - { - for (i=0; n; n--, p++, i+=2) - sprintf (buffer+i, "%02X", *(unsigned char *)p); - buffer[i] = 0; - } - return buffer; -} - - - - -void -gpgsm_print_time (FILE *fp, ksba_isotime_t t) -{ - if (!t || !*t) - fputs (_("none"), fp); - else - fprintf (fp, "%.4s-%.2s-%.2s %.2s:%.2s:%s", t, t+4, t+6, t+9, t+11, t+13); -} - -void -gpgsm_dump_time (ksba_isotime_t t) -{ - if (!t || !*t) - log_printf (_("[none]")); - else - log_printf ("%.4s-%.2s-%.2s %.2s:%.2s:%s", - t, t+4, t+6, t+9, t+11, t+13); -} - - - - -void -gpgsm_dump_string (const char *string) -{ - - if (!string) - log_printf ("[error]"); - else - { - const unsigned char *s; - - for (s=string; *s; s++) - { - if (*s < ' ' || (*s >= 0x7f && *s <= 0xa0)) - break; - } - if (!*s && *string != '[') - log_printf ("%s", string); - else - { - log_printf ( "[ "); - log_printhex (NULL, string, strlen (string)); - log_printf ( " ]"); - } - } -} - - -/* This simple dump function is mainly used for debugging purposes. */ -void -gpgsm_dump_cert (const char *text, ksba_cert_t cert) -{ - ksba_sexp_t sexp; - unsigned char *p; - char *dn; - ksba_isotime_t t; - - log_debug ("BEGIN Certificate `%s':\n", text? text:""); - if (cert) - { - sexp = ksba_cert_get_serial (cert); - log_debug (" serial: "); - gpgsm_dump_serial (sexp); - ksba_free (sexp); - log_printf ("\n"); - - ksba_cert_get_validity (cert, 0, t); - log_debug (" notBefore: "); - gpgsm_dump_time (t); - log_printf ("\n"); - ksba_cert_get_validity (cert, 1, t); - log_debug (" notAfter: "); - gpgsm_dump_time (t); - log_printf ("\n"); - - dn = ksba_cert_get_issuer (cert, 0); - log_debug (" issuer: "); - gpgsm_dump_string (dn); - ksba_free (dn); - log_printf ("\n"); - - dn = ksba_cert_get_subject (cert, 0); - log_debug (" subject: "); - gpgsm_dump_string (dn); - ksba_free (dn); - log_printf ("\n"); - - log_debug (" hash algo: %s\n", ksba_cert_get_digest_algo (cert)); - - p = gpgsm_get_fingerprint_string (cert, 0); - log_debug (" SHA1 Fingerprint: %s\n", p); - xfree (p); - } - log_debug ("END Certificate\n"); -} - - - -/* helper for the rfc2253 string parser */ -static const unsigned char * -parse_dn_part (struct dn_array_s *array, const unsigned char *string) -{ - static struct { - const char *label; - const char *oid; - } label_map[] = { - /* Warning: When adding new labels, make sure that the buffer - below we be allocated large enough. */ - {"EMail", "1.2.840.113549.1.9.1" }, - {"T", "2.5.4.12" }, - {"GN", "2.5.4.42" }, - {"SN", "2.5.4.4" }, - {"NameDistinguisher", "0.2.262.1.10.7.20"}, - {"ADDR", "2.5.4.16" }, - {"BC", "2.5.4.15" }, - {"D", "2.5.4.13" }, - {"PostalCode", "2.5.4.17" }, - {"Pseudo", "2.5.4.65" }, - {"SerialNumber", "2.5.4.5" }, - {NULL, NULL} - }; - const unsigned char *s, *s1; - size_t n; - unsigned char *p; - int i; - - /* Parse attributeType */ - for (s = string+1; *s && *s != '='; s++) - ; - if (!*s) - return NULL; /* error */ - n = s - string; - if (!n) - return NULL; /* empty key */ - - /* We need to allocate a few bytes more due to the possible mapping - from the shorter OID to the longer label. */ - array->key = p = xtrymalloc (n+10); - if (!array->key) - return NULL; - memcpy (p, string, n); - p[n] = 0; - trim_trailing_spaces (p); - - if (digitp (p)) - { - for (i=0; label_map[i].label; i++ ) - if ( !strcmp (p, label_map[i].oid) ) - { - strcpy (p, label_map[i].label); - break; - } - } - string = s + 1; - - if (*string == '#') - { /* hexstring */ - string++; - for (s=string; hexdigitp (s); s++) - s++; - n = s - string; - if (!n || (n & 1)) - return NULL; /* Empty or odd number of digits. */ - n /= 2; - array->value = p = xtrymalloc (n+1); - if (!p) - return NULL; - for (s1=string; n; s1 += 2, n--, p++) - { - *p = xtoi_2 (s1); - if (!*p) - *p = 0x01; /* Better print a wrong value than truncating - the string. */ - } - *p = 0; - } - else - { /* regular v3 quoted string */ - for (n=0, s=string; *s; s++) - { - if (*s == '\\') - { /* pair */ - s++; - if (*s == ',' || *s == '=' || *s == '+' - || *s == '<' || *s == '>' || *s == '#' || *s == ';' - || *s == '\\' || *s == '\"' || *s == ' ') - n++; - else if (hexdigitp (s) && hexdigitp (s+1)) - { - s++; - n++; - } - else - return NULL; /* invalid escape sequence */ - } - else if (*s == '\"') - return NULL; /* invalid encoding */ - else if (*s == ',' || *s == '=' || *s == '+' - || *s == '<' || *s == '>' || *s == '#' || *s == ';' ) - break; - else - n++; - } - - array->value = p = xtrymalloc (n+1); - if (!p) - return NULL; - for (s=string; n; s++, n--) - { - if (*s == '\\') - { - s++; - if (hexdigitp (s)) - { - *p++ = xtoi_2 (s); - s++; - } - else - *p++ = *s; - } - else - *p++ = *s; - } - *p = 0; - } - return s; -} - - -/* Parse a DN and return an array-ized one. This is not a validating - parser and it does not support any old-stylish syntax; KSBA is - expected to return only rfc2253 compatible strings. */ -static struct dn_array_s * -parse_dn (const unsigned char *string) -{ - struct dn_array_s *array; - size_t arrayidx, arraysize; - int i; - - arraysize = 7; /* C,ST,L,O,OU,CN,email */ - arrayidx = 0; - array = xtrymalloc ((arraysize+1) * sizeof *array); - if (!array) - return NULL; - while (*string) - { - while (*string == ' ') - string++; - if (!*string) - break; /* ready */ - if (arrayidx >= arraysize) - { - struct dn_array_s *a2; - - arraysize += 5; - a2 = xtryrealloc (array, (arraysize+1) * sizeof *array); - if (!a2) - goto failure; - array = a2; - } - array[arrayidx].key = NULL; - array[arrayidx].value = NULL; - string = parse_dn_part (array+arrayidx, string); - if (!string) - goto failure; - while (*string == ' ') - string++; - array[arrayidx].multivalued = (*string == '+'); - array[arrayidx].done = 0; - arrayidx++; - if (*string && *string != ',' && *string != ';' && *string != '+') - goto failure; /* invalid delimiter */ - if (*string) - string++; - } - array[arrayidx].key = NULL; - array[arrayidx].value = NULL; - return array; - - failure: - for (i=0; i < arrayidx; i++) - { - xfree (array[i].key); - xfree (array[i].value); - } - xfree (array); - return NULL; -} - - -static void -print_dn_part (FILE *fp, struct dn_array_s *dn, const char *key) -{ - struct dn_array_s *first_dn = dn; - - for (; dn->key; dn++) - { - if (!dn->done && !strcmp (dn->key, key)) - { - /* Forward to the last multi-valued RDN, so that we can - print them all in reverse in the correct order. Note - that this overrides the the standard sequence but that - seems to a reasonable thing to do with multi-valued - RDNs. */ - while (dn->multivalued && dn[1].key) - dn++; - next: - if (!dn->done && dn->value && *dn->value) - { - fprintf (fp, "/%s=", dn->key); - print_sanitized_utf8_string (fp, dn->value, '/'); - } - dn->done = 1; - if (dn > first_dn && dn[-1].multivalued) - { - dn--; - goto next; - } - } - } -} - -/* Print all parts of a DN in a "standard" sequence. We first print - all the known parts, followed by the uncommon ones */ -static void -print_dn_parts (FILE *fp, struct dn_array_s *dn) -{ - const char *stdpart[] = { - "CN", "OU", "O", "STREET", "L", "ST", "C", "EMail", NULL - }; - int i; - - for (i=0; stdpart[i]; i++) - print_dn_part (fp, dn, stdpart[i]); - - /* Now print the rest without any specific ordering */ - for (; dn->key; dn++) - print_dn_part (fp, dn, dn->key); -} - - - -void -gpgsm_print_name (FILE *fp, const char *name) -{ - const unsigned char *s; - int i; - - s = name; - if (!s) - { - fputs (_("[Error - No name]"), fp); - } - else if (*s == '<') - { - const unsigned char *s2 = strchr (s+1, '>'); - if (s2) - print_sanitized_utf8_buffer (fp, s + 1, s2 - s - 1, 0); - } - else if (*s == '(') - fputs (_("[Error - unknown encoding]"), fp); - else if (!((*s >= '0' && *s < '9') - || (*s >= 'A' && *s <= 'Z') - || (*s >= 'a' && *s <= 'z'))) - fputs (_("[Error - invalid encoding]"), fp); - else - { - struct dn_array_s *dn = parse_dn (s); - if (!dn) - fputs (_("[Error - invalid DN]"), fp); - else - { - print_dn_parts (fp, dn); - for (i=0; dn[i].key; i++) - { - xfree (dn[i].key); - xfree (dn[i].value); - } - xfree (dn); - } - } -} - - - -/* A cookie structure used for the memory stream. */ -struct format_name_cookie -{ - char *buffer; /* Malloced buffer with the data to deliver. */ - size_t size; /* Allocated size of this buffer. */ - size_t len; /* strlen (buffer). */ - int error; /* system error code if any. */ -}; - -/* The writer function for the memory stream. */ -static int -format_name_writer (void *cookie, const char *buffer, size_t size) -{ - struct format_name_cookie *c = cookie; - char *p; - - if (c->buffer) - p = xtryrealloc (c->buffer, c->size + size + 1); - else - p = xtrymalloc (size + 1); - if (!p) - { - c->error = errno; - xfree (c->buffer); - errno = c->error; - return -1; - } - c->buffer = p; - memcpy (p + c->len, buffer, size); - c->len += size; - p[c->len] = 0; /* Terminate string. */ - - return size; -} - -/* Format NAME which is expected to be in rfc2253 format into a better - human readable format. Caller must free the returned string. NULL - is returned in case of an error. */ -char * -gpgsm_format_name (const char *name) -{ -#if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN) - FILE *fp; - struct format_name_cookie cookie; - - memset (&cookie, 0, sizeof cookie); - -#ifdef HAVE_FOPENCOOKIE - { - cookie_io_functions_t io = { NULL }; - io.write = format_name_writer; - - fp = fopencookie (&cookie, "w", io); - } -#else /*!HAVE_FOPENCOOKIE*/ - { - fp = funopen (&cookie, NULL, format_name_writer, NULL, NULL); - } -#endif /*!HAVE_FOPENCOOKIE*/ - if (!fp) - { - int save_errno = errno; - log_error ("error creating memory stream: %s\n", strerror (errno)); - errno = save_errno; - return NULL; - } - gpgsm_print_name (fp, name); - fclose (fp); - if (cookie.error || !cookie.buffer) - { - xfree (cookie.buffer); - errno = cookie.error; - return NULL; - } - return cookie.buffer; -#else /* No fun - use the name verbatim. */ - return xtrystrdup (name); -#endif /* No fun. */ -} - - -/* Create a key description for the CERT, this may be passed to the - pinentry. The caller must free the returned string. NULL may be - returned on error. */ -char * -gpgsm_format_keydesc (ksba_cert_t cert) -{ - int rc; - char *name, *subject, *buffer, *p; - const char *s; - ksba_isotime_t t; - char created[20]; - char *sn; - ksba_sexp_t sexp; - char *orig_codeset = NULL; - - name = ksba_cert_get_subject (cert, 0); - subject = name? gpgsm_format_name (name) : NULL; - ksba_free (name); name = NULL; - - sexp = ksba_cert_get_serial (cert); - sn = sexp? gpgsm_format_serial (sexp) : NULL; - ksba_free (sexp); - - ksba_cert_get_validity (cert, 0, t); - if (t && *t) - sprintf (created, "%.4s-%.2s-%.2s", t, t+4, t+6); - else - *created = 0; - - -#ifdef ENABLE_NLS - /* The Assuan agent protol requires us to transmit utf-8 strings */ - orig_codeset = bind_textdomain_codeset (PACKAGE_GT, NULL); -#ifdef HAVE_LANGINFO_CODESET - if (!orig_codeset) - orig_codeset = nl_langinfo (CODESET); -#endif - if (orig_codeset) - { /* We only switch when we are able to restore the codeset later. */ - orig_codeset = xstrdup (orig_codeset); - if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8")) - orig_codeset = NULL; - } -#endif - - - rc = asprintf (&name, - _("Please enter the passphrase to unlock the" - " secret key for:\n" - "\"%s\"\n" - "S/N %s, ID %08lX, created %s" ), - subject? subject:"?", - sn? sn: "?", - gpgsm_get_short_fingerprint (cert), - created); - -#ifdef ENABLE_NLS - if (orig_codeset) - bind_textdomain_codeset (PACKAGE_GT, orig_codeset); -#endif - xfree (orig_codeset); - - if (rc < 0) - { - int save_errno = errno; - xfree (subject); - xfree (sn); - errno = save_errno; - return NULL; - } - - xfree (subject); - xfree (sn); - - buffer = p = xtrymalloc (strlen (name) * 3 + 1); - for (s=name; *s; s++) - { - if (*s < ' ' || *s == '+') - { - sprintf (p, "%%%02X", *(unsigned char *)s); - p += 3; - } - else if (*s == ' ') - *p++ = '+'; - else - *p++ = *s; - } - *p = 0; - free (name); - - return buffer; -} diff --git a/sm/certlist.c b/sm/certlist.c deleted file mode 100644 index 96acf90f7..000000000 --- a/sm/certlist.c +++ /dev/null @@ -1,427 +0,0 @@ -/* certlist.c - build list of certificates - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - - -static const char oid_kp_serverAuth[] = "1.3.6.1.5.5.7.3.1"; -static const char oid_kp_clientAuth[] = "1.3.6.1.5.5.7.3.2"; -static const char oid_kp_codeSigning[] = "1.3.6.1.5.5.7.3.3"; -static const char oid_kp_emailProtection[]= "1.3.6.1.5.5.7.3.4"; -static const char oid_kp_timeStamping[] = "1.3.6.1.5.5.7.3.8"; -static const char oid_kp_ocspSigning[] = "1.3.6.1.5.6.7.3.9"; - -/* Return 0 if the cert is usable for encryption. A MODE of 0 checks - for signing a MODE of 1 checks for encryption, a MODE of 2 checks - for verification and a MODE of 3 for decryption (just for - debugging) */ -static int -cert_usage_p (ksba_cert_t cert, int mode) -{ - gpg_error_t err; - unsigned int use; - char *extkeyusages; - - err = ksba_cert_get_ext_key_usages (cert, &extkeyusages); - if (gpg_err_code (err) == GPG_ERR_NO_DATA) - err = 0; /* no policy given */ - if (!err) - { - unsigned int extusemask = ~0; /* Allow all. */ - - if (extkeyusages) - { - char *p, *pend; - int any_critical = 0; - - extusemask = 0; - - p = extkeyusages; - while (p && (pend=strchr (p, ':'))) - { - *pend++ = 0; - /* Only care about critical flagged usages. */ - if ( *pend == 'C' ) - { - any_critical = 1; - if ( !strcmp (p, oid_kp_serverAuth)) - extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE - | KSBA_KEYUSAGE_KEY_ENCIPHERMENT - | KSBA_KEYUSAGE_KEY_AGREEMENT); - else if ( !strcmp (p, oid_kp_clientAuth)) - extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE - | KSBA_KEYUSAGE_KEY_AGREEMENT); - else if ( !strcmp (p, oid_kp_codeSigning)) - extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE); - else if ( !strcmp (p, oid_kp_emailProtection)) - extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE - | KSBA_KEYUSAGE_NON_REPUDIATION - | KSBA_KEYUSAGE_KEY_ENCIPHERMENT - | KSBA_KEYUSAGE_KEY_AGREEMENT); - else if ( !strcmp (p, oid_kp_timeStamping)) - extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE - | KSBA_KEYUSAGE_NON_REPUDIATION); - } - - if ((p = strchr (pend, '\n'))) - p++; - } - xfree (extkeyusages); - extkeyusages = NULL; - - if (!any_critical) - extusemask = ~0; /* Reset to the don't care mask. */ - } - - - err = ksba_cert_get_key_usage (cert, &use); - if (gpg_err_code (err) == GPG_ERR_NO_DATA) - { - err = 0; - if (opt.verbose && mode < 2) - log_info (_("no key usage specified - assuming all usages\n")); - use = ~0; - } - - /* Apply extKeyUsage. */ - use &= extusemask; - - } - if (err) - { - log_error (_("error getting key usage information: %s\n"), - gpg_strerror (err)); - xfree (extkeyusages); - return err; - } - - if (mode == 4) - { - if ((use & (KSBA_KEYUSAGE_KEY_CERT_SIGN))) - return 0; - log_info (_("certificate should have not " - "been used for certification\n")); - return gpg_error (GPG_ERR_WRONG_KEY_USAGE); - } - - if ((use & ((mode&1)? - (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT): - (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION))) - ) - return 0; - - log_info (mode==3? _("certificate should have not been used for encryption\n"): - mode==2? _("certificate should have not been used for signing\n"): - mode==1? _("certificate is not usable for encryption\n"): - _("certificate is not usable for signing\n")); - return gpg_error (GPG_ERR_WRONG_KEY_USAGE); -} - - -/* Return 0 if the cert is usable for signing */ -int -gpgsm_cert_use_sign_p (ksba_cert_t cert) -{ - return cert_usage_p (cert, 0); -} - - -/* Return 0 if the cert is usable for encryption */ -int -gpgsm_cert_use_encrypt_p (ksba_cert_t cert) -{ - return cert_usage_p (cert, 1); -} - -int -gpgsm_cert_use_verify_p (ksba_cert_t cert) -{ - return cert_usage_p (cert, 2); -} - -int -gpgsm_cert_use_decrypt_p (ksba_cert_t cert) -{ - return cert_usage_p (cert, 3); -} - -int -gpgsm_cert_use_cert_p (ksba_cert_t cert) -{ - return cert_usage_p (cert, 4); -} - - -static int -same_subject_issuer (const char *subject, const char *issuer, ksba_cert_t cert) -{ - char *subject2 = ksba_cert_get_subject (cert, 0); - char *issuer2 = ksba_cert_get_subject (cert, 0); - int tmp; - - tmp = (subject && subject2 - && !strcmp (subject, subject2) - && issuer && issuer2 - && !strcmp (issuer, issuer2)); - xfree (subject2); - xfree (issuer2); - return tmp; -} - -/* Return true if CERT is already contained in CERTLIST. */ -static int -is_cert_in_certlist (ksba_cert_t cert, certlist_t certlist) -{ - const unsigned char *img_a, *img_b; - size_t len_a, len_b; - - img_a = ksba_cert_get_image (cert, &len_a); - if (img_a) - { - for ( ; certlist; certlist = certlist->next) - { - img_b = ksba_cert_get_image (certlist->cert, &len_b); - if (img_b && len_a == len_b && !memcmp (img_a, img_b, len_a)) - return 1; /* Already contained. */ - } - } - return 0; -} - - -/* Add CERT to the list of certificates at CERTADDR but avoid - duplicates. */ -int -gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert, - certlist_t *listaddr, int is_encrypt_to) -{ - if (!is_cert_in_certlist (cert, *listaddr)) - { - certlist_t cl = xtrycalloc (1, sizeof *cl); - if (!cl) - return OUT_OF_CORE (errno); - cl->cert = cert; - ksba_cert_ref (cert); - cl->next = *listaddr; - cl->is_encrypt_to = is_encrypt_to; - *listaddr = cl; - } - return 0; -} - -/* Add a certificate to a list of certificate and make sure that it is - a valid certificate. With SECRET set to true a secret key must be - available for the certificate. IS_ENCRYPT_TO sets the corresponding - flag in the new create LISTADDR item. */ -int -gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret, - CERTLIST *listaddr, int is_encrypt_to) -{ - int rc; - KEYDB_SEARCH_DESC desc; - KEYDB_HANDLE kh = NULL; - ksba_cert_t cert = NULL; - - rc = keydb_classify_name (name, &desc); - if (!rc) - { - kh = keydb_new (0); - if (!kh) - rc = gpg_error (GPG_ERR_ENOMEM); - else - { - int wrong_usage = 0; - char *subject = NULL; - char *issuer = NULL; - - get_next: - rc = keydb_search (kh, &desc, 1); - if (!rc) - rc = keydb_get_cert (kh, &cert); - if (!rc) - { - rc = secret? gpgsm_cert_use_sign_p (cert) - : gpgsm_cert_use_encrypt_p (cert); - if (gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE) - { - /* There might be another certificate with the - correct usage, so we try again */ - if (!wrong_usage) - { /* save the first match */ - wrong_usage = rc; - subject = ksba_cert_get_subject (cert, 0); - issuer = ksba_cert_get_subject (cert, 0); - ksba_cert_release (cert); - cert = NULL; - goto get_next; - } - else if (same_subject_issuer (subject, issuer, cert)) - { - wrong_usage = rc; - ksba_cert_release (cert); - cert = NULL; - goto get_next; - } - else - wrong_usage = rc; - - } - } - /* We want the error code from the first match in this case. */ - if (rc && wrong_usage) - rc = wrong_usage; - - if (!rc) - { - next_ambigious: - rc = keydb_search (kh, &desc, 1); - if (rc == -1) - rc = 0; - else if (!rc) - { - ksba_cert_t cert2 = NULL; - - /* We have to ignore ambigious names as long as - there only fault is a bad key usage */ - if (!keydb_get_cert (kh, &cert2)) - { - int tmp = (same_subject_issuer (subject, issuer, cert2) - && ((gpg_err_code ( - secret? gpgsm_cert_use_sign_p (cert2) - : gpgsm_cert_use_encrypt_p (cert2) - ) - ) == GPG_ERR_WRONG_KEY_USAGE)); - ksba_cert_release (cert2); - if (tmp) - goto next_ambigious; - } - rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME); - } - } - xfree (subject); - xfree (issuer); - - if (!rc && !is_cert_in_certlist (cert, *listaddr)) - { - if (!rc && secret) - { - char *p; - - rc = gpg_error (GPG_ERR_NO_SECKEY); - p = gpgsm_get_keygrip_hexstring (cert); - if (p) - { - if (!gpgsm_agent_havekey (ctrl, p)) - rc = 0; - xfree (p); - } - } - if (!rc) - rc = gpgsm_validate_chain (ctrl, cert, NULL, 0, NULL, 0); - if (!rc) - { - CERTLIST cl = xtrycalloc (1, sizeof *cl); - if (!cl) - rc = OUT_OF_CORE (errno); - else - { - cl->cert = cert; cert = NULL; - cl->next = *listaddr; - cl->is_encrypt_to = is_encrypt_to; - *listaddr = cl; - } - } - } - } - } - - keydb_release (kh); - ksba_cert_release (cert); - return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc; -} - -void -gpgsm_release_certlist (CERTLIST list) -{ - while (list) - { - CERTLIST cl = list->next; - ksba_cert_release (list->cert); - xfree (list); - list = cl; - } -} - - -/* Like gpgsm_add_to_certlist, but look only for one certificate. No - chain validation is done */ -int -gpgsm_find_cert (const char *name, ksba_cert_t *r_cert) -{ - int rc; - KEYDB_SEARCH_DESC desc; - KEYDB_HANDLE kh = NULL; - - *r_cert = NULL; - rc = keydb_classify_name (name, &desc); - if (!rc) - { - kh = keydb_new (0); - if (!kh) - rc = gpg_error (GPG_ERR_ENOMEM); - else - { - rc = keydb_search (kh, &desc, 1); - if (!rc) - rc = keydb_get_cert (kh, r_cert); - if (!rc) - { - rc = keydb_search (kh, &desc, 1); - if (rc == -1) - rc = 0; - else - { - if (!rc) - rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME); - ksba_cert_release (*r_cert); - *r_cert = NULL; - } - } - } - } - - keydb_release (kh); - return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc; -} - diff --git a/sm/certreqgen.c b/sm/certreqgen.c deleted file mode 100644 index 969ed14b0..000000000 --- a/sm/certreqgen.c +++ /dev/null @@ -1,739 +0,0 @@ -/* certreqgen.c - Generate a key and a certification request - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* -The format of the native parameter file is follows: - o Text only, line length is limited to about 1000 chars. - o You must use UTF-8 encoding to specify non-ascii characters. - o Empty lines are ignored. - o Leading and trailing spaces are ignored. - o A hash sign as the first non white space character is a comment line. - o Control statements are indicated by a leading percent sign, the - arguments are separated by white space from the keyword. - o Parameters are specified by a keyword, followed by a colon. Arguments - are separated by white space. - o The first parameter must be "Key-Type", control statements - may be placed anywhere. - o Key generation takes place when either the end of the parameter file - is reached, the next "Key-Type" parameter is encountered or at the - controlstatement "%commit" - o Control statements: - %echo <text> - Print <text>. - %dry-run - Suppress actual key generation (useful for syntax checking). - %commit - Perform the key generation. Note that an implicit commit is done - at the next "Key-Type" parameter. - %certfile <filename> - Do not write the certificate to the keyDB but to <filename>. - This must be given before the first - commit to take place, duplicate specification of the same filename - is ignored, the last filename before a commit is used. - The filename is used until a new filename is used (at commit points) - and all keys are written to that file. If a new filename is given, - this file is created (and overwrites an existing one). - Both control statements must be given. - o The order of the parameters does not matter except for "Key-Type" - which must be the first parameter. The parameters are only for the - generated keyblock and parameters from previous key generations are not - used. Some syntactically checks may be performed. - The currently defined parameters are: - Key-Type: <algo> - Starts a new parameter block by giving the type of the - primary key. The algorithm must be capable of signing. - This is a required parameter. For now the only supported - algorithm is "rsa". - Key-Length: <length-in-bits> - Length of the key in bits. Default is 1024. - Key-Usage: <usage-list> - Space or comma delimited list of key usage, allowed values are - "encrypt" and "sign". This is used to generate the KeyUsage extension. - Please make sure that the algorithm is capable of this usage. Default - is to allow encrypt and sign. - Name-DN: subject name - This is the DN name of the subject in rfc2253 format. - Name-Email: <string> - The ist the email address - -Here is an example: -$ cat >foo <<EOF -%echo Generating a standard key -Key-Type: RSA -Key-Length: 1024 -Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Düsseldorf,C=DE -Name-Email: joe@foo.bar -# Do a commit here, so that we can later print "done" :-) -%commit -%echo done -EOF -*/ - - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - - -enum para_name { - pKEYTYPE, - pKEYLENGTH, - pKEYUSAGE, - pNAMEDN, - pNAMEEMAIL -}; - -struct para_data_s { - struct para_data_s *next; - int lnr; - enum para_name key; - union { - unsigned int usage; - char value[1]; - } u; -}; - -struct reqgen_ctrl_s { - int lnr; - int dryrun; - ksba_writer_t writer; -}; - - -static const char oidstr_keyUsage[] = "2.5.29.15"; - - -static int proc_parameters (ctrl_t ctrl, - struct para_data_s *para, - struct reqgen_ctrl_s *outctrl); -static int create_request (ctrl_t ctrl, - struct para_data_s *para, - ksba_const_sexp_t public, - struct reqgen_ctrl_s *outctrl); - - - -static void -release_parameter_list (struct para_data_s *r) -{ - struct para_data_s *r2; - - for (; r ; r = r2) - { - r2 = r->next; - xfree(r); - } -} - -static struct para_data_s * -get_parameter (struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r; - - for (r = para; r && r->key != key; r = r->next) - ; - return r; -} - -static const char * -get_parameter_value (struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter (para, key); - return (r && *r->u.value)? r->u.value : NULL; -} - -static int -get_parameter_algo (struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter (para, key); - if (!r) - return -1; - if (digitp (r->u.value)) - return atoi( r->u.value ); - return gcry_pk_map_name (r->u.value); -} - -/* Parse the usage parameter. Returns 0 on success. Note that we - only care about sign and encrypt and don't (yet) allow all the - other X.509 usage to be specified; instead we will use a fixed - mapping to the X.509 usage flags. */ -static int -parse_parameter_usage (struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter (para, key); - char *p, *pn; - unsigned int use; - - if (!r) - return 0; /* none (this is an optional parameter)*/ - - use = 0; - pn = r->u.value; - while ( (p = strsep (&pn, " \t,")) ) - { - if (!*p) - ; - else if ( !ascii_strcasecmp (p, "sign") ) - use |= GCRY_PK_USAGE_SIGN; - else if ( !ascii_strcasecmp (p, "encrypt") ) - use |= GCRY_PK_USAGE_ENCR; - else - { - log_error ("line %d: invalid usage list\n", r->lnr); - return -1; /* error */ - } - } - r->u.usage = use; - return 0; -} - - -static unsigned int -get_parameter_uint (struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter (para, key); - - if (!r) - return 0; - - if (r->key == pKEYUSAGE) - return r->u.usage; - - return (unsigned int)strtoul (r->u.value, NULL, 10); -} - - - -/* Read the certificate generation parameters from FP and generate - (all) certificate requests. */ -static int -read_parameters (ctrl_t ctrl, FILE *fp, ksba_writer_t writer) -{ - static struct { - const char *name; - enum para_name key; - } keywords[] = { - { "Key-Type", pKEYTYPE}, - { "Key-Length", pKEYLENGTH }, - { "Key-Usage", pKEYUSAGE }, - { "Name-DN", pNAMEDN }, - { "Name-Email", pNAMEEMAIL }, - { NULL, 0 } - }; - char line[1024], *p; - const char *err = NULL; - struct para_data_s *para, *r; - int i, rc = 0, any = 0; - struct reqgen_ctrl_s outctrl; - - memset (&outctrl, 0, sizeof (outctrl)); - outctrl.writer = writer; - - err = NULL; - para = NULL; - while (fgets (line, DIM(line)-1, fp) ) - { - char *keyword, *value; - - outctrl.lnr++; - if (*line && line[strlen(line)-1] != '\n') - { - err = "line too long"; - break; - } - for (p=line; spacep (p); p++) - ; - if (!*p || *p == '#') - continue; - - keyword = p; - if (*keyword == '%') - { - for (; *p && !spacep (p); p++) - ; - if (*p) - *p++ = 0; - for (; spacep (p); p++) - ; - value = p; - trim_trailing_spaces (value); - - if (!ascii_strcasecmp (keyword, "%echo")) - log_info ("%s\n", value); - else if (!ascii_strcasecmp (keyword, "%dry-run")) - outctrl.dryrun = 1; - else if (!ascii_strcasecmp( keyword, "%commit")) - { - rc = proc_parameters (ctrl, para, &outctrl); - if (rc) - goto leave; - any = 1; - release_parameter_list (para); - para = NULL; - } - else - log_info ("skipping control `%s' (%s)\n", keyword, value); - - continue; - } - - - if (!(p = strchr (p, ':')) || p == keyword) - { - err = "missing colon"; - break; - } - if (*p) - *p++ = 0; - for (; spacep (p); p++) - ; - if (!*p) - { - err = "missing argument"; - break; - } - value = p; - trim_trailing_spaces (value); - - for (i=0; (keywords[i].name - && ascii_strcasecmp (keywords[i].name, keyword)); i++) - ; - if (!keywords[i].name) - { - err = "unknown keyword"; - break; - } - if (keywords[i].key != pKEYTYPE && !para) - { - err = "parameter block does not start with \"Key-Type\""; - break; - } - - if (keywords[i].key == pKEYTYPE && para) - { - rc = proc_parameters (ctrl, para, &outctrl); - if (rc) - goto leave; - any = 1; - release_parameter_list (para); - para = NULL; - } - else - { - for (r = para; r && r->key != keywords[i].key; r = r->next) - ; - if (r) - { - err = "duplicate keyword"; - break; - } - } - - r = xtrycalloc (1, sizeof *r + strlen( value )); - if (!r) - { - err = "out of core"; - break; - } - r->lnr = outctrl.lnr; - r->key = keywords[i].key; - strcpy (r->u.value, value); - r->next = para; - para = r; - } - - if (err) - { - log_error ("line %d: %s\n", outctrl.lnr, err); - rc = gpg_error (GPG_ERR_GENERAL); - } - else if (ferror(fp)) - { - log_error ("line %d: read error: %s\n", outctrl.lnr, strerror(errno) ); - rc = gpg_error (GPG_ERR_GENERAL); - } - else if (para) - { - rc = proc_parameters (ctrl, para, &outctrl); - if (rc) - goto leave; - any = 1; - } - - if (!rc && !any) - rc = gpg_error (GPG_ERR_NO_DATA); - - leave: - release_parameter_list (para); - return rc; -} - -/* check whether there are invalid characters in the email address S */ -static int -has_invalid_email_chars (const char *s) -{ - int at_seen=0; - static char valid_chars[] = "01234567890_-." - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - for (; *s; s++) - { - if (*s & 0x80) - return 1; - if (*s == '@') - at_seen++; - else if (!at_seen && !( !!strchr (valid_chars, *s) || *s == '+')) - return 1; - else if (at_seen && !strchr (valid_chars, *s)) - return 1; - } - return at_seen != 1; -} - - -/* Check that all required parameters are given and perform the action */ -static int -proc_parameters (ctrl_t ctrl, - struct para_data_s *para, struct reqgen_ctrl_s *outctrl) -{ - struct para_data_s *r; - const char *s; - int i; - unsigned int nbits; - char numbuf[20]; - unsigned char keyparms[100]; - int rc; - ksba_sexp_t public; - - /* check that we have all required parameters */ - assert (get_parameter (para, pKEYTYPE)); - - /* We can only use RSA for now. There is a with pkcs-10 on how to - use ElGamal because it is expected that a PK algorithm can always - be used for signing. */ - i = get_parameter_algo (para, pKEYTYPE); - if (i < 1 || i != GCRY_PK_RSA ) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: invalid algorithm\n", r->lnr); - return gpg_error (GPG_ERR_INV_PARAMETER); - } - - /* check the keylength */ - if (!get_parameter (para, pKEYLENGTH)) - nbits = 1024; - else - nbits = get_parameter_uint (para, pKEYLENGTH); - if (nbits < 512 || nbits > 4096) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: invalid key length %u (valid are 512 to 4096)\n", - r->lnr, nbits); - return gpg_error (GPG_ERR_INV_PARAMETER); - } - - /* check the usage */ - if (parse_parameter_usage (para, pKEYUSAGE)) - return gpg_error (GPG_ERR_INV_PARAMETER); - - /* check that there is a subject name and that this DN fits our - requirements */ - if (!(s=get_parameter_value (para, pNAMEDN))) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: no subject name given\n", r->lnr); - return gpg_error (GPG_ERR_INV_PARAMETER); - } - /* fixme check s */ - - /* check that the optional email address is okay */ - if ((s=get_parameter_value (para, pNAMEEMAIL))) - { - if (has_invalid_email_chars (s) - || *s == '@' - || s[strlen(s)-1] == '@' - || s[strlen(s)-1] == '.' - || strstr(s, "..")) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: not a valid email address\n", r->lnr); - return gpg_error (GPG_ERR_INV_PARAMETER); - } - } - - sprintf (numbuf, "%u", nbits); - snprintf (keyparms, DIM (keyparms)-1, - "(6:genkey(3:rsa(5:nbits%d:%s)))", strlen (numbuf), numbuf); - rc = gpgsm_agent_genkey (ctrl, keyparms, &public); - if (rc) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: key generation failed: %s\n", - r->lnr, gpg_strerror (rc)); - return rc; - } - - rc = create_request (ctrl, para, public, outctrl); - xfree (public); - - return rc; -} - - -/* Parameters are checked, the key pair has been created. Now - generate the request and write it out */ -static int -create_request (ctrl_t ctrl, - struct para_data_s *para, ksba_const_sexp_t public, - struct reqgen_ctrl_s *outctrl) -{ - ksba_certreq_t cr; - gpg_error_t err; - gcry_md_hd_t md; - ksba_stop_reason_t stopreason; - int rc = 0; - const char *s; - unsigned int use; - - err = ksba_certreq_new (&cr); - if (err) - return err; - - rc = gcry_md_open (&md, GCRY_MD_SHA1, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if (DBG_HASHING) - gcry_md_start_debug (md, "cr.cri"); - - ksba_certreq_set_hash_function (cr, HASH_FNC, md); - ksba_certreq_set_writer (cr, outctrl->writer); - - err = ksba_certreq_add_subject (cr, get_parameter_value (para, pNAMEDN)); - if (err) - { - log_error ("error setting the subject's name: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - s = get_parameter_value (para, pNAMEEMAIL); - if (s) - { - char *buf; - - buf = xtrymalloc (strlen (s) + 3); - if (!buf) - { - rc = OUT_OF_CORE (errno); - goto leave; - } - *buf = '<'; - strcpy (buf+1, s); - strcat (buf+1, ">"); - err = ksba_certreq_add_subject (cr, buf); - xfree (buf); - if (err) - { - log_error ("error setting the subject's alternate name: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - - - err = ksba_certreq_set_public_key (cr, public); - if (err) - { - log_error ("error setting the public key: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - - use = get_parameter_uint (para, pKEYUSAGE); - if (use == GCRY_PK_USAGE_SIGN) - { - /* For signing only we encode the bits: - KSBA_KEYUSAGE_DIGITAL_SIGNATURE - KSBA_KEYUSAGE_NON_REPUDIATION */ - err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1, - "\x03\x02\x06\xC0", 4); - } - else if (use == GCRY_PK_USAGE_ENCR) - { - /* For encrypt only we encode the bits: - KSBA_KEYUSAGE_KEY_ENCIPHERMENT - KSBA_KEYUSAGE_DATA_ENCIPHERMENT */ - err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1, - "\x03\x02\x04\x30", 4); - } - else - err = 0; /* Both or none given: don't request one. */ - if (err) - { - log_error ("error setting the key usage: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - - do - { - err = ksba_certreq_build (cr, &stopreason); - if (err) - { - log_error ("ksba_certreq_build failed: %s\n", gpg_strerror (err)); - rc = err; - goto leave; - } - if (stopreason == KSBA_SR_NEED_SIG) - { - gcry_sexp_t s_pkey; - size_t n; - unsigned char grip[20], hexgrip[41]; - char *sigval; - size_t siglen; - - n = gcry_sexp_canon_len (public, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - err = gpg_error (GPG_ERR_BUG); - goto leave; - } - rc = gcry_sexp_sscan (&s_pkey, NULL, public, n); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if ( !gcry_pk_get_keygrip (s_pkey, grip) ) - { - rc = gpg_error (GPG_ERR_GENERAL); - log_error ("can't figure out the keygrip\n"); - gcry_sexp_release (s_pkey); - goto leave; - } - gcry_sexp_release (s_pkey); - for (n=0; n < 20; n++) - sprintf (hexgrip+n*2, "%02X", grip[n]); - - rc = gpgsm_agent_pksign (ctrl, hexgrip, NULL, - gcry_md_read(md, GCRY_MD_SHA1), - gcry_md_get_algo_dlen (GCRY_MD_SHA1), - GCRY_MD_SHA1, - &sigval, &siglen); - if (rc) - { - log_error ("signing failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - err = ksba_certreq_set_sig_val (cr, sigval); - xfree (sigval); - if (err) - { - log_error ("failed to store the sig_val: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - } - while (stopreason != KSBA_SR_READY); - - - leave: - gcry_md_close (md); - ksba_certreq_release (cr); - return rc; -} - - - -/* Create a new key by reading the parameters from in_fd. Multiple - keys may be created */ -int -gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *out_fp) -{ - int rc; - FILE *in_fp; - Base64Context b64writer = NULL; - ksba_writer_t writer; - - in_fp = fdopen (dup (in_fd), "rb"); - if (!in_fp) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("fdopen() failed: %s\n", strerror (errno)); - return tmperr; - } - - ctrl->pem_name = "NEW CERTIFICATE REQUEST"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - - rc = read_parameters (ctrl, in_fp, writer); - if (rc) - { - log_error ("error creating certificate request: %s\n", - gpg_strerror (rc)); - goto leave; - } - - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - gpgsm_status (ctrl, STATUS_KEY_CREATED, "P"); - log_info ("certificate request created\n"); - - leave: - gpgsm_destroy_writer (b64writer); - fclose (in_fp); - return rc; -} - diff --git a/sm/decrypt.c b/sm/decrypt.c deleted file mode 100644 index 8ac2e23fe..000000000 --- a/sm/decrypt.c +++ /dev/null @@ -1,512 +0,0 @@ -/* decrypt.c - Decrypt a message - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - -struct decrypt_filter_parm_s { - int algo; - int mode; - int blklen; - gcry_cipher_hd_t hd; - char iv[16]; - size_t ivlen; - int any_data; /* dod we push anything through the filter at all? */ - unsigned char lastblock[16]; /* to strip the padding we have to - keep this one */ - char helpblock[16]; /* needed because there is no block buffering in - libgcrypt (yet) */ - int helpblocklen; -}; - - - -/* Decrypt the session key and fill in the parm structure. The - algo and the IV is expected to be already in PARM. */ -static int -prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc, - ksba_const_sexp_t enc_val, - struct decrypt_filter_parm_s *parm) -{ - char *seskey = NULL; - size_t n, seskeylen; - int rc; - - rc = gpgsm_agent_pkdecrypt (ctrl, hexkeygrip, desc, enc_val, - &seskey, &seskeylen); - if (rc) - { - log_error ("error decrypting session key: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (DBG_CRYPTO) - log_printhex ("pkcs1 encoded session key:", seskey, seskeylen); - - n=0; - if (seskeylen == 24) - { - /* Smells like a 3-des key. This might happen because a SC has - already done the unpacking. */ - } - else - { - if (n + 7 > seskeylen ) - { - rc = gpg_error (GPG_ERR_INV_SESSION_KEY); - goto leave; - } - - /* FIXME: Actually the leading zero is required but due to the way - we encode the output in libgcrypt as an MPI we are not able to - encode that leading zero. However, when using a Smartcard we are - doing it the right way and therefore we have to skip the zero. This - should be fixed in gpg-agent of course. */ - if (!seskey[n]) - n++; - - if (seskey[n] != 2 ) /* Wrong block type version. */ - { - rc = gpg_error (GPG_ERR_INV_SESSION_KEY); - goto leave; - } - - for (n++; n < seskeylen && seskey[n]; n++) /* Skip the random bytes. */ - ; - n++; /* and the zero byte */ - if (n >= seskeylen ) - { - rc = gpg_error (GPG_ERR_INV_SESSION_KEY); - goto leave; - } - } - - if (DBG_CRYPTO) - log_printhex ("session key:", seskey+n, seskeylen-n); - - rc = gcry_cipher_open (&parm->hd, parm->algo, parm->mode, 0); - if (rc) - { - log_error ("error creating decryptor: %s\n", gpg_strerror (rc)); - goto leave; - } - - rc = gcry_cipher_setkey (parm->hd, seskey+n, seskeylen-n); - if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY) - { - log_info (_("WARNING: message was encrypted with " - "a weak key in the symmetric cipher.\n")); - rc = 0; - } - if (rc) - { - log_error("key setup failed: %s\n", gpg_strerror(rc) ); - goto leave; - } - - gcry_cipher_setiv (parm->hd, parm->iv, parm->ivlen); - - leave: - xfree (seskey); - return rc; -} - - -/* This function is called by the KSBA writer just before the actual - write is done. The function must take INLEN bytes from INBUF, - decrypt it and store it inoutbuf which has a maximum size of - maxoutlen. The valid bytes in outbuf should be return in outlen. - Due to different buffer sizes or different length of input and - output, it may happen that fewer bytes are process or fewer bytes - are written. */ -static gpg_error_t -decrypt_filter (void *arg, - const void *inbuf, size_t inlen, size_t *inused, - void *outbuf, size_t maxoutlen, size_t *outlen) -{ - struct decrypt_filter_parm_s *parm = arg; - int blklen = parm->blklen; - size_t orig_inlen = inlen; - - /* fixme: Should we issue an error when we have not seen one full block? */ - if (!inlen) - return gpg_error (GPG_ERR_BUG); - - if (maxoutlen < 2*parm->blklen) - return gpg_error (GPG_ERR_BUG); - /* make some space becuase we will later need an extra block at the end */ - maxoutlen -= blklen; - - if (parm->helpblocklen) - { - int i, j; - - for (i=parm->helpblocklen,j=0; i < blklen && j < inlen; i++, j++) - parm->helpblock[i] = ((const char*)inbuf)[j]; - inlen -= j; - if (blklen > maxoutlen) - return gpg_error (GPG_ERR_BUG); - if (i < blklen) - { - parm->helpblocklen = i; - *outlen = 0; - } - else - { - parm->helpblocklen = 0; - if (parm->any_data) - { - memcpy (outbuf, parm->lastblock, blklen); - *outlen =blklen; - } - else - *outlen = 0; - gcry_cipher_decrypt (parm->hd, parm->lastblock, blklen, - parm->helpblock, blklen); - parm->any_data = 1; - } - *inused = orig_inlen - inlen; - return 0; - } - - - if (inlen > maxoutlen) - inlen = maxoutlen; - if (inlen % blklen) - { /* store the remainder away */ - parm->helpblocklen = inlen%blklen; - inlen = inlen/blklen*blklen; - memcpy (parm->helpblock, (const char*)inbuf+inlen, parm->helpblocklen); - } - - *inused = inlen + parm->helpblocklen; - if (inlen) - { - assert (inlen >= blklen); - if (parm->any_data) - { - gcry_cipher_decrypt (parm->hd, (char*)outbuf+blklen, inlen, - inbuf, inlen); - memcpy (outbuf, parm->lastblock, blklen); - memcpy (parm->lastblock,(char*)outbuf+inlen, blklen); - *outlen = inlen; - } - else - { - gcry_cipher_decrypt (parm->hd, outbuf, inlen, inbuf, inlen); - memcpy (parm->lastblock, (char*)outbuf+inlen-blklen, blklen); - *outlen = inlen - blklen; - parm->any_data = 1; - } - } - else - *outlen = 0; - return 0; -} - - - -/* Perform a decrypt operation. */ -int -gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp) -{ - int rc; - Base64Context b64reader = NULL; - Base64Context b64writer = NULL; - ksba_reader_t reader; - ksba_writer_t writer; - ksba_cms_t cms = NULL; - ksba_stop_reason_t stopreason; - KEYDB_HANDLE kh; - int recp; - FILE *in_fp = NULL; - struct decrypt_filter_parm_s dfparm; - - memset (&dfparm, 0, sizeof dfparm); - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - - in_fp = fdopen ( dup (in_fd), "rb"); - if (!in_fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("fdopen() failed: %s\n", strerror (errno)); - goto leave; - } - - rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader); - if (rc) - { - log_error ("can't create reader: %s\n", gpg_strerror (rc)); - goto leave; - } - - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - - rc = ksba_cms_new (&cms); - if (rc) - goto leave; - - rc = ksba_cms_set_reader_writer (cms, reader, writer); - if (rc) - { - log_debug ("ksba_cms_set_reader_writer failed: %s\n", - gpg_strerror (rc)); - goto leave; - } - - /* parser loop */ - do - { - rc = ksba_cms_parse (cms, &stopreason); - if (rc) - { - log_debug ("ksba_cms_parse failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (stopreason == KSBA_SR_BEGIN_DATA - || stopreason == KSBA_SR_DETACHED_DATA) - { - int algo, mode; - const char *algoid; - int any_key = 0; - - algoid = ksba_cms_get_content_oid (cms, 2/* encryption algo*/); - algo = gcry_cipher_map_name (algoid); - mode = gcry_cipher_mode_from_oid (algoid); - if (!algo || !mode) - { - rc = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - log_error ("unsupported algorithm `%s'\n", algoid? algoid:"?"); - if (algoid && !strcmp (algoid, "1.2.840.113549.3.2")) - log_info (_("(this is the RC2 algorithm)\n")); - else if (!algoid) - log_info (_("(this does not seem to be an encrypted" - " message)\n")); - { - char numbuf[50]; - sprintf (numbuf, "%d", rc); - gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm", - numbuf, algoid?algoid:"?", NULL); - } - - /* If it seems that this is not an ecrypted message we - return a more sensible error code. */ - if (!algoid) - rc = gpg_error (GPG_ERR_NO_DATA); - - goto leave; - } - dfparm.algo = algo; - dfparm.mode = mode; - dfparm.blklen = gcry_cipher_get_algo_blklen (algo); - if (dfparm.blklen > sizeof (dfparm.helpblock)) - return gpg_error (GPG_ERR_BUG); - - rc = ksba_cms_get_content_enc_iv (cms, - dfparm.iv, - sizeof (dfparm.iv), - &dfparm.ivlen); - if (rc) - { - log_error ("error getting IV: %s\n", gpg_strerror (rc)); - goto leave; - } - - for (recp=0; !any_key; recp++) - { - char *issuer; - ksba_sexp_t serial; - ksba_sexp_t enc_val; - char *hexkeygrip = NULL; - char *desc = NULL; - - rc = ksba_cms_get_issuer_serial (cms, recp, &issuer, &serial); - if (rc == -1 && recp) - break; /* no more recipients */ - if (rc) - log_error ("recp %d - error getting info: %s\n", - recp, gpg_strerror (rc)); - else - { - ksba_cert_t cert = NULL; - - log_debug ("recp %d - issuer: `%s'\n", - recp, issuer? issuer:"[NONE]"); - log_debug ("recp %d - serial: ", recp); - gpgsm_dump_serial (serial); - log_printf ("\n"); - - keydb_search_reset (kh); - rc = keydb_search_issuer_sn (kh, issuer, serial); - if (rc) - { - log_error ("failed to find the certificate: %s\n", - gpg_strerror(rc)); - goto oops; - } - - rc = keydb_get_cert (kh, &cert); - if (rc) - { - log_error ("failed to get cert: %s\n", gpg_strerror (rc)); - goto oops; - } - /* Just in case there is a problem with the own - certificate we print this message - should never - happen of course */ - rc = gpgsm_cert_use_decrypt_p (cert); - if (rc) - { - char numbuf[50]; - sprintf (numbuf, "%d", rc); - gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.keyusage", - numbuf, NULL); - rc = 0; - } - - hexkeygrip = gpgsm_get_keygrip_hexstring (cert); - desc = gpgsm_format_keydesc (cert); - - oops: - xfree (issuer); - xfree (serial); - ksba_cert_release (cert); - } - - if (!hexkeygrip) - ; - else if (!(enc_val = ksba_cms_get_enc_val (cms, recp))) - log_error ("recp %d - error getting encrypted session key\n", - recp); - else - { - rc = prepare_decryption (ctrl, - hexkeygrip, desc, enc_val, &dfparm); - xfree (enc_val); - if (rc) - { - log_info ("decrypting session key failed: %s\n", - gpg_strerror (rc)); - } - else - { /* setup the bulk decrypter */ - any_key = 1; - ksba_writer_set_filter (writer, - decrypt_filter, - &dfparm); - } - } - xfree (hexkeygrip); - xfree (desc); - } - if (!any_key) - { - rc = gpg_error (GPG_ERR_NO_SECKEY); - goto leave; - } - } - else if (stopreason == KSBA_SR_END_DATA) - { - ksba_writer_set_filter (writer, NULL, NULL); - if (dfparm.any_data) - { /* write the last block with padding removed */ - int i, npadding = dfparm.lastblock[dfparm.blklen-1]; - if (!npadding || npadding > dfparm.blklen) - { - log_error ("invalid padding with value %d\n", npadding); - rc = gpg_error (GPG_ERR_INV_DATA); - goto leave; - } - rc = ksba_writer_write (writer, - dfparm.lastblock, - dfparm.blklen - npadding); - if (rc) - goto leave; - - for (i=dfparm.blklen - npadding; i < dfparm.blklen; i++) - { - if (dfparm.lastblock[i] != npadding) - { - log_error ("inconsistent padding\n"); - rc = gpg_error (GPG_ERR_INV_DATA); - goto leave; - } - } - } - } - - } - while (stopreason != KSBA_SR_READY); - - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - gpgsm_status (ctrl, STATUS_DECRYPTION_OKAY, NULL); - - - leave: - if (rc) - { - gpgsm_status (ctrl, STATUS_DECRYPTION_FAILED, NULL); - log_error ("message decryption failed: %s <%s>\n", - gpg_strerror (rc), gpg_strsource (rc)); - } - ksba_cms_release (cms); - gpgsm_destroy_reader (b64reader); - gpgsm_destroy_writer (b64writer); - keydb_release (kh); - if (in_fp) - fclose (in_fp); - if (dfparm.hd) - gcry_cipher_close (dfparm.hd); - return rc; -} - - diff --git a/sm/delete.c b/sm/delete.c deleted file mode 100644 index 11a0a5476..000000000 --- a/sm/delete.c +++ /dev/null @@ -1,172 +0,0 @@ -/* delete.c - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - - -/* Delete a certificate or an secret key from a key database. */ -static int -delete_one (CTRL ctrl, const char *username) -{ - int rc = 0; - KEYDB_SEARCH_DESC desc; - KEYDB_HANDLE kh = NULL; - ksba_cert_t cert = NULL; - int duplicates = 0; - - rc = keydb_classify_name (username, &desc); - if (rc) - { - log_error (_("certificate `%s' not found: %s\n"), - username, gpg_strerror (rc)); - gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "1", NULL); - goto leave; - } - - kh = keydb_new (0); - if (!kh) - { - log_error ("keydb_new failed\n"); - goto leave; - } - - - rc = keydb_search (kh, &desc, 1); - if (!rc) - rc = keydb_get_cert (kh, &cert); - if (!rc) - { - char fpr[20]; - - gpgsm_get_fingerprint (cert, 0, fpr, NULL); - - next_ambigious: - rc = keydb_search (kh, &desc, 1); - if (rc == -1) - rc = 0; - else if (!rc) - { - ksba_cert_t cert2 = NULL; - char fpr2[20]; - - /* We ignore all duplicated certificates which might have - been inserted due to program bugs. */ - if (!keydb_get_cert (kh, &cert2)) - { - gpgsm_get_fingerprint (cert2, 0, fpr2, NULL); - ksba_cert_release (cert2); - if (!memcmp (fpr, fpr2, 20)) - { - duplicates++; - goto next_ambigious; - } - } - rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME); - } - } - if (rc) - { - if (rc == -1) - rc = gpg_error (GPG_ERR_NO_PUBKEY); - log_error (_("certificate `%s' not found: %s\n"), - username, gpg_strerror (rc)); - gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "3", NULL); - goto leave; - } - - /* We need to search again to get back to the right position. */ - rc = keydb_lock (kh); - if (rc) - { - log_error (_("error locking keybox: %s\n"), gpg_strerror (rc)); - goto leave; - } - - do - { - keydb_search_reset (kh); - rc = keydb_search (kh, &desc, 1); - if (rc) - { - log_error ("problem re-searching certificate: %s\n", - gpg_strerror (rc)); - goto leave; - } - - rc = keydb_delete (kh); - if (rc) - goto leave; - if (opt.verbose) - { - if (duplicates) - log_info (_("duplicated certificate `%s' deleted\n"), username); - else - log_info (_("certificate `%s' deleted\n"), username); - } - } - while (duplicates--); - - leave: - keydb_release (kh); - ksba_cert_release (cert); - return rc; -} - - - -/* Delete the certificates specified by NAMES. */ -int -gpgsm_delete (CTRL ctrl, STRLIST names) -{ - int rc; - - if (!names) - { - log_error ("nothing to delete\n"); - return gpg_error (GPG_ERR_NO_DATA); - } - - for (; names; names=names->next ) - { - rc = delete_one (ctrl, names->d); - if (rc) - { - log_error (_("deleting certificate \"%s\" failed: %s\n"), - names->d, gpg_strerror (rc) ); - return rc; - } - } - - return 0; -} diff --git a/sm/encrypt.c b/sm/encrypt.c deleted file mode 100644 index 50da92c32..000000000 --- a/sm/encrypt.c +++ /dev/null @@ -1,511 +0,0 @@ -/* encrypt.c - Encrypt a message - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - - -struct dek_s { - const char *algoid; - int algo; - gcry_cipher_hd_t chd; - char key[32]; - int keylen; - char iv[32]; - int ivlen; -}; -typedef struct dek_s *DEK; - -struct encrypt_cb_parm_s { - FILE *fp; - DEK dek; - int eof_seen; - int ready; - int readerror; - int bufsize; - unsigned char *buffer; - int buflen; -}; - - - - - -/* Initialize the data encryption key (session key). */ -static int -init_dek (DEK dek) -{ - int rc=0, mode, i; - - dek->algo = gcry_cipher_map_name (dek->algoid); - mode = gcry_cipher_mode_from_oid (dek->algoid); - if (!dek->algo || !mode) - { - log_error ("unsupported algorithm `%s'\n", dek->algoid); - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - } - - /* Extra check for algorithms we considere to be to weak for - encryption, qlthough we suppor them fro decryption. Note that - there is another check below discriminating on the key length. */ - switch (dek->algo) - { - case GCRY_CIPHER_DES: - case GCRY_CIPHER_RFC2268_40: - log_error ("cipher algorithm `%s' not allowed: too weak\n", - gcry_cipher_algo_name (dek->algo)); - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - default: - break; - } - - dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); - if (!dek->keylen || dek->keylen > sizeof (dek->key)) - return gpg_error (GPG_ERR_BUG); - - dek->ivlen = gcry_cipher_get_algo_blklen (dek->algo); - if (!dek->ivlen || dek->ivlen > sizeof (dek->iv)) - return gpg_error (GPG_ERR_BUG); - - /* Make sure we don't use weak keys. */ - if (dek->keylen < 100/8) - { - log_error ("key length of `%s' too small\n", dek->algoid); - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - } - - rc = gcry_cipher_open (&dek->chd, dek->algo, mode, GCRY_CIPHER_SECURE); - if (rc) - { - log_error ("failed to create cipher context: %s\n", gpg_strerror (rc)); - return rc; - } - - for (i=0; i < 8; i++) - { - gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM ); - rc = gcry_cipher_setkey (dek->chd, dek->key, dek->keylen); - if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY) - break; - log_info(_("weak key created - retrying\n") ); - } - if (rc) - { - log_error ("failed to set the key: %s\n", gpg_strerror (rc)); - gcry_cipher_close (dek->chd); - dek->chd = NULL; - return rc; - } - - gcry_create_nonce (dek->iv, dek->ivlen); - rc = gcry_cipher_setiv (dek->chd, dek->iv, dek->ivlen); - if (rc) - { - log_error ("failed to set the IV: %s\n", gpg_strerror (rc)); - gcry_cipher_close (dek->chd); - dek->chd = NULL; - return rc; - } - - return 0; -} - - -static int -encode_session_key (DEK dek, gcry_sexp_t * r_data) -{ - gcry_sexp_t data; - char * p, tmp[3]; - int i; - int rc; - - p = xmalloc (64 + 2 * dek->keylen); - strcpy (p, "(data\n (flags pkcs1)\n (value #"); - for (i=0; i < dek->keylen; i++) - { - sprintf (tmp, "%02x", (unsigned char) dek->key[i]); - strcat (p, tmp); - } - strcat (p, "#))\n"); - rc = gcry_sexp_sscan (&data, NULL, p, strlen (p)); - xfree (p); - *r_data = data; - return rc; -} - - -/* encrypt the DEK under the key contained in CERT and return it as a - canonical S-Exp in encval */ -static int -encrypt_dek (const DEK dek, ksba_cert_t cert, char **encval) -{ - gcry_sexp_t s_ciph, s_data, s_pkey; - int rc; - ksba_sexp_t buf; - size_t len; - - *encval = NULL; - - /* get the key from the cert */ - buf = ksba_cert_get_public_key (cert); - if (!buf) - { - log_error ("no public key for recipient\n"); - return gpg_error (GPG_ERR_NO_PUBKEY); - } - len = gcry_sexp_canon_len (buf, 0, NULL, NULL); - if (!len) - { - log_error ("libksba did not return a proper S-Exp\n"); - return gpg_error (GPG_ERR_BUG); - } - rc = gcry_sexp_sscan (&s_pkey, NULL, buf, len); - xfree (buf); buf = NULL; - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - return rc; - } - - /* put the encoded cleartext into a simple list */ - rc = encode_session_key (dek, &s_data); - if (rc) - { - log_error ("encode_session_key failed: %s\n", gpg_strerror (rc)); - return rc; - } - - /* pass it to libgcrypt */ - rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); - gcry_sexp_release (s_data); - gcry_sexp_release (s_pkey); - - /* reformat it */ - len = gcry_sexp_sprint (s_ciph, GCRYSEXP_FMT_CANON, NULL, 0); - assert (len); - buf = xtrymalloc (len); - if (!buf) - { - gpg_error_t tmperr = OUT_OF_CORE (errno); - gcry_sexp_release (s_ciph); - return tmperr; - } - len = gcry_sexp_sprint (s_ciph, GCRYSEXP_FMT_CANON, buf, len); - assert (len); - - *encval = buf; - return 0; -} - - - -/* do the actual encryption */ -static int -encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread) -{ - struct encrypt_cb_parm_s *parm = cb_value; - int blklen = parm->dek->ivlen; - unsigned char *p; - size_t n; - - *nread = 0; - if (!buffer) - return -1; /* not supported */ - - if (parm->ready) - return -1; - - if (count < blklen) - BUG (); - - if (!parm->eof_seen) - { /* fillup the buffer */ - p = parm->buffer; - for (n=parm->buflen; n < parm->bufsize; n++) - { - int c = getc (parm->fp); - if (c == EOF) - { - if (ferror (parm->fp)) - { - parm->readerror = errno; - return -1; - } - parm->eof_seen = 1; - break; - } - p[n] = c; - } - parm->buflen = n; - } - - n = parm->buflen < count? parm->buflen : count; - n = n/blklen * blklen; - if (n) - { /* encrypt the stuff */ - gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n); - *nread = n; - /* Who cares about cycles, take the easy way and shift the buffer */ - parm->buflen -= n; - memmove (parm->buffer, parm->buffer+n, parm->buflen); - } - else if (parm->eof_seen) - { /* no complete block but eof: add padding */ - /* fixme: we should try to do this also in the above code path */ - int i, npad = blklen - (parm->buflen % blklen); - p = parm->buffer; - for (n=parm->buflen, i=0; n < parm->bufsize && i < npad; n++, i++) - p[n] = npad; - gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n); - *nread = n; - parm->ready = 1; - } - - return 0; -} - - - - -/* Perform an encrypt operation. - - Encrypt the data received on DATA-FD and write it to OUT_FP. The - recipients are take from the certificate given in recplist; if this - is NULL it will be encrypted for a default recipient */ -int -gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp) -{ - int rc = 0; - Base64Context b64writer = NULL; - gpg_error_t err; - ksba_writer_t writer; - ksba_reader_t reader = NULL; - ksba_cms_t cms = NULL; - ksba_stop_reason_t stopreason; - KEYDB_HANDLE kh = NULL; - struct encrypt_cb_parm_s encparm; - DEK dek = NULL; - int recpno; - FILE *data_fp = NULL; - CERTLIST cl; - - memset (&encparm, 0, sizeof encparm); - - /* Check that the certificate list is not empty and that at least - one certificate is not flagged as encrypt_to; i.e. is a real - recipient. */ - for (cl = recplist; cl; cl = cl->next) - if (!cl->is_encrypt_to) - break; - if (!cl) - { - log_error(_("no valid recipients given\n")); - gpgsm_status (ctrl, STATUS_NO_RECP, "0"); - rc = gpg_error (GPG_ERR_NO_PUBKEY); - goto leave; - } - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - data_fp = fdopen ( dup (data_fd), "rb"); - if (!data_fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("fdopen() failed: %s\n", strerror (errno)); - goto leave; - } - - err = ksba_reader_new (&reader); - if (err) - rc = err; - if (!rc) - rc = ksba_reader_set_cb (reader, encrypt_cb, &encparm); - if (rc) - goto leave; - - encparm.fp = data_fp; - - ctrl->pem_name = "ENCRYPTED MESSAGE"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - - err = ksba_cms_new (&cms); - if (err) - { - rc = err; - goto leave; - } - - err = ksba_cms_set_reader_writer (cms, reader, writer); - if (err) - { - log_debug ("ksba_cms_set_reader_writer failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - /* We are going to create enveloped data with uninterpreted data as - inner content */ - err = ksba_cms_set_content_type (cms, 0, KSBA_CT_ENVELOPED_DATA); - if (!err) - err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA); - if (err) - { - log_debug ("ksba_cms_set_content_type failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - /* Create a session key */ - dek = xtrycalloc_secure (1, sizeof *dek); - if (!dek) - rc = OUT_OF_CORE (errno); - else - { - dek->algoid = opt.def_cipher_algoid; - rc = init_dek (dek); - } - if (rc) - { - log_error ("failed to create the session key: %s\n", - gpg_strerror (rc)); - goto leave; - } - - err = ksba_cms_set_content_enc_algo (cms, dek->algoid, dek->iv, dek->ivlen); - if (err) - { - log_error ("ksba_cms_set_content_enc_algo failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - encparm.dek = dek; - /* Use a ~8k (AES) or ~4k (3DES) buffer */ - encparm.bufsize = 500 * dek->ivlen; - encparm.buffer = xtrymalloc (encparm.bufsize); - if (!encparm.buffer) - { - rc = OUT_OF_CORE (errno); - goto leave; - } - - /* Gather certificates of recipients, encrypt the session key for - each and store them in the CMS object */ - for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next) - { - char *encval; - - rc = encrypt_dek (dek, cl->cert, &encval); - if (rc) - { - log_error ("encryption failed for recipient no. %d: %s\n", - recpno, gpg_strerror (rc)); - goto leave; - } - - err = ksba_cms_add_recipient (cms, cl->cert); - if (err) - { - log_error ("ksba_cms_add_recipient failed: %s\n", - gpg_strerror (err)); - rc = err; - xfree (encval); - goto leave; - } - - err = ksba_cms_set_enc_val (cms, recpno, encval); - xfree (encval); - if (err) - { - log_error ("ksba_cms_set_enc_val failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - - /* Main control loop for encryption. */ - recpno = 0; - do - { - err = ksba_cms_build (cms, &stopreason); - if (err) - { - log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err)); - rc = err; - goto leave; - } - } - while (stopreason != KSBA_SR_READY); - - if (encparm.readerror) - { - log_error ("error reading input: %s\n", strerror (encparm.readerror)); - rc = gpg_error (gpg_err_code_from_errno (encparm.readerror)); - goto leave; - } - - - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - log_info ("encrypted data created\n"); - - leave: - ksba_cms_release (cms); - gpgsm_destroy_writer (b64writer); - ksba_reader_release (reader); - keydb_release (kh); - xfree (dek); - if (data_fp) - fclose (data_fp); - xfree (encparm.buffer); - return rc; -} diff --git a/sm/export.c b/sm/export.c deleted file mode 100644 index 3f7457502..000000000 --- a/sm/export.c +++ /dev/null @@ -1,736 +0,0 @@ -/* export.c - * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#include <signal.h> -#include <fcntl.h> -#include <sys/wait.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - - -/* A table to store a fingerprint as used in a duplicates table. We - don't need to hash here because a fingerprint is alrady a perfect - hash value. This we use the most significant bits to index the - table and then use a linked list for the overflow. Possible - enhancement for very large number of certictates: Add a second - level table and then resort to a linked list. */ -struct duptable_s -{ - struct duptable_s *next; - - /* Note that we only need to store 19 bytes because the first byte - is implictly given by the table index (we require at least 8 - bits). */ - unsigned char fpr[19]; -}; -typedef struct duptable_s *duptable_t; -#define DUPTABLE_BITS 12 -#define DUPTABLE_SIZE (1 << DUPTABLE_BITS) - - -static void print_short_info (ksba_cert_t cert, FILE *fp); -static gpg_error_t export_p12 (const unsigned char *certimg, size_t certimglen, - const char *prompt, const char *keygrip, - FILE **retfp); - - -/* Create a table used to indetify duplicated certificates. */ -static duptable_t * -create_duptable (void) -{ - return xtrycalloc (DUPTABLE_SIZE, sizeof (duptable_t)); -} - -static void -destroy_duptable (duptable_t *table) -{ - int idx; - duptable_t t, t2; - - if (table) - { - for (idx=0; idx < DUPTABLE_SIZE; idx++) - for (t = table[idx]; t; t = t2) - { - t2 = t->next; - xfree (t); - } - xfree (table); - } -} - -/* Insert the 20 byte fingerprint FPR into TABLE. Sets EXITS to true - if the fingerprint already exists in the table. */ -static gpg_error_t -insert_duptable (duptable_t *table, unsigned char *fpr, int *exists) -{ - size_t idx; - duptable_t t; - - *exists = 0; - idx = fpr[0]; -#if DUPTABLE_BITS > 16 || DUPTABLE_BITS < 8 -#error cannot handle a table larger than 16 bits or smaller than 8 bits -#elif DUPTABLE_BITS > 8 - idx <<= (DUPTABLE_BITS - 8); - idx |= (fpr[1] & ~(~0 << 4)); -#endif - - for (t = table[idx]; t; t = t->next) - if (!memcmp (t->fpr, fpr+1, 19)) - break; - if (t) - { - *exists = 1; - return 0; - } - /* Insert that fingerprint. */ - t = xtrymalloc (sizeof *t); - if (!t) - return gpg_error_from_errno (errno); - memcpy (t->fpr, fpr+1, 19); - t->next = table[idx]; - table[idx] = t; - return 0; -} - - - - -/* Export all certificates or just those given in NAMES. */ -void -gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp) -{ - KEYDB_HANDLE hd = NULL; - KEYDB_SEARCH_DESC *desc = NULL; - int ndesc; - Base64Context b64writer = NULL; - ksba_writer_t writer; - STRLIST sl; - ksba_cert_t cert = NULL; - int rc=0; - int count = 0; - int i; - duptable_t *dtable; - - - dtable = create_duptable (); - if (!dtable) - { - log_error ("creating duplicates table failed: %s\n", strerror (errno)); - goto leave; - } - - hd = keydb_new (0); - if (!hd) - { - log_error ("keydb_new failed\n"); - goto leave; - } - - if (!names) - ndesc = 1; - else - { - for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) - ; - } - - desc = xtrycalloc (ndesc, sizeof *desc); - if (!ndesc) - { - log_error ("allocating memory for export failed: %s\n", - gpg_strerror (OUT_OF_CORE (errno))); - goto leave; - } - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_FIRST; - else - { - for (ndesc=0, sl=names; sl; sl = sl->next) - { - rc = keydb_classify_name (sl->d, desc+ndesc); - if (rc) - { - log_error ("key `%s' not found: %s\n", - sl->d, gpg_strerror (rc)); - rc = 0; - } - else - ndesc++; - } - } - - /* If all specifications are done by fingerprint, we switch to - ephemeral mode so that _all_ currently available and matching - certificates are exported. - - fixme: we should in this case keep a list of certificates to - avoid accidential export of duplicate certificates. */ - if (names && ndesc) - { - for (i=0; (i < ndesc - && (desc[i].mode == KEYDB_SEARCH_MODE_FPR - || desc[i].mode == KEYDB_SEARCH_MODE_FPR20 - || desc[i].mode == KEYDB_SEARCH_MODE_FPR16)); i++) - ; - if (i == ndesc) - keydb_set_ephemeral (hd, 1); - } - - while (!(rc = keydb_search (hd, desc, ndesc))) - { - unsigned char fpr[20]; - int exists; - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - - rc = keydb_get_cert (hd, &cert); - if (rc) - { - log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - gpgsm_get_fingerprint (cert, 0, fpr, NULL); - rc = insert_duptable (dtable, fpr, &exists); - if (rc) - { - log_error ("inserting into duplicates table fauiled: %s\n", - gpg_strerror (rc)); - goto leave; - } - - if (!exists && count && !ctrl->create_pem) - { - log_info ("exporting more than one certificate " - "is not possible in binary mode\n"); - log_info ("ignoring other certificates\n"); - break; - } - - if (!exists) - { - const unsigned char *image; - size_t imagelen; - - image = ksba_cert_get_image (cert, &imagelen); - if (!image) - { - log_error ("ksba_cert_get_image failed\n"); - goto leave; - } - - - if (ctrl->create_pem) - { - if (count) - putc ('\n', fp); - print_short_info (cert, fp); - putc ('\n', fp); - } - count++; - - if (!b64writer) - { - ctrl->pem_name = "CERTIFICATE"; - rc = gpgsm_create_writer (&b64writer, ctrl, fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - } - - rc = ksba_writer_write (writer, image, imagelen); - if (rc) - { - log_error ("write error: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (ctrl->create_pem) - { - /* We want one certificate per PEM block */ - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - gpgsm_destroy_writer (b64writer); - b64writer = NULL; - } - } - - ksba_cert_release (cert); - cert = NULL; - } - if (rc && rc != -1) - log_error ("keydb_search failed: %s\n", gpg_strerror (rc)); - else if (b64writer) - { - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - } - - leave: - gpgsm_destroy_writer (b64writer); - ksba_cert_release (cert); - xfree (desc); - keydb_release (hd); - destroy_duptable (dtable); -} - - -/* Export a certificates and its private key. */ -void -gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp) -{ - KEYDB_HANDLE hd; - KEYDB_SEARCH_DESC *desc = NULL; - Base64Context b64writer = NULL; - ksba_writer_t writer; - ksba_cert_t cert = NULL; - int rc=0; - const unsigned char *image; - size_t imagelen; - char *keygrip = NULL; - char *prompt; - char buffer[1024]; - int nread; - FILE *datafp = NULL; - - - hd = keydb_new (0); - if (!hd) - { - log_error ("keydb_new failed\n"); - goto leave; - } - - desc = xtrycalloc (1, sizeof *desc); - if (!desc) - { - log_error ("allocating memory for export failed: %s\n", - gpg_strerror (OUT_OF_CORE (errno))); - goto leave; - } - - rc = keydb_classify_name (name, desc); - if (rc) - { - log_error ("key `%s' not found: %s\n", - name, gpg_strerror (rc)); - goto leave; - } - - /* Lookup the certificate an make sure that it is unique. */ - rc = keydb_search (hd, desc, 1); - if (!rc) - { - rc = keydb_get_cert (hd, &cert); - if (rc) - { - log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - rc = keydb_search (hd, desc, 1); - if (!rc) - rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME); - else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) - rc = 0; - if (rc) - { - log_error ("key `%s' not found: %s\n", - name, gpg_strerror (rc)); - goto leave; - } - } - - keygrip = gpgsm_get_keygrip_hexstring (cert); - if (!keygrip || gpgsm_agent_havekey (ctrl, keygrip)) - { - /* Note, that the !keygrip case indicates a bad certificate. */ - rc = gpg_error (GPG_ERR_NO_SECKEY); - log_error ("can't export key `%s': %s\n", name, gpg_strerror (rc)); - goto leave; - } - - image = ksba_cert_get_image (cert, &imagelen); - if (!image) - { - log_error ("ksba_cert_get_image failed\n"); - goto leave; - } - - if (ctrl->create_pem) - { - print_short_info (cert, fp); - putc ('\n', fp); - } - - ctrl->pem_name = "PKCS12"; - rc = gpgsm_create_writer (&b64writer, ctrl, fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - - - prompt = gpgsm_format_keydesc (cert); - rc = export_p12 (image, imagelen, prompt, keygrip, &datafp); - xfree (prompt); - if (rc) - goto leave; - rewind (datafp); - while ( (nread = fread (buffer, 1, sizeof buffer, datafp)) > 0 ) - if ((rc = ksba_writer_write (writer, buffer, nread))) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if (ferror (datafp)) - { - rc = gpg_error_from_errno (rc); - log_error ("error reading temporary file: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (ctrl->create_pem) - { - /* We want one certificate per PEM block */ - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - gpgsm_destroy_writer (b64writer); - b64writer = NULL; - } - - ksba_cert_release (cert); - cert = NULL; - - leave: - if (datafp) - fclose (datafp); - gpgsm_destroy_writer (b64writer); - ksba_cert_release (cert); - xfree (desc); - keydb_release (hd); -} - - -/* Print some info about the certifciate CERT to FP */ -static void -print_short_info (ksba_cert_t cert, FILE *fp) -{ - char *p; - ksba_sexp_t sexp; - int idx; - - for (idx=0; (p = ksba_cert_get_issuer (cert, idx)); idx++) - { - fputs (!idx? "Issuer ...: " - : "\n aka ...: ", fp); - gpgsm_print_name (fp, p); - xfree (p); - } - putc ('\n', fp); - - fputs ("Serial ...: ", fp); - sexp = ksba_cert_get_serial (cert); - if (sexp) - { - int len; - const unsigned char *s = sexp; - - if (*s == '(') - { - s++; - for (len=0; *s && *s != ':' && digitp (s); s++) - len = len*10 + atoi_1 (s); - if (*s == ':') - for (s++; len; len--, s++) - fprintf (fp, "%02X", *s); - } - xfree (sexp); - } - putc ('\n', fp); - - for (idx=0; (p = ksba_cert_get_subject (cert, idx)); idx++) - { - fputs (!idx? "Subject ..: " - : "\n aka ..: ", fp); - gpgsm_print_name (fp, p); - xfree (p); - } - putc ('\n', fp); -} - - -static gpg_error_t -popen_protect_tool (const char *pgmname, - FILE *infile, FILE *outfile, FILE **statusfile, - const char *prompt, const char *keygrip, - pid_t *pid) -{ - gpg_error_t err; - int fd, fdout, rp[2]; - int n, i; - - fflush (infile); - rewind (infile); - fd = fileno (infile); - fdout = fileno (outfile); - if (fd == -1 || fdout == -1) - log_fatal ("no file descriptor for temporary file: %s\n", - strerror (errno)); - - /* Now start the protect-tool. */ - if (pipe (rp) == -1) - { - err = gpg_error_from_errno (errno); - log_error (_("error creating a pipe: %s\n"), strerror (errno)); - return err; - } - - *pid = fork (); - if (*pid == -1) - { - err = gpg_error_from_errno (errno); - log_error (_("error forking process: %s\n"), strerror (errno)); - close (rp[0]); - close (rp[1]); - return err; - } - - if (!*pid) - { /* Child. */ - const char *arg0; - - arg0 = strrchr (pgmname, '/'); - if (arg0) - arg0++; - else - arg0 = pgmname; - - /* Connect the infile to stdin. */ - if (fd != 0 && dup2 (fd, 0) == -1) - log_fatal ("dup2 stdin failed: %s\n", strerror (errno)); - - /* Connect the outfile to stdout. */ - if (fdout != 1 && dup2 (fdout, 1) == -1) - log_fatal ("dup2 stdout failed: %s\n", strerror (errno)); - - /* Connect stderr to our pipe. */ - if (rp[1] != 2 && dup2 (rp[1], 2) == -1) - log_fatal ("dup2 stderr failed: %s\n", strerror (errno)); - - /* Close all other files. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; - for (i=3; i < n; i++) - close(i); - errno = 0; - - setup_pinentry_env (); - - execlp (pgmname, arg0, - "--homedir", opt.homedir, - "--p12-export", - "--prompt", prompt?prompt:"", - "--", - keygrip, - NULL); - /* No way to print anything, as we have closed all streams. */ - _exit (31); - } - - /* Parent. */ - close (rp[1]); - *statusfile = fdopen (rp[0], "r"); - if (!*statusfile) - { - err = gpg_error_from_errno (errno); - log_error ("can't fdopen pipe for reading: %s", strerror (errno)); - kill (*pid, SIGTERM); - return err; - } - - return 0; -} - - -static gpg_error_t -export_p12 (const unsigned char *certimg, size_t certimglen, - const char *prompt, const char *keygrip, - FILE **retfp) -{ - const char *pgmname; - gpg_error_t err = 0, child_err = 0; - int i, c, cont_line; - unsigned int pos; - FILE *infp = NULL, *outfp = NULL, *fp = NULL; - char buffer[1024]; - pid_t pid = -1; - - if (!opt.protect_tool_program || !*opt.protect_tool_program) - pgmname = GNUPG_DEFAULT_PROTECT_TOOL; - else - pgmname = opt.protect_tool_program; - - infp = tmpfile (); - if (!infp) - { - err = gpg_error_from_errno (errno); - log_error (_("error creating temporary file: %s\n"), strerror (errno)); - goto cleanup; - } - - if (fwrite (certimg, certimglen, 1, infp) != 1) - { - err = gpg_error_from_errno (errno); - log_error (_("error writing to temporary file: %s\n"), - strerror (errno)); - goto cleanup; - } - - outfp = tmpfile (); - if (!outfp) - { - err = gpg_error_from_errno (errno); - log_error (_("error creating temporary file: %s\n"), strerror (errno)); - goto cleanup; - } - - err = popen_protect_tool (pgmname, infp, outfp, &fp, prompt, keygrip, &pid); - if (err) - { - pid = -1; - goto cleanup; - } - fclose (infp); - infp = NULL; - - /* Read stderr of the protect tool. */ - pos = 0; - cont_line = 0; - while ((c=getc (fp)) != EOF) - { - /* fixme: We could here grep for status information of the - protect tool to figure out better error codes for - CHILD_ERR. */ - buffer[pos++] = c; - if (pos >= sizeof buffer - 5 || c == '\n') - { - buffer[pos - (c == '\n')] = 0; - if (cont_line) - log_printf ("%s", buffer); - else - log_info ("%s", buffer); - pos = 0; - cont_line = (c != '\n'); - } - } - - if (pos) - { - buffer[pos] = 0; - if (cont_line) - log_printf ("%s\n", buffer); - else - log_info ("%s\n", buffer); - } - else if (cont_line) - log_printf ("\n"); - - /* If we found no error in the output of the child, setup a suitable - error code, which will later be reset if the exit status of the - child is 0. */ - if (!child_err) - child_err = gpg_error (GPG_ERR_DECRYPT_FAILED); - - cleanup: - if (infp) - fclose (infp); - if (fp) - fclose (fp); - if (pid != -1) - { - int status; - - while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR) - ; - if (i == -1) - log_error (_("waiting for protect-tools to terminate failed: %s\n"), - strerror (errno)); - else if (WIFEXITED (status) && WEXITSTATUS (status) == 31) - log_error (_("error running `%s': probably not installed\n"), pgmname); - else if (WIFEXITED (status) && WEXITSTATUS (status)) - log_error (_("error running `%s': exit status %d\n"), pgmname, - WEXITSTATUS (status)); - else if (!WIFEXITED (status)) - log_error (_("error running `%s': terminated\n"), pgmname); - else - child_err = 0; - } - if (!err) - err = child_err; - if (err) - { - if (outfp) - fclose (outfp); - } - else - *retfp = outfp; - return err; -} - diff --git a/sm/fingerprint.c b/sm/fingerprint.c deleted file mode 100644 index 7fe619c18..000000000 --- a/sm/fingerprint.c +++ /dev/null @@ -1,331 +0,0 @@ -/* fingerprint.c - Get the fingerprint - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -/* Return the fingerprint of the certificate (we can't put this into - libksba because we need libgcrypt support). The caller must - provide an array of sufficient length or NULL so that the function - allocates the array. If r_len is not NULL, the length of the - digest is returned; well, this can also be done by using - gcry_md_get_algo_dlen(). If algo is 0, a SHA-1 will be used. - - If there is a problem , the function does never return NULL but a - digest of all 0xff. - */ -char * -gpgsm_get_fingerprint (ksba_cert_t cert, int algo, char *array, int *r_len) -{ - gcry_md_hd_t md; - int rc, len; - - if (!algo) - algo = GCRY_MD_SHA1; - - len = gcry_md_get_algo_dlen (algo); - assert (len); - if (!array) - array = xmalloc (len); - - if (r_len) - *r_len = len; - - rc = gcry_md_open (&md, algo, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - memset (array, 0xff, len); /* better return an invalid fpr than NULL */ - return array; - } - - rc = ksba_cert_hash (cert, 0, HASH_FNC, md); - if (rc) - { - log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (rc)); - gcry_md_close (md); - memset (array, 0xff, len); /* better return an invalid fpr than NULL */ - return array; - } - gcry_md_final (md); - memcpy (array, gcry_md_read(md, algo), len ); - return array; -} - - -/* Return an allocated buffer with the formatted fingerprint */ -char * -gpgsm_get_fingerprint_string (ksba_cert_t cert, int algo) -{ - unsigned char digest[MAX_DIGEST_LEN]; - char *buf; - int len, i; - - if (!algo) - algo = GCRY_MD_SHA1; - - len = gcry_md_get_algo_dlen (algo); - assert (len <= MAX_DIGEST_LEN ); - gpgsm_get_fingerprint (cert, algo, digest, NULL); - buf = xmalloc (len*3+1); - *buf = 0; - for (i=0; i < len; i++ ) - sprintf (buf+strlen(buf), i? ":%02X":"%02X", digest[i]); - return buf; -} - -/* Return an allocated buffer with the formatted fingerprint as one - large hexnumber */ -char * -gpgsm_get_fingerprint_hexstring (ksba_cert_t cert, int algo) -{ - unsigned char digest[MAX_DIGEST_LEN]; - char *buf; - int len, i; - - if (!algo) - algo = GCRY_MD_SHA1; - - len = gcry_md_get_algo_dlen (algo); - assert (len <= MAX_DIGEST_LEN ); - gpgsm_get_fingerprint (cert, algo, digest, NULL); - buf = xmalloc (len*3+1); - *buf = 0; - for (i=0; i < len; i++ ) - sprintf (buf+strlen(buf), "%02X", digest[i]); - return buf; -} - -/* Return a certificate ID. These are the last 4 bytes of the SHA-1 - fingerprint. */ -unsigned long -gpgsm_get_short_fingerprint (ksba_cert_t cert) -{ - unsigned char digest[20]; - - gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); - return ((digest[16]<<24)|(digest[17]<<16)|(digest[18]<< 8)|digest[19]); -} - - -/* Return the so called KEYGRIP which is the SHA-1 hash of the public - key parameters expressed as an canoncial encoded S-Exp. array must - be 20 bytes long. returns the array or a newly allocated one if the - passed one was NULL */ -char * -gpgsm_get_keygrip (ksba_cert_t cert, char *array) -{ - gcry_sexp_t s_pkey; - int rc; - ksba_sexp_t p; - size_t n; - - p = ksba_cert_get_public_key (cert); - if (!p) - return NULL; /* oops */ - - if (DBG_X509) - log_debug ("get_keygrip for public key\n"); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - return NULL; - } - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); - xfree (p); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - return NULL; - } - array = gcry_pk_get_keygrip (s_pkey, array); - gcry_sexp_release (s_pkey); - if (!array) - { - rc = gpg_error (GPG_ERR_GENERAL); - log_error ("can't calculate keygrip\n"); - return NULL; - } - if (DBG_X509) - log_printhex ("keygrip=", array, 20); - - return array; -} - -/* Return an allocated buffer with the keygrip of CERT in from of an - hexstring. NULL is returned in case of error */ -char * -gpgsm_get_keygrip_hexstring (ksba_cert_t cert) -{ - unsigned char grip[20]; - char *buf, *p; - int i; - - gpgsm_get_keygrip (cert, grip); - buf = p = xmalloc (20*2+1); - for (i=0; i < 20; i++, p += 2 ) - sprintf (p, "%02X", grip[i]); - return buf; -} - - -/* Return the PK algorithm used by CERT as well as the length in bits - of the public key at NBITS. */ -int -gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits) -{ - gcry_sexp_t s_pkey; - int rc; - ksba_sexp_t p; - size_t n; - gcry_sexp_t l1, l2; - const char *name; - char namebuf[128]; - - if (nbits) - *nbits = 0; - - p = ksba_cert_get_public_key (cert); - if (!p) - return 0; - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - xfree (p); - return 0; - } - rc = gcry_sexp_sscan (&s_pkey, NULL, p, n); - xfree (p); - if (rc) - return 0; - - if (nbits) - *nbits = gcry_pk_get_nbits (s_pkey); - - /* Breaking the algorithm out of the S-exp is a bit of a challenge ... */ - l1 = gcry_sexp_find_token (s_pkey, "public-key", 0); - if (!l1) - { - gcry_sexp_release (s_pkey); - return 0; - } - l2 = gcry_sexp_cadr (l1); - gcry_sexp_release (l1); - l1 = l2; - name = gcry_sexp_nth_data (l1, 0, &n); - if (name) - { - if (n > sizeof namebuf -1) - n = sizeof namebuf -1; - memcpy (namebuf, name, n); - namebuf[n] = 0; - } - else - *namebuf = 0; - gcry_sexp_release (l1); - gcry_sexp_release (s_pkey); - return gcry_pk_map_name (namebuf); -} - - - - -/* For certain purposes we need a certificate id which has an upper - limit of the size. We use the hash of the issuer name and the - serial number for this. In most cases the serial number is not - that large and the resulting string can be passed on an assuan - command line. Everything is hexencoded with the serialnumber - delimited from the hash by a dot. - - The caller must free the string. -*/ -char * -gpgsm_get_certid (ksba_cert_t cert) -{ - ksba_sexp_t serial; - unsigned char *p; - char *endp; - unsigned char hash[20]; - unsigned long n; - char *certid; - int i; - - p = ksba_cert_get_issuer (cert, 0); - if (!p) - return NULL; /* Ooops: No issuer */ - gcry_md_hash_buffer (GCRY_MD_SHA1, hash, p, strlen (p)); - xfree (p); - - serial = ksba_cert_get_serial (cert); - if (!serial) - return NULL; /* oops: no serial number */ - p = serial; - if (*p != '(') - { - log_error ("Ooops: invalid serial number\n"); - xfree (serial); - return NULL; - } - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p != ':') - { - log_error ("Ooops: invalid serial number (no colon)\n"); - xfree (serial); - return NULL; - } - p++; - - certid = xtrymalloc ( 40 + 1 + n*2 + 1); - if (!certid) - { - xfree (serial); - return NULL; /* out of core */ - } - - for (i=0, endp = certid; i < 20; i++, endp += 2 ) - sprintf (endp, "%02X", hash[i]); - *endp++ = '.'; - for (i=0; i < n; i++, endp += 2) - sprintf (endp, "%02X", p[i]); - *endp = 0; - - xfree (serial); - return certid; -} - - - - - - diff --git a/sm/gpgsm.c b/sm/gpgsm.c deleted file mode 100644 index bf053b7a5..000000000 --- a/sm/gpgsm.c +++ /dev/null @@ -1,1700 +0,0 @@ -/* gpgsm.c - GnuPG for S/MIME - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#include <fcntl.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <assuan.h> /* malloc hooks */ - -#include "../kbx/keybox.h" /* malloc hooks */ -#include "i18n.h" -#include "keydb.h" -#include "sysutils.h" - -enum cmd_and_opt_values { - aNull = 0, - oArmor = 'a', - aDetachedSign = 'b', - aSym = 'c', - aDecrypt = 'd', - aEncr = 'e', - oInteractive = 'i', - aListKeys = 'k', - aListSecretKeys = 'K', - oDryRun = 'n', - oOutput = 'o', - oQuiet = 'q', - oRecipient = 'r', - aSign = 's', - oTextmodeShort= 't', - oUser = 'u', - oVerbose = 'v', - oCompress = 'z', - oNotation = 'N', - oBatch = 500, - aClearsign, - aStore, - aKeygen, - aSignEncr, - aSignKey, - aLSignKey, - aListPackets, - aEditKey, - aDeleteKey, - aImport, - aVerify, - aVerifyFiles, - aListExternalKeys, - aListSigs, - aSendKeys, - aRecvKeys, - aExport, - aExportSecretKeyP12, - aCheckKeys, /* nyi */ - aServer, - aLearnCard, - aCallDirmngr, - aCallProtectTool, - aPasswd, - aGPGConfList, - aDumpKeys, - aDumpSecretKeys, - aDumpExternalKeys, - aKeydbClearSomeCertFlags, - - oOptions, - oDebug, - oDebugLevel, - oDebugAll, - oDebugWait, - oDebugAllowCoreDump, - oDebugNoChainValidation, - oDebugIgnoreExpiration, - oLogFile, - - oEnableSpecialFilenames, - - oAgentProgram, - oDisplay, - oTTYname, - oTTYtype, - oLCctype, - oLCmessages, - - oDirmngrProgram, - oProtectToolProgram, - oFakedSystemTime, - - - oAssumeArmor, - oAssumeBase64, - oAssumeBinary, - - oBase64, - oNoArmor, - - oDisableCRLChecks, - oEnableCRLChecks, - oForceCRLRefresh, - - oDisableOCSP, - oEnableOCSP, - - oIncludeCerts, - oPolicyFile, - oDisablePolicyChecks, - oEnablePolicyChecks, - oAutoIssuerKeyRetrieve, - - - oTextmode, - oFingerprint, - oWithFingerprint, - oWithMD5Fingerprint, - oAnswerYes, - oAnswerNo, - oKeyring, - oSecretKeyring, - oDefaultKey, - oDefRecipient, - oDefRecipientSelf, - oNoDefRecipient, - oStatusFD, - oNoComment, - oNoVersion, - oEmitVersion, - oCompletesNeeded, - oMarginalsNeeded, - oMaxCertDepth, - oLoadExtension, - oRFC1991, - oOpenPGP, - oCipherAlgo, - oDigestAlgo, - oCompressAlgo, - oCommandFD, - oNoVerbose, - oTrustDBName, - oNoSecmemWarn, - oNoDefKeyring, - oNoGreeting, - oNoTTY, - oNoOptions, - oNoBatch, - oHomedir, - oWithColons, - oWithKeyData, - oWithValidation, - oSkipVerify, - oCompressKeys, - oCompressSigs, - oAlwaysTrust, - oRunAsShmCP, - oSetFilename, - oSetPolicyURL, - oUseEmbeddedFilename, - oComment, - oDefaultComment, - oThrowKeyid, - oForceV3Sigs, - oForceMDC, - oS2KMode, - oS2KDigest, - oS2KCipher, - oCharset, - oNotDashEscaped, - oEscapeFrom, - oLockOnce, - oLockMultiple, - oLockNever, - oKeyServer, - oEncryptTo, - oNoEncryptTo, - oLoggerFD, - oUtf8Strings, - oNoUtf8Strings, - oDisableCipherAlgo, - oDisablePubkeyAlgo, - oAllowNonSelfsignedUID, - oAllowFreeformUID, - oNoLiteral, - oSetFilesize, - oHonorHttpProxy, - oFastListMode, - oListOnly, - oIgnoreTimeConflict, - oNoRandomSeedFile, - oNoAutoKeyRetrieve, - oUseAgent, - oMergeOnly, - oTryAllSecrets, - oTrustedKey, - oEmuMDEncodeBug, - aDummy - }; - - -static ARGPARSE_OPTS opts[] = { - - { 300, NULL, 0, N_("@Commands:\n ") }, - - { aSign, "sign", 256, N_("|[FILE]|make a signature")}, - { aClearsign, "clearsign", 256, N_("|[FILE]|make a clear text signature") }, - { aDetachedSign, "detach-sign", 256, N_("make a detached signature")}, - { aEncr, "encrypt", 256, N_("encrypt data")}, - { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")}, - { aDecrypt, "decrypt", 256, N_("decrypt data (default)")}, - { aVerify, "verify" , 256, N_("verify a signature")}, - { aVerifyFiles, "verify-files" , 256, "@" }, - { aListKeys, "list-keys", 256, N_("list keys")}, - { aListExternalKeys, "list-external-keys", 256, N_("list external keys")}, - { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")}, - { aListSigs, "list-sigs", 256, N_("list certificate chain")}, - { aListSigs, "check-sigs",256, "@"}, - { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")}, - { aKeygen, "gen-key", 256, N_("generate a new key pair")}, - { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")}, - { aSendKeys, "send-keys" , 256, N_("export keys to a key server") }, - { aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") }, - { aImport, "import", 256 , N_("import certificates")}, - { aExport, "export", 256 , N_("export certificates")}, - { aLearnCard, "learn-card", 256 ,N_("register a smartcard")}, - { aServer, "server", 256, N_("run in server mode")}, - { aCallDirmngr, "call-dirmngr", 256, N_("pass a command to the dirmngr")}, - { aCallProtectTool, "call-protect-tool", 256, - N_("invoke gpg-protect-tool")}, - { aPasswd, "passwd", 256, N_("change a passphrase")}, - { aGPGConfList, "gpgconf-list", 256, "@" }, - - { aDumpKeys, "dump-keys", 256, "@"}, - { aDumpExternalKeys, "dump-external-keys", 256, "@"}, - { aDumpSecretKeys, "dump-secret-keys", 256, "@"}, - { aKeydbClearSomeCertFlags, "keydb-clear-some-cert-flags", 256, "@"}, - - { 301, NULL, 0, N_("@\nOptions:\n ") }, - - { oArmor, "armor", 0, N_("create ascii armored output")}, - { oArmor, "armour", 0, "@" }, - { oBase64, "base64", 0, N_("create base-64 encoded output")}, - - { oAssumeArmor, "assume-armor", 0, N_("assume input is in PEM format")}, - { oAssumeBase64, "assume-base64", 0, - N_("assume input is in base-64 format")}, - { oAssumeBinary, "assume-binary", 0, - N_("assume input is in binary format")}, - - { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")}, - - - { oDisableCRLChecks, "disable-crl-checks", 0, N_("never consult a CRL")}, - { oEnableCRLChecks, "enable-crl-checks", 0, "@"}, - { oForceCRLRefresh, "force-crl-refresh", 0, "@"}, - - { oDisableOCSP, "disable-ocsp", 0, "@" }, - { oEnableOCSP, "enable-ocsp", 0, N_("check validity using OCSP")}, - - { oIncludeCerts, "include-certs", 1, - N_("|N|number of certificates to include") }, - - { oPolicyFile, "policy-file", 2, - N_("|FILE|take policy information from FILE") }, - - { oDisablePolicyChecks, "disable-policy-checks", 0, - N_("do not check certificate policies")}, - { oEnablePolicyChecks, "enable-policy-checks", 0, "@"}, - - { oAutoIssuerKeyRetrieve, "auto-issuer-key-retrieve", 0, - N_("fetch missing issuer certificates")}, - -#if 0 - { oDefRecipient, "default-recipient" ,2, - N_("|NAME|use NAME as default recipient")}, - { oDefRecipientSelf, "default-recipient-self" ,0, - N_("use the default key as default recipient")}, - { oNoDefRecipient, "no-default-recipient", 0, "@" }, -#endif - { oEncryptTo, "encrypt-to", 2, "@" }, - { oNoEncryptTo, "no-encrypt-to", 0, "@" }, - - { oUser, "local-user",2, N_("use this user-id to sign or decrypt")}, - -#if 0 - { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") }, - { oTextmodeShort, NULL, 0, "@"}, - { oTextmode, "textmode", 0, N_("use canonical text mode")}, -#endif - - { oOutput, "output", 2, N_("use as output file")}, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oNoTTY, "no-tty", 0, N_("don't use the terminal at all") }, - { oLogFile, "log-file" ,2, N_("use a log file for the server")}, -#if 0 - { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") }, - { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") }, -#endif - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - /*{ oInteractive, "interactive", 0, N_("prompt before overwriting") }, */ - /*{ oUseAgent, "use-agent",0, N_("use the gpg-agent")},*/ - { oBatch, "batch", 0, N_("batch mode: never ask")}, - { oAnswerYes, "yes", 0, N_("assume yes on most questions")}, - { oAnswerNo, "no", 0, N_("assume no on most questions")}, - - { oKeyring, "keyring" ,2, N_("add this keyring to the list of keyrings")}, - { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")}, - { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")}, - { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")}, - { oCharset, "charset" , 2, N_("|NAME|set terminal charset to NAME") }, - { oOptions, "options" , 2, N_("read options from file")}, - - { oDebug, "debug" ,4|16, "@"}, - { oDebugLevel, "debug-level" ,2, "@"}, - { oDebugAll, "debug-all" ,0, "@"}, - { oDebugWait, "debug-wait" ,1, "@"}, - { oDebugAllowCoreDump, "debug-allow-core-dump", 0, "@" }, - { oDebugNoChainValidation, "debug-no-chain-validation", 0, "@"}, - { oDebugIgnoreExpiration, "debug-ignore-expiration", 0, "@"}, - { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") }, - { aDummy, "no-comment", 0, "@"}, - { aDummy, "completes-needed", 1, "@"}, - { aDummy, "marginals-needed", 1, "@"}, - { oMaxCertDepth, "max-cert-depth", 1, "@" }, - { aDummy, "trusted-key", 2, "@"}, - { oLoadExtension, "load-extension" ,2, - N_("|FILE|load extension module FILE")}, - { aDummy, "rfc1991", 0, "@"}, - { aDummy, "openpgp", 0, "@"}, - { aDummy, "s2k-mode", 1, "@"}, - { aDummy, "s2k-digest-algo",2, "@"}, - { aDummy, "s2k-cipher-algo",2, "@"}, - { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")}, - { oDigestAlgo, "digest-algo", 2 , - N_("|NAME|use message digest algorithm NAME")}, -#if 0 - { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")}, -#endif - { aDummy, "throw-keyid", 0, "@"}, - { aDummy, "notation-data", 2, "@"}, - { aExportSecretKeyP12, "export-secret-key-p12", 256, "@"}, - - - { 302, NULL, 0, N_( - "@\n(See the man page for a complete listing of all commands and options)\n" - )}, - - { 303, NULL, 0, N_("@\nExamples:\n\n" - " -se -r Bob [file] sign and encrypt for user Bob\n" - " --clearsign [file] make a clear text signature\n" - " --detach-sign [file] make a detached signature\n" - " --list-keys [names] show keys\n" - " --fingerprint [names] show fingerprints\n" ) }, - - /* hidden options */ - { oNoVerbose, "no-verbose", 0, "@"}, - - { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" }, - - - { oTrustDBName, "trustdb-name", 2, "@" }, - { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, - { oNoArmor, "no-armor", 0, "@"}, - { oNoArmor, "no-armour", 0, "@"}, - { oNoDefKeyring, "no-default-keyring", 0, "@" }, - { oNoGreeting, "no-greeting", 0, "@" }, - { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */ - { oHomedir, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */ - { oAgentProgram, "agent-program", 2 , "@" }, - { oDisplay, "display", 2, "@" }, - { oTTYname, "ttyname", 2, "@" }, - { oTTYtype, "ttytype", 2, "@" }, - { oLCctype, "lc-ctype", 2, "@" }, - { oLCmessages, "lc-messages", 2, "@" }, - { oDirmngrProgram, "dirmngr-program", 2 , "@" }, - { oProtectToolProgram, "protect-tool-program", 2 , "@" }, - { oFakedSystemTime, "faked-system-time", 4, "@" }, /* (epoch time) */ - - - { oNoBatch, "no-batch", 0, "@" }, - { oWithColons, "with-colons", 0, "@"}, - { oWithKeyData,"with-key-data", 0, "@"}, - { oWithValidation, "with-validation", 0, "@"}, - { oWithMD5Fingerprint, "with-md5-fingerprint", 0, "@"}, - { aListKeys, "list-key", 0, "@" }, /* alias */ - { aListSigs, "list-sig", 0, "@" }, /* alias */ - { aListSigs, "check-sig",0, "@" }, /* alias */ - { oSkipVerify, "skip-verify",0, "@" }, - { oCompressKeys, "compress-keys",0, "@"}, - { oCompressSigs, "compress-sigs",0, "@"}, - { oAlwaysTrust, "always-trust", 0, "@"}, - { oNoVersion, "no-version", 0, "@"}, - { oLockOnce, "lock-once", 0, "@" }, - { oLockMultiple, "lock-multiple", 0, "@" }, - { oLockNever, "lock-never", 0, "@" }, - { oLoggerFD, "logger-fd",1, "@" }, - { oWithFingerprint, "with-fingerprint", 0, "@" }, - { oDisableCipherAlgo, "disable-cipher-algo", 2, "@" }, - { oDisablePubkeyAlgo, "disable-pubkey-algo", 2, "@" }, - { oHonorHttpProxy,"honor-http-proxy", 0, "@" }, - { oListOnly, "list-only", 0, "@"}, - { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" }, - { oNoRandomSeedFile, "no-random-seed-file", 0, "@" }, -{0} }; - - - -int gpgsm_errors_seen = 0; - -/* It is possible that we are currentlu running under setuid permissions */ -static int maybe_setuid = 1; - -/* Option --enable-special-filenames */ -static int allow_special_filenames; - - -static char *build_list (const char *text, - const char *(*mapf)(int), int (*chkf)(int)); -static void set_cmd (enum cmd_and_opt_values *ret_cmd, - enum cmd_and_opt_values new_cmd ); - -static void emergency_cleanup (void); -static int check_special_filename (const char *fname); -static int open_read (const char *filename); -static FILE *open_fwrite (const char *filename); -static void run_protect_tool (int argc, char **argv); - - -static int -our_pk_test_algo (int algo) -{ - return 1; -} - -static int -our_cipher_test_algo (int algo) -{ - return 1; -} - -static int -our_md_test_algo (int algo) -{ - return 1; -} - -static const char * -my_strusage( int level ) -{ - static char *digests, *pubkeys, *ciphers; - const char *p; - - switch (level) - { - case 11: p = "gpgsm (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: gpgsm [options] [files] (-h for help)"); - break; - case 41: - p = _("Syntax: gpgsm [options] [files]\n" - "sign, check, encrypt or decrypt using the S/MIME protocol\n" - "default operation depends on the input data\n"); - break; - - case 31: p = "\nHome: "; break; - case 32: p = opt.homedir; break; - case 33: p = _("\nSupported algorithms:\n"); break; - case 34: - if (!ciphers) - ciphers = build_list ("Cipher: ", gcry_cipher_algo_name, - our_cipher_test_algo ); - p = ciphers; - break; - case 35: - if (!pubkeys) - pubkeys = build_list ("Pubkey: ", gcry_pk_algo_name, - our_pk_test_algo ); - p = pubkeys; - break; - case 36: - if (!digests) - digests = build_list("Hash: ", gcry_md_algo_name, our_md_test_algo ); - p = digests; - break; - - default: p = NULL; break; - } - return p; -} - - -static char * -build_list (const char *text, const char * (*mapf)(int), int (*chkf)(int)) -{ - int i; - size_t n=strlen(text)+2; - char *list, *p; - - if (maybe_setuid) { - gcry_control (GCRYCTL_DROP_PRIVS); /* drop setuid */ - } - - for (i=1; i < 110; i++ ) - if (!chkf(i)) - n += strlen(mapf(i)) + 2; - list = xmalloc (21 + n); - *list = 0; - for (p=NULL, i=1; i < 110; i++) - { - if (!chkf(i)) - { - if( !p ) - p = stpcpy (list, text ); - else - p = stpcpy (p, ", "); - p = stpcpy (p, mapf(i) ); - } - } - if (p) - p = stpcpy(p, "\n" ); - return list; -} - - -static void -i18n_init(void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file (PACKAGE_GT); -#else -# ifdef ENABLE_NLS -# ifdef HAVE_LC_MESSAGES - setlocale (LC_TIME, ""); - setlocale (LC_MESSAGES, ""); -# else - setlocale (LC_ALL, "" ); -# endif - bindtextdomain (PACKAGE_GT, LOCALEDIR); - textdomain (PACKAGE_GT); -# endif -#endif -} - - -static void -wrong_args (const char *text) -{ - fputs (_("usage: gpgsm [options] "), stderr); - fputs (text, stderr); - putc ('\n', stderr); - gpgsm_exit (2); -} - - -/* Setup the debugging. With a LEVEL of NULL only the active debug - flags are propagated to the subsystems. With LEVEL set, a specific - set of debug flags is set; thus overriding all flags already - set. */ -static void -set_debug (const char *level) -{ - if (!level) - ; - else if (!strcmp (level, "none")) - opt.debug = 0; - else if (!strcmp (level, "basic")) - opt.debug = DBG_ASSUAN_VALUE; - else if (!strcmp (level, "advanced")) - opt.debug = DBG_ASSUAN_VALUE|DBG_X509_VALUE; - else if (!strcmp (level, "expert")) - opt.debug = (DBG_ASSUAN_VALUE|DBG_X509_VALUE - |DBG_CACHE_VALUE|DBG_CRYPTO_VALUE); - else if (!strcmp (level, "guru")) - opt.debug = ~0; - else - { - log_error (_("invalid debug-level `%s' given\n"), level); - gpgsm_exit(2); - } - - - if (opt.debug && !opt.verbose) - { - opt.verbose = 1; - gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); - } - if (opt.debug && opt.quiet) - opt.quiet = 0; - - if (opt.debug & DBG_MPI_VALUE) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2); - if (opt.debug & DBG_CRYPTO_VALUE ) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1); -} - - - -static void -set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd) -{ - enum cmd_and_opt_values cmd = *ret_cmd; - - if (!cmd || cmd == new_cmd) - cmd = new_cmd; - else if ( cmd == aSign && new_cmd == aEncr ) - cmd = aSignEncr; - else if ( cmd == aEncr && new_cmd == aSign ) - cmd = aSignEncr; - else if ( (cmd == aSign && new_cmd == aClearsign) - || (cmd == aClearsign && new_cmd == aSign) ) - cmd = aClearsign; - else - { - log_error(_("conflicting commands\n")); - gpgsm_exit(2); - } - - *ret_cmd = cmd; -} - - -/* Helper to add recipients to a list. */ -static void -do_add_recipient (ctrl_t ctrl, const char *name, - certlist_t *recplist, int is_encrypt_to) -{ - int rc = gpgsm_add_to_certlist (ctrl, name, 0, recplist, is_encrypt_to); - if (rc) - { - log_error (_("can't encrypt to `%s': %s\n"), name, gpg_strerror (rc)); - gpgsm_status2 (ctrl, STATUS_INV_RECP, - gpg_err_code (rc) == -1? "1": - gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1": - gpg_err_code (rc) == GPG_ERR_AMBIGUOUS_NAME? "2": - gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE? "3": - gpg_err_code (rc) == GPG_ERR_CERT_REVOKED? "4": - gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED? "5": - gpg_err_code (rc) == GPG_ERR_NO_CRL_KNOWN? "6": - gpg_err_code (rc) == GPG_ERR_CRL_TOO_OLD? "7": - gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH? "8": - "0", - name, NULL); - } -} - - -int -main ( int argc, char **argv) -{ - ARGPARSE_ARGS pargs; - int orig_argc; - char **orig_argv; - const char *fname; - /* char *username;*/ - int may_coredump; - STRLIST sl, remusr= NULL, locusr=NULL; - STRLIST nrings=NULL; - int detached_sig = 0; - FILE *configfp = NULL; - char *configname = NULL; - unsigned configlineno; - int parse_debug = 0; - int no_more_options = 0; - int default_config =1; - int default_keyring = 1; - char *logfile = NULL; - int greeting = 0; - int nogreeting = 0; - int debug_wait = 0; - const char *debug_level = NULL; - int use_random_seed = 1; - int with_fpr = 0; - char *def_digest_string = NULL; - enum cmd_and_opt_values cmd = 0; - struct server_control_s ctrl; - CERTLIST recplist = NULL; - CERTLIST signerlist = NULL; - int do_not_setup_keys = 0; - - /* trap_unaligned ();*/ - set_strusage (my_strusage); - gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - /* We don't need any locking in libgcrypt unless we use any kind of - threading. */ - gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING); - - /* Please note that we may running SUID(ROOT), so be very CAREFUL - when adding any stuff between here and the call to secmem_init() - somewhere after the option parsing */ - log_set_prefix ("gpgsm", 1); - - /* Try to auto set the character set. */ - set_native_charset (NULL); - - /* Check that the libraries are suitable. Do it here because the - option parse may need services of the library */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal( _("libgcrypt is too old (need %s, have %s)\n"), - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - if (!ksba_check_version (NEED_KSBA_VERSION) ) - { - log_fatal( _("libksba is too old (need %s, have %s)\n"), - NEED_KSBA_VERSION, ksba_check_version (NULL) ); - } - - gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); - - may_coredump = disable_core_dumps (); - - gnupg_init_signals (0, emergency_cleanup); - - create_dotlock (NULL); /* register locking cleanup */ - i18n_init(); - - opt.def_cipher_algoid = "1.2.840.113549.3.7"; /*des-EDE3-CBC*/ -#ifdef __MINGW32__ - opt.homedir = read_w32_registry_string ( NULL, - "Software\\GNU\\GnuPG", "HomeDir" ); -#else - opt.homedir = getenv ("GNUPGHOME"); -#endif - if (!opt.homedir || !*opt.homedir ) - opt.homedir = GNUPG_DEFAULT_HOMEDIR; - - /* first check whether we have a config file on the commandline */ - orig_argc = argc; - orig_argv = argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */ - while (arg_parse( &pargs, opts)) - { - if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll) - parse_debug++; - else if (pargs.r_opt == oOptions) - { /* yes there is one, so we do not try the default one but - read the config file when it is encountered at the - commandline */ - default_config = 0; - } - else if (pargs.r_opt == oNoOptions) - default_config = 0; /* --no-options */ - else if (pargs.r_opt == oHomedir) - opt.homedir = pargs.r.ret_str; - else if (pargs.r_opt == aCallProtectTool) - break; /* This break makes sure that --version and --help are - passed to the protect-tool. */ - } - - - /* initialize the secure memory. */ - gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); - maybe_setuid = 0; - - /* - Now we are now working under our real uid - */ - - ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free ); - - assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - assuan_set_assuan_log_stream (log_get_stream ()); - assuan_set_assuan_log_prefix (log_get_prefix (NULL)); - - keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - - /* Setup a default control structure for command line mode */ - memset (&ctrl, 0, sizeof ctrl); - gpgsm_init_default_ctrl (&ctrl); - ctrl.no_server = 1; - ctrl.status_fd = -1; /* not status output */ - ctrl.autodetect_encoding = 1; - - /* set the default option file */ - if (default_config ) - configname = make_filename (opt.homedir, "gpgsm.conf", NULL); - /* cet the default policy file */ - opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL); - - argc = orig_argc; - argv = orig_argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags = 1; /* do not remove the args */ - - next_pass: - if (configname) { - configlineno = 0; - configfp = fopen (configname, "r"); - if (!configfp) - { - if (default_config) - { - if (parse_debug) - log_info (_("NOTE: no default option file `%s'\n"), configname); - } - else - { - log_error (_("option file `%s': %s\n"), configname, strerror(errno)); - gpgsm_exit(2); - } - xfree(configname); - configname = NULL; - } - if (parse_debug && configname) - log_info (_("reading options from `%s'\n"), configname); - default_config = 0; - } - - while (!no_more_options - && optfile_parse (configfp, configname, &configlineno, &pargs, opts)) - { - switch (pargs.r_opt) - { - case aGPGConfList: - set_cmd (&cmd, pargs.r_opt); - do_not_setup_keys = 1; - nogreeting = 1; - break; - - case aServer: - opt.batch = 1; - set_cmd (&cmd, aServer); - break; - - case aCallDirmngr: - opt.batch = 1; - set_cmd (&cmd, aCallDirmngr); - do_not_setup_keys = 1; - break; - - case aCallProtectTool: - opt.batch = 1; - set_cmd (&cmd, aCallProtectTool); - no_more_options = 1; /* Stop parsing. */ - do_not_setup_keys = 1; - break; - - case aDeleteKey: - set_cmd (&cmd, aDeleteKey); - /*greeting=1;*/ - do_not_setup_keys = 1; - break; - - case aDetachedSign: - detached_sig = 1; - set_cmd (&cmd, aSign ); - break; - - case aKeygen: - set_cmd (&cmd, aKeygen); - greeting=1; - do_not_setup_keys = 1; - break; - - case aCheckKeys: - case aImport: - case aSendKeys: - case aRecvKeys: - case aExport: - case aExportSecretKeyP12: - case aDumpKeys: - case aDumpExternalKeys: - case aDumpSecretKeys: - case aListKeys: - case aListExternalKeys: - case aListSecretKeys: - case aListSigs: - case aLearnCard: - case aPasswd: - case aKeydbClearSomeCertFlags: - do_not_setup_keys = 1; - set_cmd (&cmd, pargs.r_opt); - break; - - case aSym: - case aDecrypt: - case aEncr: - case aSign: - case aClearsign: - case aVerify: - set_cmd (&cmd, pargs.r_opt); - break; - - /* output encoding selection */ - case oArmor: - ctrl.create_pem = 1; - break; - case oBase64: - ctrl.create_pem = 0; - ctrl.create_base64 = 1; - break; - case oNoArmor: - ctrl.create_pem = 0; - ctrl.create_base64 = 0; - break; - - /* Input encoding selection */ - case oAssumeArmor: - ctrl.autodetect_encoding = 0; - ctrl.is_pem = 1; - ctrl.is_base64 = 0; - break; - case oAssumeBase64: - ctrl.autodetect_encoding = 0; - ctrl.is_pem = 0; - ctrl.is_base64 = 1; - break; - case oAssumeBinary: - ctrl.autodetect_encoding = 0; - ctrl.is_pem = 0; - ctrl.is_base64 = 0; - break; - - case oDisableCRLChecks: - opt.no_crl_check = 1; - break; - case oEnableCRLChecks: - opt.no_crl_check = 0; - break; - case oForceCRLRefresh: - opt.force_crl_refresh = 1; - break; - - case oDisableOCSP: - ctrl.use_ocsp = opt.enable_ocsp = 0; - break; - case oEnableOCSP: - ctrl.use_ocsp = opt.enable_ocsp = 1; - break; - - case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break; - - case oPolicyFile: - xfree (opt.policy_file); - if (*pargs.r.ret_str) - opt.policy_file = xstrdup (pargs.r.ret_str); - else - opt.policy_file = NULL; - break; - - case oDisablePolicyChecks: - opt.no_policy_check = 1; - break; - case oEnablePolicyChecks: - opt.no_policy_check = 0; - break; - - case oAutoIssuerKeyRetrieve: - opt.auto_issuer_key_retrieve = 1; - break; - - case oOutput: opt.outfile = pargs.r.ret_str; break; - - - case oQuiet: opt.quiet = 1; break; - case oNoTTY: /* fixme:tty_no_terminal(1);*/ break; - case oDryRun: opt.dry_run = 1; break; - - case oVerbose: - opt.verbose++; - gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); - break; - case oNoVerbose: - opt.verbose = 0; - gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); - break; - - case oLogFile: logfile = pargs.r.ret_str; break; - - case oBatch: - opt.batch = 1; - greeting = 0; - break; - case oNoBatch: opt.batch = 0; break; - - case oAnswerYes: opt.answer_yes = 1; break; - case oAnswerNo: opt.answer_no = 1; break; - - case oKeyring: append_to_strlist (&nrings, pargs.r.ret_str); break; - - case oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oDebugLevel: debug_level = pargs.r.ret_str; break; - case oDebugWait: debug_wait = pargs.r.ret_int; break; - case oDebugAllowCoreDump: - may_coredump = enable_core_dumps (); - break; - case oDebugNoChainValidation: opt.no_chain_validation = 1; break; - case oDebugIgnoreExpiration: opt.ignore_expiration = 1; break; - - case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break; - case oLoggerFD: log_set_fd (pargs.r.ret_int ); break; - case oWithMD5Fingerprint: - opt.with_md5_fingerprint=1; /*fall thru*/ - case oWithFingerprint: - with_fpr=1; /*fall thru*/ - case oFingerprint: - opt.fingerprint++; - break; - - case oOptions: - /* config files may not be nested (silently ignore them) */ - if (!configfp) - { - xfree(configname); - configname = xstrdup (pargs.r.ret_str); - goto next_pass; - } - break; - case oNoOptions: break; /* no-options */ - case oHomedir: opt.homedir = pargs.r.ret_str; break; - case oAgentProgram: opt.agent_program = pargs.r.ret_str; break; - case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break; - case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break; - case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break; - case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break; - case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break; - case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break; - case oProtectToolProgram: - opt.protect_tool_program = pargs.r.ret_str; - break; - - case oFakedSystemTime: - gnupg_set_time ( (time_t)pargs.r.ret_ulong, 0); - break; - - case oNoDefKeyring: default_keyring = 0; break; - case oNoGreeting: nogreeting = 1; break; - - case oDefaultKey: - /* fixme:opt.def_secret_key = pargs.r.ret_str;*/ - break; - case oDefRecipient: - if (*pargs.r.ret_str) - opt.def_recipient = xstrdup (pargs.r.ret_str); - break; - case oDefRecipientSelf: - xfree (opt.def_recipient); - opt.def_recipient = NULL; - opt.def_recipient_self = 1; - break; - case oNoDefRecipient: - xfree (opt.def_recipient); - opt.def_recipient = NULL; - opt.def_recipient_self = 0; - break; - - case oWithKeyData: opt.with_key_data=1; /* fall thru */ - case oWithColons: ctrl.with_colons = 1; break; - case oWithValidation: ctrl.with_validation=1; break; - - case oSkipVerify: opt.skip_verify=1; break; - - case oNoEncryptTo: opt.no_encrypt_to = 1; break; - case oEncryptTo: /* Store the recipient in the second list */ - sl = add_to_strlist (&remusr, pargs.r.ret_str); - sl->flags = 1; - break; - - case oRecipient: /* store the recipient */ - add_to_strlist ( &remusr, pargs.r.ret_str); - break; - - case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break; - case oTextmode: /*fixme:opt.textmode=1;*/ break; - - case oUser: /* store the local users, the first one is the default */ - if (!opt.local_user) - opt.local_user = pargs.r.ret_str; - add_to_strlist (&locusr, pargs.r.ret_str); - break; - - case oNoSecmemWarn: - gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); - break; - - case oCipherAlgo: - opt.def_cipher_algoid = pargs.r.ret_str; - break; - - case oDisableCipherAlgo: - { - int algo = gcry_cipher_map_name (pargs.r.ret_str); - gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo); - } - break; - case oDisablePubkeyAlgo: - { - int algo = gcry_pk_map_name (pargs.r.ret_str); - gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,&algo, sizeof algo ); - } - break; - - case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break; - case oNoRandomSeedFile: use_random_seed = 0; break; - - case oEnableSpecialFilenames: allow_special_filenames =1; break; - - - case aDummy: - break; - default: - pargs.err = configfp? 1:2; - break; - } - } - - if (configfp) - { - fclose (configfp); - configfp = NULL; - /* Keep a copy of the config filename. */ - opt.config_filename = configname; - configname = NULL; - goto next_pass; - } - xfree (configname); - configname = NULL; - - if (!opt.config_filename) - opt.config_filename = make_filename (opt.homedir, "gpgsm.conf", NULL); - - if (log_get_errorcount(0)) - gpgsm_exit(2); - - if (nogreeting) - greeting = 0; - - if (greeting) - { - fprintf(stderr, "%s %s; %s\n", - strusage(11), strusage(13), strusage(14) ); - fprintf(stderr, "%s\n", strusage(15) ); - } -# ifdef IS_DEVELOPMENT_VERSION - if (!opt.batch) - { - log_info ("NOTE: THIS IS A DEVELOPMENT VERSION!\n"); - log_info ("It is only intended for test purposes and should NOT be\n"); - log_info ("used in a production environment or with production keys!\n"); - } -# endif - - if (may_coredump && !opt.quiet) - log_info (_("WARNING: program may create a core file!\n")); - - if (logfile && cmd == aServer) - { - log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); - } - - if (gnupg_faked_time_p ()) - { - gnupg_isotime_t tbuf; - - log_info (_("WARNING: running with faked system time: ")); - gnupg_get_isotime (tbuf); - gpgsm_dump_time (tbuf); - log_printf ("\n"); - } - -/*FIXME if (opt.batch) */ -/* tty_batchmode (1); */ - - gcry_control (GCRYCTL_RESUME_SECMEM_WARN); - - set_debug (debug_level); - - /* Although we alwasy use gpgsm_exit, we better install a regualr - exit handler so that at least the secure memory gets wiped - out. */ - if (atexit (emergency_cleanup)) - { - log_error ("atexit failed\n"); - gpgsm_exit (2); - } - - /* Must do this after dropping setuid, because the mapping functions - may try to load an module and we may have disabled an algorithm. */ - if ( !gcry_cipher_map_name (opt.def_cipher_algoid) - || !gcry_cipher_mode_from_oid (opt.def_cipher_algoid)) - log_error (_("selected cipher algorithm is invalid\n")); - - if (def_digest_string) - { - opt.def_digest_algo = gcry_md_map_name (def_digest_string); - xfree (def_digest_string); - def_digest_string = NULL; - if (our_md_test_algo(opt.def_digest_algo) ) - log_error (_("selected digest algorithm is invalid\n")); - } - - if (log_get_errorcount(0)) - gpgsm_exit(2); - - /* Set the random seed file. */ - if (use_random_seed) { - char *p = make_filename (opt.homedir, "random_seed", NULL); - gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p); - xfree(p); - } - - - if (!cmd && opt.fingerprint && !with_fpr) - set_cmd (&cmd, aListKeys); - - if (!nrings && default_keyring) /* add default keybox */ - keydb_add_resource ("pubring.kbx", 0, 0); - for (sl = nrings; sl; sl = sl->next) - keydb_add_resource (sl->d, 0, 0); - FREE_STRLIST(nrings); - - if (!do_not_setup_keys) - { - for (sl = locusr; sl ; sl = sl->next) - { - int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 1, &signerlist, 0); - if (rc) - { - log_error (_("can't sign using `%s': %s\n"), - sl->d, gpg_strerror (rc)); - gpgsm_status2 (&ctrl, STATUS_INV_RECP, - gpg_err_code (rc) == -1? "1": - gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1": - gpg_err_code (rc) == GPG_ERR_AMBIGUOUS_NAME? "2": - gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE? "3": - gpg_err_code (rc) == GPG_ERR_CERT_REVOKED? "4": - gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED? "5": - gpg_err_code (rc) == GPG_ERR_NO_CRL_KNOWN? "6": - gpg_err_code (rc) == GPG_ERR_CRL_TOO_OLD? "7": - gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH? "8": - gpg_err_code (rc) == GPG_ERR_NO_SECKEY? "9": - "0", - sl->d, NULL); - } - } - - /* Build the recipient list. We first add the regular ones and then - the encrypt-to ones because the underlying function will silenty - ignore duplicates and we can't allow to keep a duplicate which is - flagged as encrypt-to as the actually encrypt function would then - complain about no (regular) recipients. */ - for (sl = remusr; sl; sl = sl->next) - if (!(sl->flags & 1)) - do_add_recipient (&ctrl, sl->d, &recplist, 0); - if (!opt.no_encrypt_to) - { - for (sl = remusr; sl; sl = sl->next) - if ((sl->flags & 1)) - do_add_recipient (&ctrl, sl->d, &recplist, 1); - } - } - - if (log_get_errorcount(0)) - gpgsm_exit(1); /* must stop for invalid recipients */ - - fname = argc? *argv : NULL; - - switch (cmd) - { - case aGPGConfList: - { /* List options and default values in the GPG Conf format. */ - - /* The following list is taken from gnupg/tools/gpgconf-comp.c. */ - /* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING - FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */ -#define GC_OPT_FLAG_NONE 0UL - /* The RUNTIME flag for an option indicates that the option can be - changed at runtime. */ -#define GC_OPT_FLAG_RUNTIME (1UL << 3) - /* The DEFAULT flag for an option indicates that the option has a - default value. */ -#define GC_OPT_FLAG_DEFAULT (1UL << 4) - /* The DEF_DESC flag for an option indicates that the option has a - default, which is described by the value of the default field. */ -#define GC_OPT_FLAG_DEF_DESC (1UL << 5) - /* The NO_ARG_DESC flag for an option indicates that the argument has - a default, which is described by the value of the ARGDEF field. */ -#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) - - printf ("gpgconf-gpgsm.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, opt.config_filename); - - printf ("verbose:%lu:\n" - "quiet:%lu:\n" - "debug-level:%lu:\"none:\n" - "log-file:%lu:\n", - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_DEFAULT, - GC_OPT_FLAG_NONE ); - printf ("disable-crl-checks:%lu:\n", - GC_OPT_FLAG_NONE ); - printf ("enable-ocsp:%lu:\n", - GC_OPT_FLAG_NONE ); - printf ("include-certs:%lu:1:\n", - GC_OPT_FLAG_DEFAULT ); - printf ("disable-policy-checks:%lu:\n", - GC_OPT_FLAG_NONE ); - printf ("auto-issuer-key-retrieve:%lu:\n", - GC_OPT_FLAG_NONE ); - - } - break; - - case aServer: - if (debug_wait) - { - log_debug ("waiting for debugger - my pid is %u .....\n", - (unsigned int)getpid()); - sleep (debug_wait); - log_debug ("... okay\n"); - } - gpgsm_server (recplist); - break; - - case aCallDirmngr: - if (!argc) - wrong_args ("--call-dirmngr <command> {args}"); - else - if (gpgsm_dirmngr_run_command (&ctrl, *argv, argc-1, argv+1)) - gpgsm_exit (1); - break; - - case aCallProtectTool: - run_protect_tool (argc, argv); - break; - - case aEncr: /* encrypt the given file */ - if (!argc) - gpgsm_encrypt (&ctrl, recplist, 0, stdout); /* from stdin */ - else if (argc == 1) - gpgsm_encrypt (&ctrl, recplist, open_read (*argv), stdout); /* from file */ - else - wrong_args ("--encrypt [datafile]"); - break; - - case aSign: /* sign the given file */ - /* FIXME: We don't handle --output yet. We should also allow - to concatenate multiple files for signing because that is - what gpg does.*/ - if (!argc) - gpgsm_sign (&ctrl, signerlist, - 0, detached_sig, stdout); /* create from stdin */ - else if (argc == 1) - gpgsm_sign (&ctrl, signerlist, - open_read (*argv), detached_sig, stdout); /* from file */ - else - wrong_args ("--sign [datafile]"); - break; - - case aSignEncr: /* sign and encrypt the given file */ - log_error ("this command has not yet been implemented\n"); - break; - - case aClearsign: /* make a clearsig */ - log_error ("this command has not yet been implemented\n"); - break; - - case aVerify: - { - FILE *fp = NULL; - - if (argc == 2 && opt.outfile) - log_info ("option --output ignored for a detached signature\n"); - else if (opt.outfile) - fp = open_fwrite (opt.outfile); - - if (!argc) - gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */ - else if (argc == 1) - gpgsm_verify (&ctrl, open_read (*argv), -1, fp); /* std signature */ - else if (argc == 2) /* detached signature (sig, detached) */ - gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1]), NULL); - else - wrong_args ("--verify [signature [detached_data]]"); - - if (fp && fp != stdout) - fclose (fp); - } - break; - - case aVerifyFiles: - log_error (_("this command has not yet been implemented\n")); - break; - - case aDecrypt: - if (!argc) - gpgsm_decrypt (&ctrl, 0, stdout); /* from stdin */ - else if (argc == 1) - gpgsm_decrypt (&ctrl, open_read (*argv), stdout); /* from file */ - else - wrong_args ("--decrypt [filename]"); - break; - - case aDeleteKey: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_delete (&ctrl, sl); - free_strlist(sl); - break; - - case aListSigs: - ctrl.with_chain = 1; - case aListKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<6))); - free_strlist(sl); - break; - - case aDumpKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, (256 | (1<<6))); - free_strlist(sl); - break; - - case aListExternalKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, - (0 | (1<<7))); - free_strlist(sl); - break; - - case aDumpExternalKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, - (256 | (1<<7))); - free_strlist(sl); - break; - - case aListSecretKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, (2 | (1<<6))); - free_strlist(sl); - break; - - case aDumpSecretKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, (256 | 2 | (1<<6))); - free_strlist(sl); - break; - - case aKeygen: /* generate a key */ - log_error ("this function is not yet available from the commandline\n"); - break; - - case aImport: - gpgsm_import_files (&ctrl, argc, argv, open_read); - break; - - case aExport: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_export (&ctrl, sl, stdout); - free_strlist(sl); - break; - - case aExportSecretKeyP12: - if (argc == 1) - gpgsm_p12_export (&ctrl, *argv, stdout); - else - wrong_args ("--export-secret-key-p12 KEY-ID"); - break; - - case aSendKeys: - case aRecvKeys: - log_error ("this command has not yet been implemented\n"); - break; - - - case aLearnCard: - if (argc) - wrong_args ("--learn-card"); - else - { - int rc = gpgsm_agent_learn (&ctrl); - if (rc) - log_error ("error learning card: %s\n", gpg_strerror (rc)); - } - break; - - case aPasswd: - if (argc != 1) - wrong_args ("--passwd <key-Id>"); - else - { - int rc; - ksba_cert_t cert = NULL; - char *grip = NULL; - - rc = gpgsm_find_cert (*argv, &cert); - if (rc) - ; - else if (!(grip = gpgsm_get_keygrip_hexstring (cert))) - rc = gpg_error (GPG_ERR_BUG); - else - { - char *desc = gpgsm_format_keydesc (cert); - rc = gpgsm_agent_passwd (&ctrl, grip, desc); - xfree (desc); - } - if (rc) - log_error ("error changing passphrase: %s\n", gpg_strerror (rc)); - xfree (grip); - ksba_cert_release (cert); - } - break; - - case aKeydbClearSomeCertFlags: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - keydb_clear_some_cert_flags (&ctrl, sl); - free_strlist(sl); - break; - - - default: - log_error ("invalid command (there is no implicit command)\n"); - break; - } - - /* cleanup */ - gpgsm_release_certlist (recplist); - gpgsm_release_certlist (signerlist); - FREE_STRLIST(remusr); - FREE_STRLIST(locusr); - gpgsm_exit(0); - return 8; /*NEVER REACHED*/ -} - -/* Note: This function is used by signal handlers!. */ -static void -emergency_cleanup (void) -{ - gcry_control (GCRYCTL_TERM_SECMEM ); -} - - -void -gpgsm_exit (int rc) -{ - gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); - if (opt.debug & DBG_MEMSTAT_VALUE) - { - gcry_control( GCRYCTL_DUMP_MEMORY_STATS ); - gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); - } - if (opt.debug) - gcry_control (GCRYCTL_DUMP_SECMEM_STATS ); - emergency_cleanup (); - rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0; - exit (rc); -} - - -void -gpgsm_init_default_ctrl (struct server_control_s *ctrl) -{ - ctrl->include_certs = 1; /* only include the signer's cert */ - ctrl->use_ocsp = opt.enable_ocsp; -} - - - -/* Check whether the filename has the form "-&nnnn", where n is a - non-zero number. Returns this number or -1 if it is not the case. */ -static int -check_special_filename (const char *fname) -{ - if (allow_special_filenames - && fname && *fname == '-' && fname[1] == '&' ) { - int i; - - fname += 2; - for (i=0; isdigit (fname[i]); i++ ) - ; - if ( !fname[i] ) - return atoi (fname); - } - return -1; -} - - - -/* Open the FILENAME for read and return the filedescriptor. Stop - with an error message in case of problems. "-" denotes stdin and - if special filenames are allowed the given fd is opened instead. */ -static int -open_read (const char *filename) -{ - int fd; - - if (filename[0] == '-' && !filename[1]) - return 0; /* stdin */ - fd = check_special_filename (filename); - if (fd != -1) - return fd; - fd = open (filename, O_RDONLY); - if (fd == -1) - { - log_error (_("can't open `%s': %s\n"), filename, strerror (errno)); - gpgsm_exit (2); - } - return fd; -} - -/* Open FILENAME for fwrite and return the stream. Stop with an error - message in case of problems. "-" denotes stdout and if special - filenames are allowed the given fd is opened instead. Caller must - close the returned stream unless it is stdout. */ -static FILE * -open_fwrite (const char *filename) -{ - int fd; - FILE *fp; - - if (filename[0] == '-' && !filename[1]) - return stdout; - - fd = check_special_filename (filename); - if (fd != -1) - { - fp = fdopen (dup (fd), "wb"); - if (!fp) - { - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - gpgsm_exit (2); - } - return fp; - } - fp = fopen (filename, "wb"); - if (!fp) - { - log_error (_("can't open `%s': %s\n"), filename, strerror (errno)); - gpgsm_exit (2); - } - return fp; -} - - -static void -run_protect_tool (int argc, char **argv) -{ - const char *pgm; - char **av; - int i; - - if (!opt.protect_tool_program || !*opt.protect_tool_program) - pgm = GNUPG_DEFAULT_PROTECT_TOOL; - else - pgm = opt.protect_tool_program; - - av = xcalloc (argc+2, sizeof *av); - av[0] = strrchr (pgm, '/'); - if (!av[0]) - av[0] = xstrdup (pgm); - for (i=1; argc; i++, argc--, argv++) - av[i] = *argv; - av[i] = NULL; - execv (pgm, av); - log_error ("error executing `%s': %s\n", pgm, strerror (errno)); - gpgsm_exit (2); -} diff --git a/sm/gpgsm.h b/sm/gpgsm.h deleted file mode 100644 index 786a97353..000000000 --- a/sm/gpgsm.h +++ /dev/null @@ -1,311 +0,0 @@ -/* gpgsm.h - Global definitions for GpgSM - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GPGSM_H -#define GPGSM_H - -#ifdef GPG_ERR_SOURCE_DEFAULT -#error GPG_ERR_SOURCE_DEFAULT already defined -#endif -#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GPGSM -#include <gpg-error.h> - -#include <ksba.h> -#include "../common/util.h" -#include "../common/errors.h" - -#define OUT_OF_CORE(a) (gpg_error (gpg_err_code_from_errno ((a)))) - -#define MAX_DIGEST_LEN 24 - -/* A large struct named "opt" to keep global flags */ -struct { - unsigned int debug; /* debug flags (DBG_foo_VALUE) */ - int verbose; /* verbosity level */ - int quiet; /* be as quiet as possible */ - int batch; /* run in batch mode, i.e w/o any user interaction */ - int answer_yes; /* assume yes on most questions */ - int answer_no; /* assume no on most questions */ - int dry_run; /* don't change any persistent data */ - - const char *homedir; /* Configuration directory name */ - const char *config_filename; /* Name of the used config file. */ - const char *agent_program; - char *display; - char *ttyname; - char *ttytype; - char *lc_ctype; - char *lc_messages; - - const char *dirmngr_program; - const char *protect_tool_program; - char *outfile; /* name of output file */ - - int with_key_data;/* include raw key in the column delimted output */ - - int fingerprint; /* list fingerprints in all key listings */ - - int with_md5_fingerprint; /* Also print an MD5 fingerprint for - standard key listings. */ - - int armor; /* force base64 armoring (see also ctrl.with_base64) */ - int no_armor; /* don't try to figure out whether data is base64 armored*/ - - const char *def_cipher_algoid; /* cipher algorithm to use if - nothing else is specified */ - - int def_digest_algo; /* Ditto for hash algorithm */ - int def_compress_algo; /* Ditto for compress algorithm */ - - char *def_recipient; /* userID of the default recipient */ - int def_recipient_self; /* The default recipient is the default key */ - - int no_encrypt_to; /* Ignore all as encrypt to marked recipients. */ - - char *local_user; /* NULL or argument to -u */ - - int always_trust; /* Trust the given keys even if there is no - valid certification chain */ - int skip_verify; /* do not check signatures on data */ - - int lock_once; /* Keep lock once they are set */ - - int ignore_time_conflict; /* Ignore certain time conflicts */ - - int no_crl_check; /* Don't do a CRL check */ - int force_crl_refresh; /* Force refreshing the CRL. */ - int enable_ocsp; /* Default to use OCSP checks. */ - - char *policy_file; /* full pathname of policy file */ - int no_policy_check; /* ignore certificate policies */ - int no_chain_validation; /* Bypass all cert chain validity tests */ - int ignore_expiration; /* Ignore the notAfter validity checks. */ - - int auto_issuer_key_retrieve; /* try to retrieve a missing issuer key. */ -} opt; - - -#define DBG_X509_VALUE 1 /* debug x.509 data reading/writing */ -#define DBG_MPI_VALUE 2 /* debug mpi details */ -#define DBG_CRYPTO_VALUE 4 /* debug low level crypto */ -#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */ -#define DBG_CACHE_VALUE 64 /* debug the caching */ -#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ -#define DBG_HASHING_VALUE 512 /* debug hashing operations */ -#define DBG_ASSUAN_VALUE 1024 /* debug assuan communication */ - -#define DBG_X509 (opt.debug & DBG_X509_VALUE) -#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE) -#define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE) -#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE) -#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) -#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE) - -struct server_local_s; - -/* Note that the default values for this are set by - gpgsm_init_default_ctrl() */ -struct server_control_s { - int no_server; /* We are not running under server control */ - int status_fd; /* Only for non-server mode */ - struct server_local_s *server_local; - int with_colons; /* Use column delimited output format */ - int with_chain; /* Include the certifying certs in a listing */ - int with_validation;/* Validate each key while listing. */ - - int autodetect_encoding; /* Try to detect the input encoding */ - int is_pem; /* Is in PEM format */ - int is_base64; /* is in plain base-64 format */ - - int create_base64; /* Create base64 encoded output */ - int create_pem; /* create PEM output */ - const char *pem_name; /* PEM name to use */ - - int include_certs; /* -1 to send all certificates in the chain - along with a signature or the number of - certificates up the chain (0 = none, 1 = only - signer) */ - int use_ocsp; /* Set to true if OCSP should be used. */ -}; -typedef struct server_control_s *CTRL; -typedef struct server_control_s *ctrl_t; - -/* data structure used in base64.c */ -typedef struct base64_context_s *Base64Context; - - -struct certlist_s { - struct certlist_s *next; - ksba_cert_t cert; - int is_encrypt_to; /* True if the certificate has been set through - the --encrypto-to option. */ -}; -typedef struct certlist_s *CERTLIST; -typedef struct certlist_s *certlist_t; - -/*-- gpgsm.c --*/ -void gpgsm_exit (int rc); -void gpgsm_init_default_ctrl (struct server_control_s *ctrl); - -/*-- server.c --*/ -void gpgsm_server (certlist_t default_recplist); -void gpgsm_status (ctrl_t ctrl, int no, const char *text); -void gpgsm_status2 (ctrl_t ctrl, int no, ...); -void gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, - gpg_err_code_t ec); - -/*-- fingerprint --*/ -char *gpgsm_get_fingerprint (ksba_cert_t cert, int algo, - char *array, int *r_len); -char *gpgsm_get_fingerprint_string (ksba_cert_t cert, int algo); -char *gpgsm_get_fingerprint_hexstring (ksba_cert_t cert, int algo); -unsigned long gpgsm_get_short_fingerprint (ksba_cert_t cert); -char *gpgsm_get_keygrip (ksba_cert_t cert, char *array); -char *gpgsm_get_keygrip_hexstring (ksba_cert_t cert); -int gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits); -char *gpgsm_get_certid (ksba_cert_t cert); - - -/*-- base64.c --*/ -int gpgsm_create_reader (Base64Context *ctx, - ctrl_t ctrl, FILE *fp, int allow_multi_pem, - ksba_reader_t *r_reader); -int gpgsm_reader_eof_seen (Base64Context ctx); -void gpgsm_destroy_reader (Base64Context ctx); -int gpgsm_create_writer (Base64Context *ctx, - ctrl_t ctrl, FILE *fp, ksba_writer_t *r_writer); -int gpgsm_finish_writer (Base64Context ctx); -void gpgsm_destroy_writer (Base64Context ctx); - - -/*-- certdump.c --*/ -void gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p); -void gpgsm_print_time (FILE *fp, ksba_isotime_t t); -void gpgsm_print_name (FILE *fp, const char *string); - -void gpgsm_dump_cert (const char *text, ksba_cert_t cert); -void gpgsm_dump_serial (ksba_const_sexp_t p); -void gpgsm_dump_time (ksba_isotime_t t); -void gpgsm_dump_string (const char *string); - -char *gpgsm_format_serial (ksba_const_sexp_t p); -char *gpgsm_format_name (const char *name); - -char *gpgsm_format_keydesc (ksba_cert_t cert); - - -/*-- certcheck.c --*/ -int gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert); -int gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, - gcry_md_hd_t md, int hash_algo); -/* fixme: move create functions to another file */ -int gpgsm_create_cms_signature (ctrl_t ctrl, - ksba_cert_t cert, gcry_md_hd_t md, int mdalgo, - char **r_sigval); - - -/*-- certchain.c --*/ -int gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next); -int gpgsm_is_root_cert (ksba_cert_t cert); -int gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, - ksba_isotime_t r_exptime, - int listmode, FILE *listfp, - unsigned int flags); -int gpgsm_basic_cert_check (ksba_cert_t cert); - -/*-- certlist.c --*/ -int gpgsm_cert_use_sign_p (ksba_cert_t cert); -int gpgsm_cert_use_encrypt_p (ksba_cert_t cert); -int gpgsm_cert_use_verify_p (ksba_cert_t cert); -int gpgsm_cert_use_decrypt_p (ksba_cert_t cert); -int gpgsm_cert_use_cert_p (ksba_cert_t cert); -int gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert, - certlist_t *listaddr, int is_encrypt_to); -int gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret, - certlist_t *listaddr, int is_encrypt_to); -void gpgsm_release_certlist (certlist_t list); -int gpgsm_find_cert (const char *name, ksba_cert_t *r_cert); - -/*-- keylist.c --*/ -gpg_error_t gpgsm_list_keys (ctrl_t ctrl, STRLIST names, - FILE *fp, unsigned int mode); - -/*-- import.c --*/ -int gpgsm_import (ctrl_t ctrl, int in_fd); -int gpgsm_import_files (ctrl_t ctrl, int nfiles, char **files, - int (*of)(const char *fname)); - -/*-- export.c --*/ -void gpgsm_export (ctrl_t ctrl, STRLIST names, FILE *fp); -void gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp); - -/*-- delete.c --*/ -int gpgsm_delete (ctrl_t ctrl, STRLIST names); - -/*-- verify.c --*/ -int gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp); - -/*-- sign.c --*/ -int gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert); -int gpgsm_sign (ctrl_t ctrl, CERTLIST signerlist, - int data_fd, int detached, FILE *out_fp); - -/*-- encrypt.c --*/ -int gpgsm_encrypt (ctrl_t ctrl, CERTLIST recplist, int in_fd, FILE *out_fp); - -/*-- decrypt.c --*/ -int gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp); - -/*-- certreqgen.c --*/ -int gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *out_fp); - -/*-- call-agent.c --*/ -int gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc, - unsigned char *digest, - size_t digestlen, - int digestalgo, - char **r_buf, size_t *r_buflen); -int gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, - ksba_const_sexp_t ciphertext, - char **r_buf, size_t *r_buflen); -int gpgsm_agent_genkey (ctrl_t ctrl, - ksba_const_sexp_t keyparms, ksba_sexp_t *r_pubkey); -int gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert); -int gpgsm_agent_havekey (ctrl_t ctrl, const char *hexkeygrip); -int gpgsm_agent_marktrusted (ctrl_t ctrl, ksba_cert_t cert); -int gpgsm_agent_learn (ctrl_t ctrl); -int gpgsm_agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc); - -/*-- call-dirmngr.c --*/ -int gpgsm_dirmngr_isvalid (ctrl_t ctrl, - ksba_cert_t cert, ksba_cert_t issuer_cert, - int use_ocsp); -int gpgsm_dirmngr_lookup (ctrl_t ctrl, STRLIST names, - void (*cb)(void*, ksba_cert_t), void *cb_value); -int gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command, - int argc, char **argv); - - -/*-- misc.c --*/ -void setup_pinentry_env (void); - - - -#endif /*GPGSM_H*/ diff --git a/sm/import.c b/sm/import.c deleted file mode 100644 index c5581eb64..000000000 --- a/sm/import.c +++ /dev/null @@ -1,725 +0,0 @@ -/* import.c - Import certificates - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#include <signal.h> -#include <fcntl.h> -#include <sys/wait.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - - -struct stats_s { - unsigned long count; - unsigned long imported; - unsigned long unchanged; - unsigned long not_imported; - unsigned long secret_read; - unsigned long secret_imported; - unsigned long secret_dups; - }; - - -static gpg_error_t parse_p12 (ksba_reader_t reader, FILE **retfp, - struct stats_s *stats); - - - -static void -print_imported_status (CTRL ctrl, ksba_cert_t cert, int new_cert) -{ - char *fpr; - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - if (new_cert) - gpgsm_status2 (ctrl, STATUS_IMPORTED, fpr, "[X.509]", NULL); - - gpgsm_status2 (ctrl, STATUS_IMPORT_OK, - new_cert? "1":"0", fpr, NULL); - - xfree (fpr); -} - - -/* Print an IMPORT_PROBLEM status. REASON is one of: - 0 := "No specific reason given". - 1 := "Invalid Certificate". - 2 := "Issuer Certificate missing". - 3 := "Certificate Chain too long". - 4 := "Error storing certificate". -*/ -static void -print_import_problem (CTRL ctrl, ksba_cert_t cert, int reason) -{ - char *fpr = NULL; - char buf[25]; - int i; - - sprintf (buf, "%d", reason); - if (cert) - { - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - /* detetect an error (all high) value */ - for (i=0; fpr[i] == 'F'; i++) - ; - if (!fpr[i]) - { - xfree (fpr); - fpr = NULL; - } - } - gpgsm_status2 (ctrl, STATUS_IMPORT_PROBLEM, buf, fpr, NULL); - xfree (fpr); -} - - -void -print_imported_summary (CTRL ctrl, struct stats_s *stats) -{ - char buf[14*25]; - - if (!opt.quiet) - { - log_info (_("total number processed: %lu\n"), stats->count); - if (stats->imported) - { - log_info (_(" imported: %lu"), stats->imported ); - log_printf ("\n"); - } - if (stats->unchanged) - log_info (_(" unchanged: %lu\n"), stats->unchanged); - if (stats->secret_read) - log_info (_(" secret keys read: %lu\n"), stats->secret_read ); - if (stats->secret_imported) - log_info (_(" secret keys imported: %lu\n"), stats->secret_imported ); - if (stats->secret_dups) - log_info (_(" secret keys unchanged: %lu\n"), stats->secret_dups ); - if (stats->not_imported) - log_info (_(" not imported: %lu\n"), stats->not_imported); - } - - sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", - stats->count, - 0l /*stats->no_user_id*/, - stats->imported, - 0l /*stats->imported_rsa*/, - stats->unchanged, - 0l /*stats->n_uids*/, - 0l /*stats->n_subk*/, - 0l /*stats->n_sigs*/, - 0l /*stats->n_revoc*/, - stats->secret_read, - stats->secret_imported, - stats->secret_dups, - 0l /*stats->skipped_new_keys*/, - stats->not_imported - ); - gpgsm_status (ctrl, STATUS_IMPORT_RES, buf); -} - - - -static void -check_and_store (CTRL ctrl, struct stats_s *stats, ksba_cert_t cert, int depth) -{ - int rc; - - if (stats) - stats->count++; - if ( depth >= 50 ) - { - log_error (_("certificate chain too long\n")); - if (stats) - stats->not_imported++; - print_import_problem (ctrl, cert, 3); - return; - } - - /* Some basic checks, but don't care about missing certificates; - this is so that we are able to import entire certificate chains - w/o requirening a special order (i.e. root-CA first). This used - to be different but because gpgsm_verify even imports - certificates without any checks, it doesn't matter much and the - code gets much cleaner. A housekeeping function to remove - certificates w/o an anchor would be nice, though. */ - rc = gpgsm_basic_cert_check (cert); - if (!rc || gpg_err_code (rc) == GPG_ERR_MISSING_CERT) - { - int existed; - - if (!keydb_store_cert (cert, 0, &existed)) - { - ksba_cert_t next = NULL; - - if (!existed) - { - print_imported_status (ctrl, cert, 1); - if (stats) - stats->imported++; - } - else - { - print_imported_status (ctrl, cert, 0); - if (stats) - stats->unchanged++; - } - - if (opt.verbose > 1 && existed) - { - if (depth) - log_info ("issuer certificate already in DB\n"); - else - log_info ("certificate already in DB\n"); - } - else if (opt.verbose && !existed) - { - if (depth) - log_info ("issuer certificate imported\n"); - else - log_info ("certificate imported\n"); - } - - /* Now lets walk up the chain and import all certificates up - the chain. This is required in case we already stored - parent certificates in the ephemeral keybox. Do not - update the statistics, though. */ - if (!gpgsm_walk_cert_chain (cert, &next)) - { - check_and_store (ctrl, NULL, next, depth+1); - ksba_cert_release (next); - } - } - else - { - log_error (_("error storing certificate\n")); - if (stats) - stats->not_imported++; - print_import_problem (ctrl, cert, 4); - } - } - else - { - log_error (_("basic certificate checks failed - not imported\n")); - if (stats) - stats->not_imported++; - print_import_problem (ctrl, cert, - gpg_err_code (rc) == GPG_ERR_MISSING_CERT? 2 : - gpg_err_code (rc) == GPG_ERR_BAD_CERT? 1 : 0); - } -} - - - - -static int -import_one (CTRL ctrl, struct stats_s *stats, int in_fd) -{ - int rc; - Base64Context b64reader = NULL; - ksba_reader_t reader; - ksba_cert_t cert = NULL; - ksba_cms_t cms = NULL; - FILE *fp = NULL; - ksba_content_type_t ct; - int any = 0; - - fp = fdopen ( dup (in_fd), "rb"); - if (!fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("fdopen() failed: %s\n", strerror (errno)); - goto leave; - } - - rc = gpgsm_create_reader (&b64reader, ctrl, fp, 1, &reader); - if (rc) - { - log_error ("can't create reader: %s\n", gpg_strerror (rc)); - goto leave; - } - - - /* We need to loop here to handle multiple PEM objects in one - file. */ - do - { - ksba_cms_release (cms); cms = NULL; - ksba_cert_release (cert); cert = NULL; - - ct = ksba_cms_identify (reader); - if (ct == KSBA_CT_SIGNED_DATA) - { /* This is probably a signed-only message - import the certs */ - ksba_stop_reason_t stopreason; - int i; - - rc = ksba_cms_new (&cms); - if (rc) - goto leave; - - rc = ksba_cms_set_reader_writer (cms, reader, NULL); - if (rc) - { - log_error ("ksba_cms_set_reader_writer failed: %s\n", - gpg_strerror (rc)); - goto leave; - } - - do - { - rc = ksba_cms_parse (cms, &stopreason); - if (rc) - { - log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (stopreason == KSBA_SR_BEGIN_DATA) - log_info ("not a certs-only message\n"); - } - while (stopreason != KSBA_SR_READY); - - for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++) - { - check_and_store (ctrl, stats, cert, 0); - ksba_cert_release (cert); - cert = NULL; - } - if (!i) - log_error ("no certificate found\n"); - else - any = 1; - } - else if (ct == KSBA_CT_PKCS12) - { /* This seems to be a pkcs12 message. We use an external - tool to parse the message and to store the private keys. - We need to use a another reader here to parse the - certificate we included in the p12 file; then we continue - to look for other pkcs12 files (works only if they are in - PEM format. */ - FILE *certfp; - Base64Context b64p12rdr; - ksba_reader_t p12rdr; - - rc = parse_p12 (reader, &certfp, stats); - if (!rc) - { - any = 1; - - rewind (certfp); - rc = gpgsm_create_reader (&b64p12rdr, ctrl, certfp, 1, &p12rdr); - if (rc) - { - log_error ("can't create reader: %s\n", gpg_strerror (rc)); - fclose (certfp); - goto leave; - } - - do - { - ksba_cert_release (cert); cert = NULL; - rc = ksba_cert_new (&cert); - if (!rc) - { - rc = ksba_cert_read_der (cert, p12rdr); - if (!rc) - check_and_store (ctrl, stats, cert, 0); - } - ksba_reader_clear (p12rdr, NULL, NULL); - } - while (!rc && !gpgsm_reader_eof_seen (b64p12rdr)); - - if (gpg_err_code (rc) == GPG_ERR_EOF) - rc = 0; - gpgsm_destroy_reader (b64p12rdr); - fclose (certfp); - if (rc) - goto leave; - } - } - else if (ct == KSBA_CT_NONE) - { /* Failed to identify this message - assume a certificate */ - - rc = ksba_cert_new (&cert); - if (rc) - goto leave; - - rc = ksba_cert_read_der (cert, reader); - if (rc) - goto leave; - - check_and_store (ctrl, stats, cert, 0); - any = 1; - } - else - { - log_error ("can't extract certificates from input\n"); - rc = gpg_error (GPG_ERR_NO_DATA); - } - - ksba_reader_clear (reader, NULL, NULL); - } - while (!gpgsm_reader_eof_seen (b64reader)); - - leave: - if (any && gpg_err_code (rc) == GPG_ERR_EOF) - rc = 0; - ksba_cms_release (cms); - ksba_cert_release (cert); - gpgsm_destroy_reader (b64reader); - if (fp) - fclose (fp); - return rc; -} - - -int -gpgsm_import (CTRL ctrl, int in_fd) -{ - int rc; - struct stats_s stats; - - memset (&stats, 0, sizeof stats); - rc = import_one (ctrl, &stats, in_fd); - print_imported_summary (ctrl, &stats); - /* If we never printed an error message do it now so that a command - line invocation will return with an error (log_error keeps a - global errorcount) */ - if (rc && !log_get_errorcount (0)) - log_error (_("error importing certificate: %s\n"), gpg_strerror (rc)); - return rc; -} - - -int -gpgsm_import_files (CTRL ctrl, int nfiles, char **files, - int (*of)(const char *fname)) -{ - int rc = 0; - struct stats_s stats; - - memset (&stats, 0, sizeof stats); - - if (!nfiles) - rc = import_one (ctrl, &stats, 0); - else - { - for (; nfiles && !rc ; nfiles--, files++) - { - int fd = of (*files); - rc = import_one (ctrl, &stats, fd); - close (fd); - if (rc == -1) - rc = 0; - } - } - print_imported_summary (ctrl, &stats); - /* If we never printed an error message do it now so that a command - line invocation will return with an error (log_error keeps a - global errorcount) */ - if (rc && !log_get_errorcount (0)) - log_error (_("error importing certificate: %s\n"), gpg_strerror (rc)); - return rc; -} - - -/* Fork and exec the protecttool, connect the file descriptor of - INFILE to stdin, return a new stream in STATUSFILE, write the - output to OUTFILE and the pid of the process in PID. Returns 0 on - success or an error code. */ -static gpg_error_t -popen_protect_tool (const char *pgmname, - FILE *infile, FILE *outfile, FILE **statusfile, pid_t *pid) -{ - gpg_error_t err; - int fd, fdout, rp[2]; - int n, i; - - fflush (infile); - rewind (infile); - fd = fileno (infile); - fdout = fileno (outfile); - if (fd == -1 || fdout == -1) - log_fatal ("no file descriptor for temporary file: %s\n", - strerror (errno)); - - /* Now start the protect-tool. */ - if (pipe (rp) == -1) - { - err = gpg_error_from_errno (errno); - log_error (_("error creating a pipe: %s\n"), strerror (errno)); - return err; - } - - *pid = fork (); - if (*pid == -1) - { - err = gpg_error_from_errno (errno); - log_error (_("error forking process: %s\n"), strerror (errno)); - close (rp[0]); - close (rp[1]); - return err; - } - - if (!*pid) - { /* Child. */ - const char *arg0; - - arg0 = strrchr (pgmname, '/'); - if (arg0) - arg0++; - else - arg0 = pgmname; - - /* Connect the infile to stdin. */ - if (fd != 0 && dup2 (fd, 0) == -1) - log_fatal ("dup2 stdin failed: %s\n", strerror (errno)); - - /* Connect the outfile to stdout. */ - if (fdout != 1 && dup2 (fdout, 1) == -1) - log_fatal ("dup2 stdout failed: %s\n", strerror (errno)); - - /* Connect stderr to our pipe. */ - if (rp[1] != 2 && dup2 (rp[1], 2) == -1) - log_fatal ("dup2 stderr failed: %s\n", strerror (errno)); - - /* Close all other files. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; - for (i=3; i < n; i++) - close(i); - errno = 0; - - setup_pinentry_env (); - - execlp (pgmname, arg0, - "--homedir", opt.homedir, - "--p12-import", - "--store", - "--no-fail-on-exist", - "--enable-status-msg", - "--", - NULL); - /* No way to print anything, as we have closed all streams. */ - _exit (31); - } - - /* Parent. */ - close (rp[1]); - *statusfile = fdopen (rp[0], "r"); - if (!*statusfile) - { - err = gpg_error_from_errno (errno); - log_error ("can't fdopen pipe for reading: %s", strerror (errno)); - kill (*pid, SIGTERM); - return err; - } - - return 0; -} - - -/* Assume that the reader is at a pkcs#12 message and try to import - certificates from that stupid format. We will alos store secret - keys. All of the pkcs#12 parsing and key storing is handled by the - gpg-protect-tool, we merely have to take care of receiving the - certificates. On success RETFP returns a temporary file with - certificates. */ -static gpg_error_t -parse_p12 (ksba_reader_t reader, FILE **retfp, struct stats_s *stats) -{ - const char *pgmname; - gpg_error_t err = 0, child_err = 0; - int i, c, cont_line; - unsigned int pos; - FILE *tmpfp, *certfp = NULL, *fp = NULL; - char buffer[1024]; - size_t nread; - pid_t pid = -1; - - if (!opt.protect_tool_program || !*opt.protect_tool_program) - pgmname = GNUPG_DEFAULT_PROTECT_TOOL; - else - pgmname = opt.protect_tool_program; - - *retfp = NULL; - - /* To avoid an extra feeder process or doing selects and because - gpg-protect-tool will anyway parse the entire pkcs#12 message in - memory, we simply use tempfiles here and pass them to - the gpg-protect-tool. */ - tmpfp = tmpfile (); - if (!tmpfp) - { - err = gpg_error_from_errno (errno); - log_error (_("error creating temporary file: %s\n"), strerror (errno)); - goto cleanup; - } - while (!(err = ksba_reader_read (reader, buffer, sizeof buffer, &nread))) - { - if (nread && fwrite (buffer, nread, 1, tmpfp) != 1) - { - err = gpg_error_from_errno (errno); - log_error (_("error writing to temporary file: %s\n"), - strerror (errno)); - goto cleanup; - } - } - if (gpg_err_code (err) == GPG_ERR_EOF) - err = 0; - if (err) - { - log_error (_("error reading input: %s\n"), gpg_strerror (err)); - goto cleanup; - } - - certfp = tmpfile (); - if (!certfp) - { - err = gpg_error_from_errno (errno); - log_error (_("error creating temporary file: %s\n"), strerror (errno)); - goto cleanup; - } - - err = popen_protect_tool (pgmname, tmpfp, certfp, &fp, &pid); - if (err) - { - pid = -1; - goto cleanup; - } - fclose (tmpfp); - tmpfp = NULL; - - /* Read stderr of the protect tool. */ - pos = 0; - cont_line = 0; - while ((c=getc (fp)) != EOF) - { - /* fixme: We could here grep for status information of the - protect tool to figure out better error codes for - CHILD_ERR. */ - buffer[pos++] = c; - if (pos >= sizeof buffer - 5 || c == '\n') - { - buffer[pos - (c == '\n')] = 0; - if (cont_line) - log_printf ("%s", buffer); - else - { - if (!strncmp (buffer, "gpg-protect-tool: [PROTECT-TOOL:] ",34)) - { - char *p, *pend; - - p = buffer + 34; - pend = strchr (p, ' '); - if (pend) - *pend = 0; - if ( !strcmp (p, "secretkey-stored")) - { - stats->count++; - stats->secret_read++; - stats->secret_imported++; - } - else if ( !strcmp (p, "secretkey-exists")) - { - stats->count++; - stats->secret_read++; - stats->secret_dups++; - } - else if ( !strcmp (p, "bad-passphrase")) - ; - } - else - log_info ("%s", buffer); - } - pos = 0; - cont_line = (c != '\n'); - } - } - - if (pos) - { - buffer[pos] = 0; - if (cont_line) - log_printf ("%s\n", buffer); - else - log_info ("%s\n", buffer); - } - - /* If we found no error in the output of the cild, setup a suitable - error code, which will later be reset if the exit status of the - child is 0. */ - if (!child_err) - child_err = gpg_error (GPG_ERR_DECRYPT_FAILED); - - - cleanup: - if (tmpfp) - fclose (tmpfp); - if (fp) - fclose (fp); - if (pid != -1) - { - int status; - - while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR) - ; - if (i == -1) - log_error (_("waiting for protect-tool to terminate failed: %s\n"), - strerror (errno)); - else if (WIFEXITED (status) && WEXITSTATUS (status) == 31) - log_error (_("error running `%s': probably not installed\n"), pgmname); - else if (WIFEXITED (status) && WEXITSTATUS (status)) - log_error (_("error running `%s': exit status %d\n"), pgmname, - WEXITSTATUS (status)); - else if (!WIFEXITED (status)) - log_error (_("error running `%s': terminated\n"), pgmname); - else - child_err = 0; - } - if (!err) - err = child_err; - if (err) - { - if (certfp) - fclose (certfp); - } - else - *retfp = certfp; - return err; -} diff --git a/sm/keydb.c b/sm/keydb.c deleted file mode 100644 index 6c5c77364..000000000 --- a/sm/keydb.c +++ /dev/null @@ -1,1532 +0,0 @@ -/* keydb.c - key database dispatcher - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "gpgsm.h" -#include "../kbx/keybox.h" -#include "keydb.h" -#include "i18n.h" - -#define DIRSEP_C '/' - -static int active_handles; - -typedef enum { - KEYDB_RESOURCE_TYPE_NONE = 0, - KEYDB_RESOURCE_TYPE_KEYBOX -} KeydbResourceType; -#define MAX_KEYDB_RESOURCES 20 - -struct resource_item { - KeydbResourceType type; - union { - KEYBOX_HANDLE kr; - } u; - void *token; - int secret; - DOTLOCK lockhandle; -}; - -static struct resource_item all_resources[MAX_KEYDB_RESOURCES]; -static int used_resources; - -struct keydb_handle { - int locked; - int found; - int current; - int is_ephemeral; - int used; /* items in active */ - struct resource_item active[MAX_KEYDB_RESOURCES]; -}; - - -static int lock_all (KEYDB_HANDLE hd); -static void unlock_all (KEYDB_HANDLE hd); - - -/* - * Register a resource (which currently may only be a keybox file). - * The first keybox which is added by this function is - * created if it does not exist. - * Note: this function may be called before secure memory is - * available. - */ -int -keydb_add_resource (const char *url, int force, int secret) -{ - static int any_secret, any_public; - const char *resname = url; - char *filename = NULL; - int rc = 0; - FILE *fp; - KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; - const char *created_fname = NULL; - - /* Do we have an URL? - gnupg-kbx:filename := this is a plain keybox - filename := See what is is, but create as plain keybox. - */ - if (strlen (resname) > 10) - { - if (!strncmp (resname, "gnupg-kbx:", 10) ) - { - rt = KEYDB_RESOURCE_TYPE_KEYBOX; - resname += 10; - } -#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__) - else if (strchr (resname, ':')) - { - log_error ("invalid key resource URL `%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } -#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ - } - - if (*resname != DIRSEP_C ) - { /* do tilde expansion etc */ - if (strchr(resname, DIRSEP_C) ) - filename = make_filename (resname, NULL); - else - filename = make_filename (opt.homedir, resname, NULL); - } - else - filename = xstrdup (resname); - - if (!force) - force = secret? !any_secret : !any_public; - - /* see whether we can determine the filetype */ - if (rt == KEYDB_RESOURCE_TYPE_NONE) - { - FILE *fp2 = fopen( filename, "rb" ); - - if (fp2) { - u32 magic; - - /* FIXME: check for the keybox magic */ - if (fread( &magic, 4, 1, fp2) == 1 ) - { - if (magic == 0x13579ace || magic == 0xce9a5713) - ; /* GDBM magic - no more support */ - else - rt = KEYDB_RESOURCE_TYPE_KEYBOX; - } - else /* maybe empty: assume ring */ - rt = KEYDB_RESOURCE_TYPE_KEYBOX; - fclose (fp2); - } - else /* no file yet: create ring */ - rt = KEYDB_RESOURCE_TYPE_KEYBOX; - } - - switch (rt) - { - case KEYDB_RESOURCE_TYPE_NONE: - log_error ("unknown type of key resource `%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - - case KEYDB_RESOURCE_TYPE_KEYBOX: - fp = fopen (filename, "rb"); - if (!fp && !force) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - - if (!fp) - { /* no file */ -#if 0 /* no autocreate of the homedirectory yet */ - { - char *last_slash_in_filename; - - last_slash_in_filename = strrchr (filename, DIRSEP_C); - *last_slash_in_filename = 0; - if (access (filename, F_OK)) - { /* on the first time we try to create the default - homedir and in this case the process will be - terminated, so that on the next invocation can - read the options file in on startup */ - try_make_homedir (filename); - rc = gpg_error (GPG_ERR_FILE_OPEN_ERROR); - *last_slash_in_filename = DIRSEP_C; - goto leave; - } - *last_slash_in_filename = DIRSEP_C; - } -#endif - fp = fopen (filename, "w"); - if (!fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_error (_("error creating keybox `%s': %s\n"), - filename, strerror(errno)); - if (errno == ENOENT) - log_info (_("you may want to start the gpg-agent first\n")); - goto leave; - } - - if (!opt.quiet) - log_info (_("keybox `%s' created\n"), filename); - created_fname = filename; - } - fclose (fp); - fp = NULL; - /* now register the file */ - { - - void *token = keybox_register_file (filename, secret); - if (!token) - ; /* already registered - ignore it */ - else if (used_resources >= MAX_KEYDB_RESOURCES) - rc = gpg_error (GPG_ERR_RESOURCE_LIMIT); - else - { - all_resources[used_resources].type = rt; - all_resources[used_resources].u.kr = NULL; /* Not used here */ - all_resources[used_resources].token = token; - all_resources[used_resources].secret = secret; - - all_resources[used_resources].lockhandle - = create_dotlock (filename); - if (!all_resources[used_resources].lockhandle) - log_fatal ( _("can't create lock for `%s'\n"), filename); - - /* Do a compress run if needed and the file is not locked. */ - if (!make_dotlock (all_resources[used_resources].lockhandle, 0)) - { - KEYBOX_HANDLE kbxhd = keybox_new (token, secret); - - if (kbxhd) - { - keybox_compress (kbxhd); - keybox_release (kbxhd); - } - release_dotlock (all_resources[used_resources].lockhandle); - } - - used_resources++; - } - } - - - break; - default: - log_error ("resource type of `%s' not supported\n", url); - rc = gpg_error (GPG_ERR_NOT_SUPPORTED); - goto leave; - } - - /* fixme: check directory permissions and print a warning */ - - leave: - if (rc) - log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror(rc)); - else if (secret) - any_secret = 1; - else - any_public = 1; - xfree (filename); - return rc; -} - - -KEYDB_HANDLE -keydb_new (int secret) -{ - KEYDB_HANDLE hd; - int i, j; - - hd = xcalloc (1, sizeof *hd); - hd->found = -1; - - assert (used_resources <= MAX_KEYDB_RESOURCES); - for (i=j=0; i < used_resources; i++) - { - if (!all_resources[i].secret != !secret) - continue; - switch (all_resources[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - hd->active[j].type = all_resources[i].type; - hd->active[j].token = all_resources[i].token; - hd->active[j].secret = all_resources[i].secret; - hd->active[j].lockhandle = all_resources[i].lockhandle; - hd->active[j].u.kr = keybox_new (all_resources[i].token, secret); - if (!hd->active[j].u.kr) - { - xfree (hd); - return NULL; /* fixme: release all previously allocated handles*/ - } - j++; - break; - } - } - hd->used = j; - - active_handles++; - return hd; -} - -void -keydb_release (KEYDB_HANDLE hd) -{ - int i; - - if (!hd) - return; - assert (active_handles > 0); - active_handles--; - - unlock_all (hd); - for (i=0; i < hd->used; i++) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - keybox_release (hd->active[i].u.kr); - break; - } - } - - xfree (hd); -} - - -/* Return the name of the current resource. This is function first - looks for the last found found, then for the current search - position, and last returns the first available resource. The - returned string is only valid as long as the handle exists. This - function does only return NULL if no handle is specified, in all - other error cases an empty string is returned. */ -const char * -keydb_get_resource_name (KEYDB_HANDLE hd) -{ - int idx; - const char *s = NULL; - - if (!hd) - return NULL; - - if ( hd->found >= 0 && hd->found < hd->used) - idx = hd->found; - else if ( hd->current >= 0 && hd->current < hd->used) - idx = hd->current; - else - idx = 0; - - switch (hd->active[idx].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - s = NULL; - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - s = keybox_get_resource_name (hd->active[idx].u.kr); - break; - } - - return s? s: ""; -} - -/* Switch the handle into ephemeral mode and return the orginal value. */ -int -keydb_set_ephemeral (KEYDB_HANDLE hd, int yes) -{ - int i; - - if (!hd) - return 0; - - yes = !!yes; - if (hd->is_ephemeral != yes) - { - for (i=0; i < hd->used; i++) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - keybox_set_ephemeral (hd->active[i].u.kr, yes); - break; - } - } - } - - i = hd->is_ephemeral; - hd->is_ephemeral = yes; - return i; -} - - -/* If the keyring has not yet been locked, lock it now. This - operation is required before any update opeations; it is optionaly - for an insert operation. The lock is released with - keydb_released. */ -gpg_error_t -keydb_lock (KEYDB_HANDLE hd) -{ - if (!hd) - return gpg_error (GPG_ERR_INV_HANDLE); - if (hd->locked) - return 0; /* Already locked. */ - return lock_all (hd); -} - - - -static int -lock_all (KEYDB_HANDLE hd) -{ - int i, rc = 0; - - /* Fixme: This locking scheme may lead to deadlock if the resources - are not added in the same order by all processes. We are - currently only allowing one resource so it is not a problem. */ - for (i=0; i < hd->used; i++) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - if (hd->active[i].lockhandle) - rc = make_dotlock (hd->active[i].lockhandle, -1); - break; - } - if (rc) - break; - } - - if (rc) - { - /* revert the already set locks */ - for (i--; i >= 0; i--) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - if (hd->active[i].lockhandle) - release_dotlock (hd->active[i].lockhandle); - break; - } - } - } - else - hd->locked = 1; - - /* make_dotlock () does not yet guarantee that errno is set, thus - we can't rely on the error reason and will simply use - EACCES. */ - return rc? gpg_error (GPG_ERR_EACCES) : 0; -} - -static void -unlock_all (KEYDB_HANDLE hd) -{ - int i; - - if (!hd->locked) - return; - - for (i=hd->used-1; i >= 0; i--) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - if (hd->active[i].lockhandle) - release_dotlock (hd->active[i].lockhandle); - break; - } - } - hd->locked = 0; -} - - -#if 0 -/* - * Return the last found keybox. Caller must free it. - * The returned keyblock has the kbode flag bit 0 set for the node with - * the public key used to locate the keyblock or flag bit 1 set for - * the user ID node. - */ -int -keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) -{ - int rc = 0; - - if (!hd) - return G10ERR_INV_ARG; - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - switch (hd->active[hd->found].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = G10ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_get_keyblock (hd->active[hd->found].u.kr, ret_kb); - break; - } - - return rc; -} - -/* - * update the current keyblock with KB - */ -int -keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb) -{ - int rc = 0; - - if (!hd) - return G10ERR_INV_ARG; - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - if( opt.dry_run ) - return 0; - - if (!hd->locked) - return gpg_error (GPG_ERR_NOT_LOCKED); - - switch (hd->active[hd->found].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = G10ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_update_keyblock (hd->active[hd->found].u.kr, kb); - break; - } - - unlock_all (hd); - return rc; -} - - -/* - * Insert a new KB into one of the resources. - */ -int -keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb) -{ - int rc = -1; - int idx; - - if (!hd) - return G10ERR_INV_ARG; - - if( opt.dry_run ) - return 0; - - if ( hd->found >= 0 && hd->found < hd->used) - idx = hd->found; - else if ( hd->current >= 0 && hd->current < hd->used) - idx = hd->current; - else - return G10ERR_GENERAL; - - rc = lock_all (hd); - if (rc) - return rc; - - switch (hd->active[idx].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = G10ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_insert_keyblock (hd->active[idx].u.kr, kb); - break; - } - - unlock_all (hd); - return rc; -} - -#endif /*disabled code*/ - - - -/* - Return the last found object. Caller must free it. The returned - keyblock has the kbode flag bit 0 set for the node with the public - key used to locate the keyblock or flag bit 1 set for the user ID - node. */ -int -keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert) -{ - int rc = 0; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - switch (hd->active[hd->found].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - rc = gpg_error (GPG_ERR_GENERAL); /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_get_cert (hd->active[hd->found].u.kr, r_cert); - break; - } - - return rc; -} - -/* Return a flag of the last found object. WHICH is the flag requested; - it should be one of the KEYBOX_FLAG_ values. If the operation is - successful, the flag value will be stored at the address given by - VALUE. Return 0 on success or an error code. */ -gpg_error_t -keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int *value) -{ - int err = 0; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if ( hd->found < 0 || hd->found >= hd->used) - return gpg_error (GPG_ERR_NOTHING_FOUND); - - switch (hd->active[hd->found].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - err = gpg_error (GPG_ERR_GENERAL); /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - err = keybox_get_flags (hd->active[hd->found].u.kr, which, idx, value); - break; - } - - return err; -} - -/* Set a flag of the last found object. WHICH is the flag to be set; it - should be one of the KEYBOX_FLAG_ values. If the operation is - successful, the flag value will be stored in the keybox. Note, - that some flag values can't be updated and thus may return an - error, some other flag values may be masked out before an update. - Returns 0 on success or an error code. */ -gpg_error_t -keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value) -{ - int err = 0; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if ( hd->found < 0 || hd->found >= hd->used) - return gpg_error (GPG_ERR_NOTHING_FOUND); - - if (!hd->locked) - return gpg_error (GPG_ERR_NOT_LOCKED); - - switch (hd->active[hd->found].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - err = gpg_error (GPG_ERR_GENERAL); /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - err = keybox_set_flags (hd->active[hd->found].u.kr, which, idx, value); - break; - } - - return err; -} - -/* - * Insert a new Certificate into one of the resources. - */ -int -keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert) -{ - int rc = -1; - int idx; - char digest[20]; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if (opt.dry_run) - return 0; - - if ( hd->found >= 0 && hd->found < hd->used) - idx = hd->found; - else if ( hd->current >= 0 && hd->current < hd->used) - idx = hd->current; - else - return gpg_error (GPG_ERR_GENERAL); - - rc = lock_all (hd); - if (rc) - return rc; - - gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/ - - switch (hd->active[idx].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - rc = gpg_error (GPG_ERR_GENERAL); - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_insert_cert (hd->active[idx].u.kr, cert, digest); - break; - } - - unlock_all (hd); - return rc; -} - - - -/* update the current keyblock with KB */ -int -keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert) -{ - int rc = 0; - char digest[20]; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - if (opt.dry_run) - return 0; - - rc = lock_all (hd); - if (rc) - return rc; - - gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/ - - switch (hd->active[hd->found].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - rc = gpg_error (GPG_ERR_GENERAL); /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_update_cert (hd->active[hd->found].u.kr, cert, digest); - break; - } - - unlock_all (hd); - return rc; -} - - -/* - * The current keyblock or cert will be deleted. - */ -int -keydb_delete (KEYDB_HANDLE hd) -{ - int rc = -1; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - if( opt.dry_run ) - return 0; - - if (!hd->locked) - return gpg_error (GPG_ERR_NOT_LOCKED); - - switch (hd->active[hd->found].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - rc = gpg_error (GPG_ERR_GENERAL); - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_delete (hd->active[hd->found].u.kr); - break; - } - - unlock_all (hd); - return rc; -} - - - -/* - * Locate the default writable key resource, so that the next - * operation (which is only relevant for inserts) will be done on this - * resource. - */ -int -keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) -{ - int rc; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - rc = keydb_search_reset (hd); /* this does reset hd->current */ - if (rc) - return rc; - - for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) - { - switch (hd->active[hd->current].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - BUG(); - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - if (keybox_is_writable (hd->active[hd->current].token)) - return 0; /* found (hd->current is set to it) */ - break; - } - } - - return -1; -} - -/* - * Rebuild the caches of all key resources. - */ -void -keydb_rebuild_caches (void) -{ - int i; - - for (i=0; i < used_resources; i++) - { - if (all_resources[i].secret) - continue; - switch (all_resources[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: -/* rc = keybox_rebuild_cache (all_resources[i].token); */ -/* if (rc) */ -/* log_error (_("failed to rebuild keybox cache: %s\n"), */ -/* g10_errstr (rc)); */ - break; - } - } -} - - - -/* - * Start the next search on this handle right at the beginning - */ -int -keydb_search_reset (KEYDB_HANDLE hd) -{ - int i, rc = 0; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - hd->current = 0; - hd->found = -1; - /* and reset all resources */ - for (i=0; !rc && i < hd->used; i++) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_search_reset (hd->active[i].u.kr); - break; - } - } - return rc; /* fixme: we need to map error codes or share them with - all modules*/ -} - -/* - * Search through all keydb resources, starting at the current position, - * for a keyblock which contains one of the keys described in the DESC array. - */ -int -keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc) -{ - int rc = -1; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - while (rc == -1 && hd->current >= 0 && hd->current < hd->used) - { - switch (hd->active[hd->current].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - BUG(); /* we should never see it here */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc); - break; - } - if (rc == -1) /* EOF -> switch to next resource */ - hd->current++; - else if (!rc) - hd->found = hd->current; - } - - return rc; -} - - -int -keydb_search_first (KEYDB_HANDLE hd) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FIRST; - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_next (KEYDB_HANDLE hd) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_NEXT; - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_kid (KEYDB_HANDLE hd, u32 *kid) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_LONG_KID; -/* desc.u.kid[0] = kid[0]; */ -/* desc.u.kid[1] = kid[1]; */ - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FPR; - memcpy (desc.u.fpr, fpr, 20); - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer) -{ - KEYDB_SEARCH_DESC desc; - int rc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_ISSUER; - desc.u.name = issuer; - rc = keydb_search (hd, &desc, 1); - return rc; -} - -int -keydb_search_issuer_sn (KEYDB_HANDLE hd, - const char *issuer, ksba_const_sexp_t serial) -{ - KEYDB_SEARCH_DESC desc; - int rc; - const unsigned char *s; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN; - s = serial; - if (*s !='(') - return gpg_error (GPG_ERR_INV_VALUE); - s++; - for (desc.snlen = 0; digitp (s); s++) - desc.snlen = 10*desc.snlen + atoi_1 (s); - if (*s !=':') - return gpg_error (GPG_ERR_INV_VALUE); - desc.sn = s+1; - desc.u.name = issuer; - rc = keydb_search (hd, &desc, 1); - return rc; -} - -int -keydb_search_subject (KEYDB_HANDLE hd, const char *name) -{ - KEYDB_SEARCH_DESC desc; - int rc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_SUBJECT; - desc.u.name = name; - rc = keydb_search (hd, &desc, 1); - return rc; -} - - -static int -hextobyte (const unsigned char *s) -{ - int c; - - if( *s >= '0' && *s <= '9' ) - c = 16 * (*s - '0'); - else if ( *s >= 'A' && *s <= 'F' ) - c = 16 * (10 + *s - 'A'); - else if ( *s >= 'a' && *s <= 'f' ) - c = 16 * (10 + *s - 'a'); - else - return -1; - s++; - if ( *s >= '0' && *s <= '9' ) - c += *s - '0'; - else if ( *s >= 'A' && *s <= 'F' ) - c += 10 + *s - 'A'; - else if ( *s >= 'a' && *s <= 'f' ) - c += 10 + *s - 'a'; - else - return -1; - return c; -} - - -static int -classify_user_id (const char *name, - KEYDB_SEARCH_DESC *desc, - int *force_exact ) -{ - const char *s; - int hexprefix = 0; - int hexlength; - int mode = 0; - - /* clear the structure so that the mode field is set to zero unless - * we set it to the correct value right at the end of this function */ - memset (desc, 0, sizeof *desc); - *force_exact = 0; - /* Skip leading spaces. Fixme: what about trailing white space? */ - for(s = name; *s && spacep (s); s++ ) - ; - - switch (*s) - { - case 0: /* empty string is an error */ - return 0; - - case '.': /* an email address, compare from end */ - mode = KEYDB_SEARCH_MODE_MAILEND; - s++; - desc->u.name = s; - break; - - case '<': /* an email address */ - mode = KEYDB_SEARCH_MODE_MAIL; - s++; - desc->u.name = s; - break; - - case '@': /* part of an email address */ - mode = KEYDB_SEARCH_MODE_MAILSUB; - s++; - desc->u.name = s; - break; - - case '=': /* exact compare */ - mode = KEYDB_SEARCH_MODE_EXACT; - s++; - desc->u.name = s; - break; - - case '*': /* case insensitive substring search */ - mode = KEYDB_SEARCH_MODE_SUBSTR; - s++; - desc->u.name = s; - break; - - case '+': /* compare individual words */ - mode = KEYDB_SEARCH_MODE_WORDS; - s++; - desc->u.name = s; - break; - - case '/': /* subject's DN */ - s++; - if (!*s || spacep (s)) - return 0; /* no DN or prefixed with a space */ - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_SUBJECT; - break; - - case '#': - { - const char *si; - - s++; - if ( *s == '/') - { /* "#/" indicates an issuer's DN */ - s++; - if (!*s || spacep (s)) - return 0; /* no DN or prefixed with a space */ - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_ISSUER; - } - else - { /* serialnumber + optional issuer ID */ - for (si=s; *si && *si != '/'; si++) - { - if (!strchr("01234567890abcdefABCDEF", *si)) - return 0; /* invalid digit in serial number*/ - } - desc->sn = s; - desc->snlen = -1; - if (!*si) - mode = KEYDB_SEARCH_MODE_SN; - else - { - s = si+1; - if (!*s || spacep (s)) - return 0; /* no DN or prefixed with a space */ - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_ISSUER_SN; - } - } - } - break; - - case ':': /*Unified fingerprint */ - { - const char *se, *si; - int i; - - se = strchr (++s,':'); - if (!se) - return 0; - for (i=0,si=s; si < se; si++, i++ ) - { - if (!strchr("01234567890abcdefABCDEF", *si)) - return 0; /* invalid digit */ - } - if (i != 32 && i != 40) - return 0; /* invalid length of fpr*/ - for (i=0,si=s; si < se; i++, si +=2) - desc->u.fpr[i] = hextobyte(si); - for (; i < 20; i++) - desc->u.fpr[i]= 0; - s = se + 1; - mode = KEYDB_SEARCH_MODE_FPR; - } - break; - - default: - if (s[0] == '0' && s[1] == 'x') - { - hexprefix = 1; - s += 2; - } - - hexlength = strspn(s, "0123456789abcdefABCDEF"); - if (hexlength >= 8 && s[hexlength] =='!') - { - *force_exact = 1; - hexlength++; /* just for the following check */ - } - - /* check if a hexadecimal number is terminated by EOS or blank */ - if (hexlength && s[hexlength] && !spacep (s+hexlength)) - { - if (hexprefix) /* a "0x" prefix without correct */ - return 0; /* termination is an error */ - /* The first chars looked like a hex number, but really is - not */ - hexlength = 0; - } - - if (*force_exact) - hexlength--; /* remove the bang */ - - if (hexlength == 8 - || (!hexprefix && hexlength == 9 && *s == '0')) - { /* short keyid */ - unsigned long kid; - if (hexlength == 9) - s++; - kid = strtoul( s, NULL, 16 ); - desc->u.kid[4] = kid >> 24; - desc->u.kid[5] = kid >> 16; - desc->u.kid[6] = kid >> 8; - desc->u.kid[7] = kid; - mode = KEYDB_SEARCH_MODE_SHORT_KID; - } - else if (hexlength == 16 - || (!hexprefix && hexlength == 17 && *s == '0')) - { /* complete keyid */ - unsigned long kid0, kid1; - char buf[9]; - if (hexlength == 17) - s++; - mem2str(buf, s, 9 ); - kid0 = strtoul (buf, NULL, 16); - kid1 = strtoul (s+8, NULL, 16); - desc->u.kid[0] = kid0 >> 24; - desc->u.kid[1] = kid0 >> 16; - desc->u.kid[2] = kid0 >> 8; - desc->u.kid[3] = kid0; - desc->u.kid[4] = kid1 >> 24; - desc->u.kid[5] = kid1 >> 16; - desc->u.kid[6] = kid1 >> 8; - desc->u.kid[7] = kid1; - mode = KEYDB_SEARCH_MODE_LONG_KID; - } - else if (hexlength == 32 - || (!hexprefix && hexlength == 33 && *s == '0')) - { /* md5 fingerprint */ - int i; - if (hexlength == 33) - s++; - memset(desc->u.fpr+16, 0, 4); - for (i=0; i < 16; i++, s+=2) - { - int c = hextobyte(s); - if (c == -1) - return 0; - desc->u.fpr[i] = c; - } - mode = KEYDB_SEARCH_MODE_FPR16; - } - else if (hexlength == 40 - || (!hexprefix && hexlength == 41 && *s == '0')) - { /* sha1/rmd160 fingerprint */ - int i; - if (hexlength == 41) - s++; - for (i=0; i < 20; i++, s+=2) - { - int c = hextobyte(s); - if (c == -1) - return 0; - desc->u.fpr[i] = c; - } - mode = KEYDB_SEARCH_MODE_FPR20; - } - else if (!hexprefix) - { - /* The fingerprint in an X.509 listing is often delimited by - colons, so we try to single this case out. */ - mode = 0; - hexlength = strspn (s, ":0123456789abcdefABCDEF"); - if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength))) - { - int i; - - for (i=0; i < 20; i++, s += 3) - { - int c = hextobyte(s); - if (c == -1 || (i < 19 && s[2] != ':')) - break; - desc->u.fpr[i] = c; - } - if (i == 20) - mode = KEYDB_SEARCH_MODE_FPR20; - } - if (!mode) /* default is substring search */ - { - *force_exact = 0; - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_SUBSTR; - } - } - else - { /* hex number with a prefix but a wrong length */ - return 0; - } - } - - desc->mode = mode; - return mode; -} - - -int -keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc) -{ - int dummy; - KEYDB_SEARCH_DESC dummy_desc; - - if (!desc) - desc = &dummy_desc; - - if (!classify_user_id (name, desc, &dummy)) - return gpg_error (GPG_ERR_INV_NAME); - return 0; -} - - -/* Store the certificate in the key DB but make sure that it does not - already exists. We do this simply by comparing the fingerprint. - If EXISTED is not NULL it will be set to true if the certificate - was already in the DB. */ -int -keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed) -{ - KEYDB_HANDLE kh; - int rc; - unsigned char fpr[20]; - - if (existed) - *existed = 0; - - if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL)) - { - log_error (_("failed to get the fingerprint\n")); - return gpg_error (GPG_ERR_GENERAL); - } - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocate keyDB handle\n")); - return gpg_error (GPG_ERR_ENOMEM);; - } - - if (ephemeral) - keydb_set_ephemeral (kh, 1); - - rc = keydb_search_fpr (kh, fpr); - if (rc != -1) - { - keydb_release (kh); - if (!rc) - { - if (existed) - *existed = 1; - return 0; /* okay */ - } - log_error (_("problem looking for existing certificate: %s\n"), - gpg_strerror (rc)); - return rc; - } - - rc = keydb_locate_writable (kh, 0); - if (rc) - { - log_error (_("error finding writable keyDB: %s\n"), gpg_strerror (rc)); - keydb_release (kh); - return rc; - } - - rc = keydb_insert_cert (kh, cert); - if (rc) - { - log_error (_("error storing certificate: %s\n"), gpg_strerror (rc)); - keydb_release (kh); - return rc; - } - keydb_release (kh); - return 0; -} - - -/* This is basically keydb_set_flags but it implements a complete - transaction by locating the certificate in the DB and updating the - flags. */ -gpg_error_t -keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value) -{ - KEYDB_HANDLE kh; - gpg_error_t err; - unsigned char fpr[20]; - unsigned int old_value; - - if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL)) - { - log_error (_("failed to get the fingerprint\n")); - return gpg_error (GPG_ERR_GENERAL); - } - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocate keyDB handle\n")); - return gpg_error (GPG_ERR_ENOMEM);; - } - - err = keydb_lock (kh); - if (err) - { - log_error (_("error locking keybox: %s\n"), gpg_strerror (err)); - keydb_release (kh); - return err; - } - - err = keydb_search_fpr (kh, fpr); - if (err) - { - log_error (_("problem re-searching certificate: %s\n"), - gpg_strerror (err)); - keydb_release (kh); - return err; - } - - err = keydb_get_flags (kh, which, idx, &old_value); - if (err) - { - log_error (_("error getting stored flags: %s\n"), gpg_strerror (err)); - keydb_release (kh); - return err; - } - if (value != old_value) - { - err = keydb_set_flags (kh, which, idx, value); - if (err) - { - log_error (_("error storing flags: %s\n"), gpg_strerror (err)); - keydb_release (kh); - return err; - } - } - keydb_release (kh); - return 0; -} - - -/* Reset all the certificate flags we have stored with the certificates - for performance reasons. */ -void -keydb_clear_some_cert_flags (ctrl_t ctrl, STRLIST names) -{ - gpg_error_t err; - KEYDB_HANDLE hd = NULL; - KEYDB_SEARCH_DESC *desc = NULL; - int ndesc; - STRLIST sl; - int rc=0; - unsigned int old_value, value; - - hd = keydb_new (0); - if (!hd) - { - log_error ("keydb_new failed\n"); - goto leave; - } - - if (!names) - ndesc = 1; - else - { - for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) - ; - } - - desc = xtrycalloc (ndesc, sizeof *desc); - if (!ndesc) - { - log_error ("allocating memory failed: %s\n", - gpg_strerror (OUT_OF_CORE (errno))); - goto leave; - } - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_FIRST; - else - { - for (ndesc=0, sl=names; sl; sl = sl->next) - { - rc = keydb_classify_name (sl->d, desc+ndesc); - if (rc) - { - log_error ("key `%s' not found: %s\n", - sl->d, gpg_strerror (rc)); - rc = 0; - } - else - ndesc++; - } - } - - err = keydb_lock (hd); - if (err) - { - log_error (_("error locking keybox: %s\n"), gpg_strerror (err)); - goto leave; - } - - while (!(rc = keydb_search (hd, desc, ndesc))) - { - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - - err = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &old_value); - if (err) - { - log_error (_("error getting stored flags: %s\n"), - gpg_strerror (err)); - goto leave; - } - - value = (old_value & ~VALIDITY_REVOKED); - if (value != old_value) - { - err = keydb_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value); - if (err) - { - log_error (_("error storing flags: %s\n"), gpg_strerror (err)); - goto leave; - } - } - } - if (rc && rc != -1) - log_error ("keydb_search failed: %s\n", gpg_strerror (rc)); - - leave: - xfree (desc); - keydb_release (hd); -} - - diff --git a/sm/keydb.h b/sm/keydb.h deleted file mode 100644 index 924ad77c4..000000000 --- a/sm/keydb.h +++ /dev/null @@ -1,85 +0,0 @@ -/* keydb.h - Key database - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_KEYDB_H -#define GNUPG_KEYDB_H - -#include <ksba.h> - -#include "../kbx/keybox-search-desc.h" - -typedef struct keydb_handle *KEYDB_HANDLE; - -/* Flag value used with KEYBOX_FLAG_VALIDITY. */ -#define VALIDITY_REVOKED (1<<5) - - -/*-- keydb.c --*/ -int keydb_add_resource (const char *url, int force, int secret); -KEYDB_HANDLE keydb_new (int secret); -void keydb_release (KEYDB_HANDLE hd); -int keydb_set_ephemeral (KEYDB_HANDLE hd, int yes); -const char *keydb_get_resource_name (KEYDB_HANDLE hd); -gpg_error_t keydb_lock (KEYDB_HANDLE hd); - -#if 0 /* pgp stuff */ -int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb); -int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb); -int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb); -#endif - -gpg_error_t keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, - unsigned int *value); -gpg_error_t keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, - unsigned int value); -int keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert); -int keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert); -int keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert); - -int keydb_delete (KEYDB_HANDLE hd); - -int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved); -void keydb_rebuild_caches (void); - -int keydb_search_reset (KEYDB_HANDLE hd); -int keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc); -int keydb_search_first (KEYDB_HANDLE hd); -int keydb_search_next (KEYDB_HANDLE hd); -int keydb_search_kid (KEYDB_HANDLE hd, u32 *kid); -int keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr); -int keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer); -int keydb_search_issuer_sn (KEYDB_HANDLE hd, - const char *issuer, const unsigned char *serial); -int keydb_search_subject (KEYDB_HANDLE hd, const char *issuer); - -int keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc); - -int keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed); -gpg_error_t keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, - unsigned int value); - -void keydb_clear_some_cert_flags (ctrl_t ctrl, STRLIST names); - - -#endif /*GNUPG_KEYDB_H*/ - - - - diff --git a/sm/keylist.c b/sm/keylist.c deleted file mode 100644 index 27c67ded3..000000000 --- a/sm/keylist.c +++ /dev/null @@ -1,1252 +0,0 @@ -/* keylist.c - * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" - -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */ -#include "i18n.h" - -struct list_external_parm_s { - ctrl_t ctrl; - FILE *fp; - int print_header; - int with_colons; - int with_chain; - int raw_mode; -}; - - -/* This table is to map Extended Key Usage OIDs to human readable - names. */ -struct { - const char *oid; - const char *name; -} key_purpose_map[] = { - { "1.3.6.1.5.5.7.3.1", "serverAuth" }, - { "1.3.6.1.5.5.7.3.2", "clientAuth" }, - { "1.3.6.1.5.5.7.3.3", "codeSigning" }, - { "1.3.6.1.5.5.7.3.4", "emailProtection" }, - { "1.3.6.1.5.5.7.3.5", "ipsecEndSystem" }, - { "1.3.6.1.5.5.7.3.6", "ipsecTunnel" }, - { "1.3.6.1.5.5.7.3.7", "ipsecUser" }, - { "1.3.6.1.5.5.7.3.8", "timeStamping" }, - { "1.3.6.1.5.5.7.3.9", "ocspSigning" }, - { "1.3.6.1.5.5.7.3.10", "dvcs" }, - { "1.3.6.1.5.5.7.3.11", "sbgpCertAAServerAuth" }, - { "1.3.6.1.5.5.7.3.13", "eapOverPPP" }, - { "1.3.6.1.5.5.7.3.14", "wlanSSID" }, - { NULL, NULL } -}; - - -/* A table mapping OIDs to a descriptive string. */ -static struct { - char *oid; - char *name; - unsigned int flag; -} oidtranstbl[] = { - - /* Algorithms. */ - { "1.2.840.10040.4.1", "dsa" }, - { "1.2.840.10040.4.3", "dsaWithSha1" }, - - { "1.2.840.113549.1.1.1", "rsaEncryption" }, - { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" }, - { "1.2.840.113549.1.1.3", "md4WithRSAEncryption" }, - { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" }, - { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" }, - { "1.2.840.113549.1.1.7", "rsaOAEP" }, - { "1.2.840.113549.1.1.8", "rsaOAEP-MGF" }, - { "1.2.840.113549.1.1.9", "rsaOAEP-pSpecified" }, - { "1.2.840.113549.1.1.10", "rsaPSS" }, - { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" }, - { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" }, - { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" }, - - { "1.3.14.3.2.26", "sha1" }, - { "1.3.14.3.2.29", "sha-1WithRSAEncryption" }, - { "1.3.36.3.3.1.2", "rsaSignatureWithripemd160" }, - - - /* Telesec extensions. */ - { "0.2.262.1.10.12.0", "certExtensionLiabilityLimitationExt" }, - { "0.2.262.1.10.12.1", "telesecCertIdExt" }, - { "0.2.262.1.10.12.2", "telesecPolicyIdentifier" }, - { "0.2.262.1.10.12.3", "telesecPolicyQualifierID" }, - { "0.2.262.1.10.12.4", "telesecCRLFilteredExt" }, - { "0.2.262.1.10.12.5", "telesecCRLFilterExt"}, - { "0.2.262.1.10.12.6", "telesecNamingAuthorityExt" }, - - /* PKIX private extensions. */ - { "1.3.6.1.5.5.7.1.1", "authorityInfoAccess" }, - { "1.3.6.1.5.5.7.1.2", "biometricInfo" }, - { "1.3.6.1.5.5.7.1.3", "qcStatements" }, - { "1.3.6.1.5.5.7.1.4", "acAuditIdentity" }, - { "1.3.6.1.5.5.7.1.5", "acTargeting" }, - { "1.3.6.1.5.5.7.1.6", "acAaControls" }, - { "1.3.6.1.5.5.7.1.7", "sbgp-ipAddrBlock" }, - { "1.3.6.1.5.5.7.1.8", "sbgp-autonomousSysNum" }, - { "1.3.6.1.5.5.7.1.9", "sbgp-routerIdentifier" }, - { "1.3.6.1.5.5.7.1.10", "acProxying" }, - { "1.3.6.1.5.5.7.1.11", "subjectInfoAccess" }, - - /* X.509 id-ce */ - { "2.5.29.14", "subjectKeyIdentifier"}, - { "2.5.29.15", "keyUsage", 1 }, - { "2.5.29.16", "privateKeyUsagePeriod" }, - { "2.5.29.17", "subjectAltName", 1 }, - { "2.5.29.18", "issuerAltName", 1 }, - { "2.5.29.19", "basicConstraints", 1}, - { "2.5.29.20", "cRLNumber" }, - { "2.5.29.21", "cRLReason" }, - { "2.5.29.22", "expirationDate" }, - { "2.5.29.23", "instructionCode" }, - { "2.5.29.24", "invalidityDate" }, - { "2.5.29.27", "deltaCRLIndicator" }, - { "2.5.29.28", "issuingDistributionPoint" }, - { "2.5.29.29", "certificateIssuer" }, - { "2.5.29.30", "nameConstraints" }, - { "2.5.29.31", "cRLDistributionPoints", 1 }, - { "2.5.29.32", "certificatePolicies", 1 }, - { "2.5.29.32.0", "anyPolicy" }, - { "2.5.29.33", "policyMappings" }, - { "2.5.29.35", "authorityKeyIdentifier", 1 }, - { "2.5.29.36", "policyConstraints" }, - { "2.5.29.37", "extKeyUsage", 1 }, - { "2.5.29.46", "freshestCRL" }, - { "2.5.29.54", "inhibitAnyPolicy" }, - - /* Netscape certificate extensions. */ - { "2.16.840.1.113730.1.1", "netscape-cert-type" }, - { "2.16.840.1.113730.1.2", "netscape-base-url" }, - { "2.16.840.1.113730.1.3", "netscape-revocation-url" }, - { "2.16.840.1.113730.1.4", "netscape-ca-revocation-url" }, - { "2.16.840.1.113730.1.7", "netscape-cert-renewal-url" }, - { "2.16.840.1.113730.1.8", "netscape-ca-policy-url" }, - { "2.16.840.1.113730.1.9", "netscape-homePage-url" }, - { "2.16.840.1.113730.1.10", "netscape-entitylogo" }, - { "2.16.840.1.113730.1.11", "netscape-userPicture" }, - { "2.16.840.1.113730.1.12", "netscape-ssl-server-name" }, - { "2.16.840.1.113730.1.13", "netscape-comment" }, - - { NULL } -}; - - -/* Return the description for OID; if no description is available - NULL is returned. */ -static const char * -get_oid_desc (const char *oid, unsigned int *flag) -{ - int i; - - if (oid) - for (i=0; oidtranstbl[i].oid; i++) - if (!strcmp (oidtranstbl[i].oid, oid)) - { - if (flag) - *flag = oidtranstbl[i].flag; - return oidtranstbl[i].name; - } - if (flag) - *flag = 0; - return NULL; -} - - -static void -print_key_data (ksba_cert_t cert, FILE *fp) -{ -#if 0 - int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0; - int i; - - for(i=0; i < n; i++ ) - { - fprintf (fp, "pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) ); - mpi_print(stdout, pk->pkey[i], 1 ); - putchar(':'); - putchar('\n'); - } -#endif -} - -static void -print_capabilities (ksba_cert_t cert, FILE *fp) -{ - gpg_error_t err; - unsigned int use; - - err = ksba_cert_get_key_usage (cert, &use); - if (gpg_err_code (err) == GPG_ERR_NO_DATA) - { - putc ('e', fp); - putc ('s', fp); - putc ('c', fp); - putc ('E', fp); - putc ('S', fp); - putc ('C', fp); - return; - } - if (err) - { - log_error (_("error getting key usage information: %s\n"), - gpg_strerror (err)); - return; - } - - if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT))) - putc ('e', fp); - if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION))) - putc ('s', fp); - if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN)) - putc ('c', fp); - if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT))) - putc ('E', fp); - if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION))) - putc ('S', fp); - if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN)) - putc ('C', fp); -} - - -static void -print_time (gnupg_isotime_t t, FILE *fp) -{ - if (!t || !*t) - ; - else - fputs (t, fp); -} - - -/* return an allocated string with the email address extracted from a - DN */ -static char * -email_kludge (const char *name) -{ - const unsigned char *p; - unsigned char *buf; - int n; - - if (strncmp (name, "1.2.840.113549.1.9.1=#", 22)) - return NULL; - /* This looks pretty much like an email address in the subject's DN - we use this to add an additional user ID entry. This way, - openSSL generated keys get a nicer and usable listing */ - name += 22; - for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++) - ; - if (*p != '#' || !n) - return NULL; - buf = xtrymalloc (n+3); - if (!buf) - return NULL; /* oops, out of core */ - *buf = '<'; - for (n=1, p=name; *p != '#'; p +=2, n++) - buf[n] = xtoi_2 (p); - buf[n++] = '>'; - buf[n] = 0; - return buf; -} - - - - -/* List one certificate in colon mode */ -static void -list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, - FILE *fp, int have_secret) -{ - int rc; - int idx; - char truststring[2]; - char *p; - ksba_sexp_t sexp; - char *fpr; - ksba_isotime_t t; - gpg_error_t valerr; - int algo; - unsigned int nbits; - const char *chain_id; - char *chain_id_buffer = NULL; - int is_root = 0; - - if (ctrl->with_validation) - valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL, 0); - else - valerr = 0; - - - /* We need to get the fingerprint and the chaining ID in advance. */ - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - { - ksba_cert_t next; - - rc = gpgsm_walk_cert_chain (cert, &next); - if (!rc) /* We known the issuer's certificate. */ - { - p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1); - chain_id_buffer = p; - chain_id = chain_id_buffer; - ksba_cert_release (next); - } - else if (rc == -1) /* We have reached the root certificate. */ - { - chain_id = fpr; - is_root = 1; - } - else - chain_id = NULL; - } - - - fputs (have_secret? "crs:":"crt:", fp); - truststring[0] = 0; - truststring[1] = 0; - if ((validity & VALIDITY_REVOKED) - || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED) - *truststring = 'r'; - else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED) - *truststring = 'e'; - else if (valerr) - *truststring = 'i'; - else - { - /* Lets also check whether the certificate under question - expired. This is merely a hack until we found a proper way - to store the expiration flag in the keybox. */ - ksba_isotime_t current_time, not_after; - - gnupg_get_isotime (current_time); - if (!opt.ignore_expiration - && !ksba_cert_get_validity (cert, 1, not_after) - && *not_after && strcmp (current_time, not_after) > 0 ) - *truststring = 'e'; - } - - /* Is we have no truststring yet (i.e. the certificate might be - good) and this is a root certificate, we ask the agent whether - this is a trusted root certificate. */ - if (!*truststring && is_root) - { - rc = gpgsm_agent_istrusted (ctrl, cert); - if (!rc) - *truststring = 'u'; /* Yes, we trust this one (ultimately). */ - else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED) - *truststring = 'n'; /* No, we do not trust this one. */ - /* (in case of an error we can't tell anything.) */ - } - - if (*truststring) - fputs (truststring, fp); - - algo = gpgsm_get_key_algo_info (cert, &nbits); - fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24); - - /* We assume --fixed-list-mode for gpgsm */ - ksba_cert_get_validity (cert, 0, t); - print_time (t, fp); - putc (':', fp); - ksba_cert_get_validity (cert, 1, t); - print_time ( t, fp); - putc (':', fp); - /* Field 8, serial number: */ - if ((sexp = ksba_cert_get_serial (cert))) - { - int len; - const unsigned char *s = sexp; - - if (*s == '(') - { - s++; - for (len=0; *s && *s != ':' && digitp (s); s++) - len = len*10 + atoi_1 (s); - if (*s == ':') - for (s++; len; len--, s++) - fprintf (fp,"%02X", *s); - } - xfree (sexp); - } - putc (':', fp); - /* Field 9, ownertrust - not used here */ - putc (':', fp); - /* field 10, old user ID - we use it here for the issuer DN */ - if ((p = ksba_cert_get_issuer (cert,0))) - { - print_sanitized_string (fp, p, ':'); - xfree (p); - } - putc (':', fp); - /* Field 11, signature class - not used */ - putc (':', fp); - /* Field 12, capabilities: */ - print_capabilities (cert, fp); - putc (':', fp); - putc ('\n', fp); - - /* FPR record */ - fprintf (fp, "fpr:::::::::%s:::", fpr); - /* Print chaining ID (field 13)*/ - if (chain_id) - fputs (chain_id, fp); - putc (':', fp); - putc ('\n', fp); - xfree (fpr); fpr = NULL; chain_id = NULL; - xfree (chain_id_buffer); chain_id_buffer = NULL; - - if (opt.with_key_data) - { - if ( (p = gpgsm_get_keygrip_hexstring (cert))) - { - fprintf (fp, "grp:::::::::%s:\n", p); - xfree (p); - } - print_key_data (cert, fp); - } - - for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++) - { - fprintf (fp, "uid:%s::::::::", truststring); - print_sanitized_string (fp, p, ':'); - putc (':', fp); - putc (':', fp); - putc ('\n', fp); - if (!idx) - { - /* It would be better to get the faked email address from - the keydb. But as long as we don't have a way to pass - the meta data back, we just check it the same way as the - code used to create the keybox meta data does */ - char *pp = email_kludge (p); - if (pp) - { - fprintf (fp, "uid:%s::::::::", truststring); - print_sanitized_string (fp, pp, ':'); - putc (':', fp); - putc (':', fp); - putc ('\n', fp); - xfree (pp); - } - } - xfree (p); - } -} - - -static void -print_name_raw (FILE *fp, const char *string) -{ - if (!string) - fputs ("[error]", fp); - else - print_sanitized_string (fp, string, 0); -} - -static void -print_names_raw (FILE *fp, int indent, ksba_name_t name) -{ - int idx; - const char *s; - int indent_all; - - if ((indent_all = (indent < 0))) - indent = - indent; - - if (!name) - { - fputs ("none\n", fp); - return; - } - - for (idx=0; (s = ksba_name_enum (name, idx)); idx++) - { - char *p = ksba_name_get_uri (name, idx); - printf ("%*s%s\n", idx||indent_all?indent:0, "", p?p:s); - xfree (p); - } -} - - -/* List one certificate in raw mode useful to have a closer look at - the certificate. This one does not beautification and only minimal - output sanitation. It is mainly useful for debugging. */ -static void -list_cert_raw (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret, - int with_validation) -{ - gpg_error_t err; - size_t off, len; - ksba_sexp_t sexp; - char *dn; - ksba_isotime_t t; - int idx, i; - int is_ca, chainlen; - unsigned int kusage; - char *string, *p, *pend; - const char *oid, *s; - ksba_name_t name, name2; - unsigned int reason; - - sexp = ksba_cert_get_serial (cert); - fputs ("Serial number: ", fp); - gpgsm_print_serial (fp, sexp); - ksba_free (sexp); - putc ('\n', fp); - - dn = ksba_cert_get_issuer (cert, 0); - fputs (" Issuer: ", fp); - print_name_raw (fp, dn); - ksba_free (dn); - putc ('\n', fp); - for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++) - { - fputs (" aka: ", fp); - print_name_raw (fp, dn); - ksba_free (dn); - putc ('\n', fp); - } - - dn = ksba_cert_get_subject (cert, 0); - fputs (" Subject: ", fp); - print_name_raw (fp, dn); - ksba_free (dn); - putc ('\n', fp); - for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++) - { - fputs (" aka: ", fp); - print_name_raw (fp, dn); - ksba_free (dn); - putc ('\n', fp); - } - - dn = gpgsm_get_fingerprint_string (cert, 0); - fprintf (fp, " sha1_fpr: %s\n", dn?dn:"error"); - xfree (dn); - - dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5); - fprintf (fp, " md5_fpr: %s\n", dn?dn:"error"); - xfree (dn); - - ksba_cert_get_validity (cert, 0, t); - fputs (" notBefore: ", fp); - gpgsm_print_time (fp, t); - putc ('\n', fp); - fputs (" notAfter: ", fp); - ksba_cert_get_validity (cert, 1, t); - gpgsm_print_time (fp, t); - putc ('\n', fp); - - oid = ksba_cert_get_digest_algo (cert); - s = get_oid_desc (oid, NULL); - fprintf (fp, " hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":""); - - { - const char *algoname; - unsigned int nbits; - - algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits)); - fprintf (fp, " keyType: %u bit %s\n", nbits, algoname? algoname:"?"); - } - - /* authorityKeyIdentifier */ - fputs (" authKeyId: ", fp); - err = ksba_cert_get_auth_key_id (cert, NULL, &name, &sexp); - if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA) - { - if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name) - fputs ("[none]\n", fp); - else - { - gpgsm_print_serial (fp, sexp); - ksba_free (sexp); - putc ('\n', fp); - print_names_raw (fp, -15, name); - ksba_name_release (name); - } - } - else - fputs ("[?]\n", fp); - - fputs (" keyUsage:", fp); - err = ksba_cert_get_key_usage (cert, &kusage); - if (gpg_err_code (err) != GPG_ERR_NO_DATA) - { - if (err) - fprintf (fp, " [error: %s]", gpg_strerror (err)); - else - { - if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE)) - fputs (" digitalSignature", fp); - if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION)) - fputs (" nonRepudiation", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) - fputs (" keyEncipherment", fp); - if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT)) - fputs (" dataEncipherment", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT)) - fputs (" keyAgreement", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN)) - fputs (" certSign", fp); - if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN)) - fputs (" crlSign", fp); - if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY)) - fputs (" encipherOnly", fp); - if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY)) - fputs (" decipherOnly", fp); - } - putc ('\n', fp); - } - else - fputs ("[none]\n", fp); - - fputs (" extKeyUsage: ", fp); - err = ksba_cert_get_ext_key_usages (cert, &string); - if (gpg_err_code (err) != GPG_ERR_NO_DATA) - { - if (err) - fprintf (fp, "[error: %s]", gpg_strerror (err)); - else - { - p = string; - while (p && (pend=strchr (p, ':'))) - { - *pend++ = 0; - for (i=0; key_purpose_map[i].oid; i++) - if ( !strcmp (key_purpose_map[i].oid, p) ) - break; - fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp); - p = pend; - if (*p != 'C') - fputs (" (suggested)", fp); - if ((p = strchr (p, '\n'))) - { - p++; - fputs ("\n ", fp); - } - } - xfree (string); - } - putc ('\n', fp); - } - else - fputs ("[none]\n", fp); - - - fputs (" policies: ", fp); - err = ksba_cert_get_cert_policies (cert, &string); - if (gpg_err_code (err) != GPG_ERR_NO_DATA) - { - if (err) - fprintf (fp, "[error: %s]", gpg_strerror (err)); - else - { - p = string; - while (p && (pend=strchr (p, ':'))) - { - *pend++ = 0; - for (i=0; key_purpose_map[i].oid; i++) - if ( !strcmp (key_purpose_map[i].oid, p) ) - break; - fputs (p, fp); - p = pend; - if (*p == 'C') - fputs (" (critical)", fp); - if ((p = strchr (p, '\n'))) - { - p++; - fputs ("\n ", fp); - } - } - xfree (string); - } - putc ('\n', fp); - } - else - fputs ("[none]\n", fp); - - fputs (" chainLength: ", fp); - err = ksba_cert_is_ca (cert, &is_ca, &chainlen); - if (err || is_ca) - { - if (err) - fprintf (fp, "[error: %s]", gpg_strerror (err)); - else if (chainlen == -1) - fputs ("unlimited", fp); - else - fprintf (fp, "%d", chainlen); - putc ('\n', fp); - } - else - fputs ("not a CA\n", fp); - - - /* CRL distribution point */ - for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2, - &reason)) ;idx++) - { - fputs (" crlDP: ", fp); - print_names_raw (fp, 15, name); - if (reason) - { - fputs (" reason: ", fp); - if ( (reason & KSBA_CRLREASON_UNSPECIFIED)) - fputs (" unused", stdout); - if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE)) - fputs (" keyCompromise", stdout); - if ( (reason & KSBA_CRLREASON_CA_COMPROMISE)) - fputs (" caCompromise", stdout); - if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED)) - fputs (" affiliationChanged", stdout); - if ( (reason & KSBA_CRLREASON_SUPERSEDED)) - fputs (" superseded", stdout); - if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION)) - fputs (" cessationOfOperation", stdout); - if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD)) - fputs (" certificateHold", stdout); - putchar ('\n'); - } - fputs (" issuer: ", fp); - print_names_raw (fp, 23, name2); - ksba_name_release (name); - ksba_name_release (name2); - } - if (err && gpg_err_code (err) != GPG_ERR_EOF) - fputs (" crlDP: [error]\n", fp); - else if (!idx) - fputs (" crlDP: [none]\n", fp); - - - /* authorityInfoAccess. */ - for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string, - &name)); idx++) - { - fputs (" authInfo: ", fp); - s = get_oid_desc (string, NULL); - fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":""); - print_names_raw (fp, -15, name); - ksba_name_release (name); - ksba_free (string); - } - if (err && gpg_err_code (err) != GPG_ERR_EOF) - fputs (" authInfo: [error]\n", fp); - else if (!idx) - fputs (" authInfo: [none]\n", fp); - - /* subjectInfoAccess. */ - for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string, - &name)); idx++) - { - fputs (" subjectInfo: ", fp); - s = get_oid_desc (string, NULL); - fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":""); - print_names_raw (fp, -15, name); - ksba_name_release (name); - ksba_free (string); - } - if (err && gpg_err_code (err) != GPG_ERR_EOF) - fputs (" subjInfo: [error]\n", fp); - else if (!idx) - fputs (" subjInfo: [none]\n", fp); - - - for (idx=0; !(err=ksba_cert_get_extension (cert, idx, - &oid, &i, &off, &len));idx++) - { - unsigned int flag; - - s = get_oid_desc (oid, &flag); - - if (!(flag & 1)) - fprintf (fp, " %s: %s%s%s%s [%d octets]\n", - i? "critExtn":" extn", - oid, s?" (":"", s?s:"", s?")":"", (int)len); - } - - - if (with_validation) - { - err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0); - if (!err) - fprintf (fp, " [certificate is good]\n"); - else - fprintf (fp, " [certificate is bad: %s]\n", gpg_strerror (err)); - } -} - - - - -/* List one certificate in standard mode */ -static void -list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret, - int with_validation) -{ - gpg_error_t err; - ksba_sexp_t sexp; - char *dn; - ksba_isotime_t t; - int idx, i; - int is_ca, chainlen; - unsigned int kusage; - char *string, *p, *pend; - - sexp = ksba_cert_get_serial (cert); - fputs ("Serial number: ", fp); - gpgsm_print_serial (fp, sexp); - ksba_free (sexp); - putc ('\n', fp); - - dn = ksba_cert_get_issuer (cert, 0); - fputs (" Issuer: ", fp); - gpgsm_print_name (fp, dn); - ksba_free (dn); - putc ('\n', fp); - for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++) - { - fputs (" aka: ", fp); - gpgsm_print_name (fp, dn); - ksba_free (dn); - putc ('\n', fp); - } - - dn = ksba_cert_get_subject (cert, 0); - fputs (" Subject: ", fp); - gpgsm_print_name (fp, dn); - ksba_free (dn); - putc ('\n', fp); - for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++) - { - fputs (" aka: ", fp); - gpgsm_print_name (fp, dn); - ksba_free (dn); - putc ('\n', fp); - } - - ksba_cert_get_validity (cert, 0, t); - fputs (" validity: ", fp); - gpgsm_print_time (fp, t); - fputs (" through ", fp); - ksba_cert_get_validity (cert, 1, t); - gpgsm_print_time (fp, t); - putc ('\n', fp); - - - { - const char *algoname; - unsigned int nbits; - - algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits)); - fprintf (fp, " key type: %u bit %s\n", nbits, algoname? algoname:"?"); - } - - - err = ksba_cert_get_key_usage (cert, &kusage); - if (gpg_err_code (err) != GPG_ERR_NO_DATA) - { - fputs (" key usage:", fp); - if (err) - fprintf (fp, " [error: %s]", gpg_strerror (err)); - else - { - if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE)) - fputs (" digitalSignature", fp); - if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION)) - fputs (" nonRepudiation", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) - fputs (" keyEncipherment", fp); - if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT)) - fputs (" dataEncipherment", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT)) - fputs (" keyAgreement", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN)) - fputs (" certSign", fp); - if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN)) - fputs (" crlSign", fp); - if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY)) - fputs (" encipherOnly", fp); - if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY)) - fputs (" decipherOnly", fp); - } - putc ('\n', fp); - } - - err = ksba_cert_get_ext_key_usages (cert, &string); - if (gpg_err_code (err) != GPG_ERR_NO_DATA) - { - fputs ("ext key usage: ", fp); - if (err) - fprintf (fp, "[error: %s]", gpg_strerror (err)); - else - { - p = string; - while (p && (pend=strchr (p, ':'))) - { - *pend++ = 0; - for (i=0; key_purpose_map[i].oid; i++) - if ( !strcmp (key_purpose_map[i].oid, p) ) - break; - fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp); - p = pend; - if (*p != 'C') - fputs (" (suggested)", fp); - if ((p = strchr (p, '\n'))) - { - p++; - fputs (", ", fp); - } - } - xfree (string); - } - putc ('\n', fp); - } - - err = ksba_cert_get_cert_policies (cert, &string); - if (gpg_err_code (err) != GPG_ERR_NO_DATA) - { - fputs (" policies: ", fp); - if (err) - fprintf (fp, "[error: %s]", gpg_strerror (err)); - else - { - for (p=string; *p; p++) - { - if (*p == '\n') - *p = ','; - } - print_sanitized_string (fp, string, 0); - xfree (string); - } - putc ('\n', fp); - } - - err = ksba_cert_is_ca (cert, &is_ca, &chainlen); - if (err || is_ca) - { - fputs (" chain length: ", fp); - if (err) - fprintf (fp, "[error: %s]", gpg_strerror (err)); - else if (chainlen == -1) - fputs ("unlimited", fp); - else - fprintf (fp, "%d", chainlen); - putc ('\n', fp); - } - - if (opt.with_md5_fingerprint) - { - dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5); - fprintf (fp, " md5 fpr: %s\n", dn?dn:"error"); - xfree (dn); - } - - dn = gpgsm_get_fingerprint_string (cert, 0); - fprintf (fp, " fingerprint: %s\n", dn?dn:"error"); - xfree (dn); - - if (with_validation) - { - err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0); - if (!err) - fprintf (fp, " [certificate is good]\n"); - else - fprintf (fp, " [certificate is bad: %s]\n", gpg_strerror (err)); - } -} - - -/* Same as standard mode mode list all certifying certs too. */ -static void -list_cert_chain (ctrl_t ctrl, ksba_cert_t cert, int raw_mode, - FILE *fp, int with_validation) -{ - ksba_cert_t next = NULL; - - if (raw_mode) - list_cert_raw (ctrl, cert, fp, 0, with_validation); - else - list_cert_std (ctrl, cert, fp, 0, with_validation); - ksba_cert_ref (cert); - while (!gpgsm_walk_cert_chain (cert, &next)) - { - ksba_cert_release (cert); - fputs ("Certified by\n", fp); - if (raw_mode) - list_cert_raw (ctrl, next, fp, 0, with_validation); - else - list_cert_std (ctrl, next, fp, 0, with_validation); - cert = next; - } - ksba_cert_release (cert); - putc ('\n', fp); -} - - - -/* List all internal keys or just the keys given as NAMES. MODE is a - bit vector to specify what keys are to be included; see - gpgsm_list_keys (below) for details. If RAW_MODE is true, the raw - output mode will be used intead of the standard beautified one. - */ -static gpg_error_t -list_internal_keys (ctrl_t ctrl, STRLIST names, FILE *fp, - unsigned int mode, int raw_mode) -{ - KEYDB_HANDLE hd; - KEYDB_SEARCH_DESC *desc = NULL; - STRLIST sl; - int ndesc; - ksba_cert_t cert = NULL; - gpg_error_t rc = 0; - const char *lastresname, *resname; - int have_secret; - - hd = keydb_new (0); - if (!hd) - { - log_error ("keydb_new failed\n"); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - if (!names) - ndesc = 1; - else - { - for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) - ; - } - - desc = xtrycalloc (ndesc, sizeof *desc); - if (!ndesc) - { - rc = gpg_error_from_errno (errno); - log_error ("out of core\n"); - goto leave; - } - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_FIRST; - else - { - for (ndesc=0, sl=names; sl; sl = sl->next) - { - rc = keydb_classify_name (sl->d, desc+ndesc); - if (rc) - { - log_error ("key `%s' not found: %s\n", - sl->d, gpg_strerror (rc)); - rc = 0; - } - else - ndesc++; - } - - } - - /* It would be nice to see which of the given users did actually - match one in the keyring. To implement this we need to have a - found flag for each entry in desc and to set this we must check - all those entries after a match to mark all matched one - - currently we stop at the first match. To do this we need an - extra flag to enable this feature so */ - - lastresname = NULL; - while (!(rc = keydb_search (hd, desc, ndesc))) - { - unsigned int validity; - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - - rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity); - if (rc) - { - log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc)); - goto leave; - } - rc = keydb_get_cert (hd, &cert); - if (rc) - { - log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - resname = keydb_get_resource_name (hd); - - if (lastresname != resname ) - { - int i; - - if (ctrl->no_server) - { - fprintf (fp, "%s\n", resname ); - for (i=strlen(resname); i; i-- ) - putchar('-'); - putc ('\n', fp); - lastresname = resname; - } - } - - have_secret = 0; - if (mode) - { - char *p = gpgsm_get_keygrip_hexstring (cert); - if (p) - { - rc = gpgsm_agent_havekey (ctrl, p); - if (!rc) - have_secret = 1; - else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY) - goto leave; - rc = 0; - xfree (p); - } - } - - if (!mode - || ((mode & 1) && !have_secret) - || ((mode & 2) && have_secret) ) - { - if (ctrl->with_colons) - list_cert_colon (ctrl, cert, validity, fp, have_secret); - else if (ctrl->with_chain) - list_cert_chain (ctrl, cert, raw_mode, fp, ctrl->with_validation); - else - { - if (raw_mode) - list_cert_raw (ctrl, cert, fp, have_secret, - ctrl->with_validation); - else - list_cert_std (ctrl, cert, fp, have_secret, - ctrl->with_validation); - putc ('\n', fp); - } - } - ksba_cert_release (cert); - cert = NULL; - } - if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 ) - rc = 0; - if (rc) - log_error ("keydb_search failed: %s\n", gpg_strerror (rc)); - - leave: - ksba_cert_release (cert); - xfree (desc); - keydb_release (hd); - return rc; -} - - - -static void -list_external_cb (void *cb_value, ksba_cert_t cert) -{ - struct list_external_parm_s *parm = cb_value; - - if (keydb_store_cert (cert, 1, NULL)) - log_error ("error storing certificate as ephemeral\n"); - - if (parm->print_header) - { - const char *resname = "[external keys]"; - int i; - - fprintf (parm->fp, "%s\n", resname ); - for (i=strlen(resname); i; i-- ) - putchar('-'); - putc ('\n', parm->fp); - parm->print_header = 0; - } - - if (parm->with_colons) - list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0); - else if (parm->with_chain) - list_cert_chain (parm->ctrl, cert, parm->raw_mode, parm->fp, 0); - else - { - if (parm->raw_mode) - list_cert_raw (parm->ctrl, cert, parm->fp, 0, 0); - else - list_cert_std (parm->ctrl, cert, parm->fp, 0, 0); - putc ('\n', parm->fp); - } -} - - -/* List external keys similar to internal one. Note: mode does not - make sense here because it would be unwise to list external secret - keys */ -static gpg_error_t -list_external_keys (CTRL ctrl, STRLIST names, FILE *fp, int raw_mode) -{ - int rc; - struct list_external_parm_s parm; - - parm.fp = fp; - parm.ctrl = ctrl, - parm.print_header = ctrl->no_server; - parm.with_colons = ctrl->with_colons; - parm.with_chain = ctrl->with_chain; - parm.raw_mode = raw_mode; - - rc = gpgsm_dirmngr_lookup (ctrl, names, list_external_cb, &parm); - if (rc) - log_error ("listing external keys failed: %s\n", gpg_strerror (rc)); - return rc; -} - -/* List all keys or just the key given as NAMES. - MODE controls the operation mode: - Bit 0-2: - 0 = list all public keys but don't flag secret ones - 1 = list only public keys - 2 = list only secret keys - 3 = list secret and public keys - Bit 6: list internal keys - Bit 7: list external keys - Bit 8: Do a raw format dump. - */ -gpg_error_t -gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode) -{ - gpg_error_t err = 0; - - if ((mode & (1<<6))) - err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256)); - if (!err && (mode & (1<<7))) - err = list_external_keys (ctrl, names, fp, (mode&256)); - return err; -} diff --git a/sm/misc.c b/sm/misc.c deleted file mode 100644 index 281056177..000000000 --- a/sm/misc.c +++ /dev/null @@ -1,65 +0,0 @@ -/* misc.c - Miscellaneous fucntions - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif - -#include "gpgsm.h" - - -/* Setup the environment so that the pinentry is able to get all - required information. This is used prior to an exec of the - protect-tool. */ -void -setup_pinentry_env (void) -{ - char *lc; - - if (opt.display) - setenv ("DISPLAY", opt.display, 1); - if (opt.ttyname) - setenv ("GPG_TTY", opt.ttyname, 1); - if (opt.ttytype) - setenv ("TERM", opt.ttytype, 1); - - if (opt.lc_ctype) - setenv ("LC_CTYPE", opt.lc_ctype, 1); -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - else if ( (lc = setlocale (LC_CTYPE, "")) ) - setenv ("LC_CTYPE", lc, 1); -#endif - - if (opt.lc_messages) - setenv ("LC_MESSAGES", opt.lc_messages, 1); -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - else if ( (lc = setlocale (LC_MESSAGES, "")) ) - setenv ("LC_MESSAGES", lc, 1); -#endif - -} - diff --git a/sm/server.c b/sm/server.c deleted file mode 100644 index 72bf74afa..000000000 --- a/sm/server.c +++ /dev/null @@ -1,1121 +0,0 @@ -/* server.c - Server mode and main entry point - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <ctype.h> -#include <unistd.h> - -#include <assuan.h> - -#include "gpgsm.h" - -#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t)) - - -/* The filepointer for status message used in non-server mode */ -static FILE *statusfp; - -/* Data used to assuciate an Assuan context with local server data */ -struct server_local_s { - assuan_context_t assuan_ctx; - int message_fd; - int list_internal; - int list_external; - certlist_t recplist; - certlist_t signerlist; - certlist_t default_recplist; /* As set by main() - don't release. */ -}; - - - -/* Note that it is sufficient to allocate the target string D as - long as the source string S, i.e.: strlen(s)+1; */ -static void -strcpy_escaped_plus (char *d, const unsigned char *s) -{ - while (*s) - { - if (*s == '%' && s[1] && s[2]) - { - s++; - *d++ = xtoi_2 ( s); - s += 2; - } - else if (*s == '+') - *d++ = ' ', s++; - else - *d++ = *s++; - } - *d = 0; -} - - - - -/* Check whether the option NAME appears in LINE */ -static int -has_option (const char *line, const char *name) -{ - const char *s; - int n = strlen (name); - - s = strstr (line, name); - return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); -} - - -static void -close_message_fd (CTRL ctrl) -{ - if (ctrl->server_local->message_fd != -1) - { - close (ctrl->server_local->message_fd); - ctrl->server_local->message_fd = -1; - } -} - - -static int -option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - if (!strcmp (key, "include-certs")) - { - int i = *value? atoi (value) : -1; - if (ctrl->include_certs < -2) - return ASSUAN_Parameter_Error; - ctrl->include_certs = i; - } - else if (!strcmp (key, "display")) - { - if (opt.display) - free (opt.display); - opt.display = strdup (value); - if (!opt.display) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "ttyname")) - { - if (opt.ttyname) - free (opt.ttyname); - opt.ttyname = strdup (value); - if (!opt.ttyname) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "ttytype")) - { - if (opt.ttytype) - free (opt.ttytype); - opt.ttytype = strdup (value); - if (!opt.ttytype) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "lc-ctype")) - { - if (opt.lc_ctype) - free (opt.lc_ctype); - opt.lc_ctype = strdup (value); - if (!opt.lc_ctype) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "lc-messages")) - { - if (opt.lc_messages) - free (opt.lc_messages); - opt.lc_messages = strdup (value); - if (!opt.lc_messages) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "list-mode")) - { - int i = *value? atoi (value) : 0; - if (!i || i == 1) /* default and mode 1 */ - { - ctrl->server_local->list_internal = 1; - ctrl->server_local->list_external = 0; - } - else if (i == 2) - { - ctrl->server_local->list_internal = 0; - ctrl->server_local->list_external = 1; - } - else if (i == 3) - { - ctrl->server_local->list_internal = 1; - ctrl->server_local->list_external = 1; - } - else - return ASSUAN_Parameter_Error; - } - else if (!strcmp (key, "with-validation")) - { - int i = *value? atoi (value) : 0; - ctrl->with_validation = i; - } - else - return ASSUAN_Invalid_Option; - - return 0; -} - - - - -static void -reset_notify (ASSUAN_CONTEXT ctx) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - gpgsm_release_certlist (ctrl->server_local->recplist); - gpgsm_release_certlist (ctrl->server_local->signerlist); - ctrl->server_local->recplist = NULL; - ctrl->server_local->signerlist = NULL; - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); -} - - -static void -input_notify (ASSUAN_CONTEXT ctx, const char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - ctrl->autodetect_encoding = 0; - ctrl->is_pem = 0; - ctrl->is_base64 = 0; - if (strstr (line, "--armor")) - ctrl->is_pem = 1; - else if (strstr (line, "--base64")) - ctrl->is_base64 = 1; - else if (strstr (line, "--binary")) - ; - else - ctrl->autodetect_encoding = 1; -} - -static void -output_notify (ASSUAN_CONTEXT ctx, const char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - ctrl->create_pem = 0; - ctrl->create_base64 = 0; - if (strstr (line, "--armor")) - ctrl->create_pem = 1; - else if (strstr (line, "--base64")) - ctrl->create_base64 = 1; /* just the raw output */ -} - - - -/* RECIPIENT <userID> - - Set the recipient for the encryption. <userID> should be the - internal representation of the key; the server may accept any other - way of specification [we will support this]. If this is a valid and - trusted recipient the server does respond with OK, otherwise the - return is an ERR with the reason why the recipient can't be used, - the encryption will then not be done for this recipient. If the - policy is not to encrypt at all if not all recipients are valid, the - client has to take care of this. All RECIPIENT commands are - cumulative until a RESET or an successful ENCRYPT command. */ -static int -cmd_recipient (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - - rc = gpgsm_add_to_certlist (ctrl, line, 0, &ctrl->server_local->recplist, 0); - if (rc) - { - gpg_err_code_t r = gpg_err_code (rc); - gpgsm_status2 (ctrl, STATUS_INV_RECP, - r == -1? "1": - r == GPG_ERR_NO_PUBKEY? "1": - r == GPG_ERR_AMBIGUOUS_NAME? "2": - r == GPG_ERR_WRONG_KEY_USAGE? "3": - r == GPG_ERR_CERT_REVOKED? "4": - r == GPG_ERR_CERT_EXPIRED? "5": - r == GPG_ERR_NO_CRL_KNOWN? "6": - r == GPG_ERR_CRL_TOO_OLD? "7": - r == GPG_ERR_NO_POLICY_MATCH? "8": - "0", - line, NULL); - } - - return map_to_assuan_status (rc); -} - -/* SIGNER <userID> - - Set the signer's keys for the signature creation. <userID> should - be the internal representation of the key; the server may accept any - other way of specification [we will support this]. If this is a - valid and usable signing key the server does respond with OK, - otherwise it returns an ERR with the reason why the key can't be - used, the signing will then not be done for this key. If the policy - is not to sign at all if not all signer keys are valid, the client - has to take care of this. All SIGNER commands are cumulative until - a RESET but they are *not* reset by an SIGN command becuase it can - be expected that set of signers are used for more than one sign - operation. - - Note that this command returns an INV_RECP status which is a bit - strange, but they are very similar. */ -static int -cmd_signer (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - - rc = gpgsm_add_to_certlist (ctrl, line, 1, - &ctrl->server_local->signerlist, 0); - if (rc) - { - gpg_err_code_t r = gpg_err_code (rc); - gpgsm_status2 (ctrl, STATUS_INV_RECP, - r == -1? "1": - r == GPG_ERR_NO_PUBKEY? "1": - r == GPG_ERR_AMBIGUOUS_NAME? "2": - r == GPG_ERR_WRONG_KEY_USAGE? "3": - r == GPG_ERR_CERT_REVOKED? "4": - r == GPG_ERR_CERT_EXPIRED? "5": - r == GPG_ERR_NO_CRL_KNOWN? "6": - r == GPG_ERR_CRL_TOO_OLD? "7": - r == GPG_ERR_NO_POLICY_MATCH? "8": - r == GPG_ERR_NO_SECKEY? "9": - "0", - line, NULL); - } - return map_to_assuan_status (rc); -} - - -/* ENCRYPT - - Do the actual encryption process. Takes the plaintext from the INPUT - command, writes to the ciphertext to the file descriptor set with - the OUTPUT command, take the recipients form all the recipients set - so far. If this command fails the clients should try to delete all - output currently done or otherwise mark it as invalid. GPGSM does - ensure that there won't be any security problem with leftover data - on the output in this case. - - This command should in general not fail, as all necessary checks - have been done while setting the recipients. The input and output - pipes are closed. */ -static int -cmd_encrypt (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - certlist_t cl; - int inp_fd, out_fd; - FILE *out_fp; - int rc; - - inp_fd = assuan_get_input_fd (ctx); - if (inp_fd == -1) - return set_error (No_Input, NULL); - out_fd = assuan_get_output_fd (ctx); - if (out_fd == -1) - return set_error (No_Output, NULL); - - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - - /* Now add all encrypt-to marked recipients from the default - list. */ - rc = 0; - if (!opt.no_encrypt_to) - { - for (cl=ctrl->server_local->recplist; !rc && cl; cl = cl->next) - if (cl->is_encrypt_to) - rc = gpgsm_add_cert_to_certlist (ctrl, cl->cert, - &ctrl->server_local->recplist, 1); - } - if (!rc) - rc = gpgsm_encrypt (assuan_get_pointer (ctx), - ctrl->server_local->recplist, - inp_fd, out_fp); - fclose (out_fp); - - gpgsm_release_certlist (ctrl->server_local->recplist); - ctrl->server_local->recplist = NULL; - /* Close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - return map_to_assuan_status (rc); -} - -/* DECRYPT - - This performs the decrypt operation after doing some check on the - internal state. (e.g. that only needed data has been set). Because - it utilizes the GPG-Agent for the session key decryption, there is - no need to ask the client for a protecting passphrase - GpgAgent - does take care of this by requesting this from the user. */ -static int -cmd_decrypt (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; - FILE *out_fp; - int rc; - - inp_fd = assuan_get_input_fd (ctx); - if (inp_fd == -1) - return set_error (No_Input, NULL); - out_fd = assuan_get_output_fd (ctx); - if (out_fd == -1) - return set_error (No_Output, NULL); - - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - rc = gpgsm_decrypt (ctrl, inp_fd, out_fp); - fclose (out_fp); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - -/* VERIFY - - This does a verify operation on the message send to the input-FD. - The result is written out using status lines. If an output FD was - given, the signed text will be written to that. - - If the signature is a detached one, the server will inquire about - the signed material and the client must provide it. - */ -static int -cmd_verify (ASSUAN_CONTEXT ctx, char *line) -{ - int rc; - CTRL ctrl = assuan_get_pointer (ctx); - int fd = assuan_get_input_fd (ctx); - int out_fd = assuan_get_output_fd (ctx); - FILE *out_fp = NULL; - - if (fd == -1) - return set_error (No_Input, NULL); - - if (out_fd != -1) - { - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - } - - rc = gpgsm_verify (assuan_get_pointer (ctx), fd, - ctrl->server_local->message_fd, out_fp); - if (out_fp) - fclose (out_fp); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - -/* SIGN [--detached] - - Sign the data set with the INPUT command and write it to the sink - set by OUTPUT. With "--detached" specified, a detached signature is - created (surprise). */ -static int -cmd_sign (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; - FILE *out_fp; - int detached; - int rc; - - inp_fd = assuan_get_input_fd (ctx); - if (inp_fd == -1) - return set_error (No_Input, NULL); - out_fd = assuan_get_output_fd (ctx); - if (out_fd == -1) - return set_error (No_Output, NULL); - - detached = has_option (line, "--detached"); - - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - - rc = gpgsm_sign (assuan_get_pointer (ctx), ctrl->server_local->signerlist, - inp_fd, detached, out_fp); - fclose (out_fp); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - -/* IMPORT - - Import the certificates read form the input-fd, return status - message for each imported one. The import checks the validity of - the certificate but not of the entire chain. It is possible to - import expired certificates. */ -static int -cmd_import (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - int fd = assuan_get_input_fd (ctx); - - if (fd == -1) - return set_error (No_Input, NULL); - - rc = gpgsm_import (assuan_get_pointer (ctx), fd); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - -static int -cmd_export (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int fd = assuan_get_output_fd (ctx); - FILE *out_fp; - char *p; - STRLIST list, sl; - - if (fd == -1) - return set_error (No_Output, NULL); - - /* break the line down into an STRLIST */ - list = NULL; - for (p=line; *p; line = p) - { - while (*p && *p != ' ') - p++; - if (*p) - *p++ = 0; - if (*line) - { - sl = xtrymalloc (sizeof *sl + strlen (line)); - if (!sl) - { - free_strlist (list); - return ASSUAN_Out_Of_Core; - } - sl->flags = 0; - strcpy_escaped_plus (sl->d, line); - sl->next = list; - list = sl; - } - } - - out_fp = fdopen ( dup(fd), "w"); - if (!out_fp) - { - free_strlist (list); - return set_error (General_Error, "fdopen() failed"); - } - - gpgsm_export (ctrl, list, out_fp); - fclose (out_fp); - free_strlist (list); - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - return 0; -} - - -static int -cmd_delkeys (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - char *p; - STRLIST list, sl; - int rc; - - /* break the line down into an STRLIST */ - list = NULL; - for (p=line; *p; line = p) - { - while (*p && *p != ' ') - p++; - if (*p) - *p++ = 0; - if (*line) - { - sl = xtrymalloc (sizeof *sl + strlen (line)); - if (!sl) - { - free_strlist (list); - return ASSUAN_Out_Of_Core; - } - sl->flags = 0; - strcpy_escaped_plus (sl->d, line); - sl->next = list; - list = sl; - } - } - - rc = gpgsm_delete (ctrl, list); - free_strlist (list); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - - -/* MESSAGE FD=<n> - - Set the file descriptor to read a message which is used with - detached signatures */ -static int -cmd_message (ASSUAN_CONTEXT ctx, char *line) -{ - char *endp; - int fd; - CTRL ctrl = assuan_get_pointer (ctx); - - if (strncmp (line, "FD=", 3)) - return set_error (Syntax_Error, "FD=<n> expected"); - line += 3; - if (!digitp (line)) - return set_error (Syntax_Error, "number required"); - fd = strtoul (line, &endp, 10); - if (*endp) - return set_error (Syntax_Error, "garbage found"); - if (fd == -1) - return set_error (No_Input, NULL); - - ctrl->server_local->message_fd = fd; - return 0; -} - - -static int -do_listkeys (ASSUAN_CONTEXT ctx, char *line, int mode) -{ - CTRL ctrl = assuan_get_pointer (ctx); - FILE *fp = assuan_get_data_fp (ctx); - char *p; - STRLIST list, sl; - unsigned int listmode; - gpg_error_t err; - - if (!fp) - return set_error (General_Error, "no data stream"); - - /* break the line down into an STRLIST */ - list = NULL; - for (p=line; *p; line = p) - { - while (*p && *p != ' ') - p++; - if (*p) - *p++ = 0; - if (*line) - { - sl = xtrymalloc (sizeof *sl + strlen (line)); - if (!sl) - { - free_strlist (list); - return ASSUAN_Out_Of_Core; - } - sl->flags = 0; - strcpy_escaped_plus (sl->d, line); - sl->next = list; - list = sl; - } - } - - ctrl->with_colons = 1; - listmode = mode; - if (ctrl->server_local->list_internal) - listmode |= (1<<6); - if (ctrl->server_local->list_external) - listmode |= (1<<7); - err = gpgsm_list_keys (assuan_get_pointer (ctx), list, fp, listmode); - free_strlist (list); - return map_to_assuan_status (err); -} - -static int -cmd_listkeys (ASSUAN_CONTEXT ctx, char *line) -{ - return do_listkeys (ctx, line, 3); -} - -static int -cmd_listsecretkeys (ASSUAN_CONTEXT ctx, char *line) -{ - return do_listkeys (ctx, line, 2); -} - - -/* GENKEY - - Read the parameters in native format from the input fd and write a - certificate request to the output. - */ -static int -cmd_genkey (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; - FILE *out_fp; - int rc; - - inp_fd = assuan_get_input_fd (ctx); - if (inp_fd == -1) - return set_error (No_Input, NULL); - out_fd = assuan_get_output_fd (ctx); - if (out_fd == -1) - return set_error (No_Output, NULL); - - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - rc = gpgsm_genkey (ctrl, inp_fd, out_fp); - fclose (out_fp); - - /* close and reset the fds */ - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - - - - -/* Tell the assuan library about our commands */ -static int -register_commands (ASSUAN_CONTEXT ctx) -{ - static struct { - const char *name; - int (*handler)(ASSUAN_CONTEXT, char *line); - } table[] = { - { "RECIPIENT", cmd_recipient }, - { "SIGNER", cmd_signer }, - { "ENCRYPT", cmd_encrypt }, - { "DECRYPT", cmd_decrypt }, - { "VERIFY", cmd_verify }, - { "SIGN", cmd_sign }, - { "IMPORT", cmd_import }, - { "EXPORT", cmd_export }, - { "INPUT", NULL }, - { "OUTPUT", NULL }, - { "MESSAGE", cmd_message }, - { "LISTKEYS", cmd_listkeys }, - { "LISTSECRETKEYS",cmd_listsecretkeys }, - { "GENKEY", cmd_genkey }, - { "DELKEYS", cmd_delkeys }, - { NULL } - }; - int i, rc; - - for (i=0; table[i].name; i++) - { - rc = assuan_register_command (ctx, table[i].name, table[i].handler); - if (rc) - return rc; - } - return 0; -} - -/* Startup the server. DEFAULT_RECPLIST is the list of recipients as - set from the command line or config file. We only require those - marked as encrypt-to. */ -void -gpgsm_server (certlist_t default_recplist) -{ - int rc; - int filedes[2]; - ASSUAN_CONTEXT ctx; - struct server_control_s ctrl; - static const char hello[] = ("GNU Privacy Guard's S/M server " - VERSION " ready"); - - memset (&ctrl, 0, sizeof ctrl); - gpgsm_init_default_ctrl (&ctrl); - - /* For now we use a simple pipe based server so that we can work - from scripts. We will later add options to run as a daemon and - wait for requests on a Unix domain socket */ - filedes[0] = 0; - filedes[1] = 1; - rc = assuan_init_pipe_server (&ctx, filedes); - if (rc) - { - log_error ("failed to initialize the server: %s\n", - assuan_strerror(rc)); - gpgsm_exit (2); - } - rc = register_commands (ctx); - if (rc) - { - log_error ("failed to the register commands with Assuan: %s\n", - assuan_strerror(rc)); - gpgsm_exit (2); - } - if (opt.verbose || opt.debug) - { - char *tmp = NULL; - const char *s1 = getenv ("GPG_AGENT_INFO"); - const char *s2 = getenv ("DIRMNGR_INFO"); - - if (asprintf (&tmp, - "Home: %s\n" - "Config: %s\n" - "AgentInfo: %s\n" - "DirmngrInfo: %s\n" - "%s", - opt.homedir, - opt.config_filename, - s1?s1:"[not set]", - s2?s2:"[not set]", - hello) > 0) - { - assuan_set_hello_line (ctx, tmp); - free (tmp); - } - } - else - assuan_set_hello_line (ctx, hello); - - assuan_register_reset_notify (ctx, reset_notify); - assuan_register_input_notify (ctx, input_notify); - assuan_register_output_notify (ctx, output_notify); - assuan_register_option_handler (ctx, option_handler); - - assuan_set_pointer (ctx, &ctrl); - ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local); - ctrl.server_local->assuan_ctx = ctx; - ctrl.server_local->message_fd = -1; - ctrl.server_local->list_internal = 1; - ctrl.server_local->list_external = 0; - ctrl.server_local->default_recplist = default_recplist; - - if (DBG_ASSUAN) - assuan_set_log_stream (ctx, log_get_stream ()); - - for (;;) - { - rc = assuan_accept (ctx); - if (rc == -1) - { - break; - } - else if (rc) - { - log_info ("Assuan accept problem: %s\n", assuan_strerror (rc)); - break; - } - - rc = assuan_process (ctx); - if (rc) - { - log_info ("Assuan processing failed: %s\n", assuan_strerror (rc)); - continue; - } - } - - gpgsm_release_certlist (ctrl.server_local->recplist); - ctrl.server_local->recplist = NULL; - gpgsm_release_certlist (ctrl.server_local->signerlist); - ctrl.server_local->signerlist = NULL; - - assuan_deinit_server (ctx); -} - - -static const char * -get_status_string ( int no ) -{ - const char *s; - - switch (no) - { - case STATUS_ENTER : s = "ENTER"; break; - case STATUS_LEAVE : s = "LEAVE"; break; - case STATUS_ABORT : s = "ABORT"; break; - case STATUS_NEWSIG : s = "NEWSIG"; break; - case STATUS_GOODSIG: s = "GOODSIG"; break; - case STATUS_SIGEXPIRED: s = "SIGEXPIRED"; break; - case STATUS_KEYREVOKED: s = "KEYREVOKED"; break; - case STATUS_BADSIG : s = "BADSIG"; break; - case STATUS_ERRSIG : s = "ERRSIG"; break; - case STATUS_BADARMOR : s = "BADARMOR"; break; - case STATUS_RSA_OR_IDEA : s= "RSA_OR_IDEA"; break; - case STATUS_TRUST_UNDEFINED: s = "TRUST_UNDEFINED"; break; - case STATUS_TRUST_NEVER : s = "TRUST_NEVER"; break; - case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL"; break; - case STATUS_TRUST_FULLY : s = "TRUST_FULLY"; break; - case STATUS_TRUST_ULTIMATE : s = "TRUST_ULTIMATE"; break; - case STATUS_GET_BOOL : s = "GET_BOOL"; break; - case STATUS_GET_LINE : s = "GET_LINE"; break; - case STATUS_GET_HIDDEN : s = "GET_HIDDEN"; break; - case STATUS_GOT_IT : s = "GOT_IT"; break; - case STATUS_SHM_INFO : s = "SHM_INFO"; break; - case STATUS_SHM_GET : s = "SHM_GET"; break; - case STATUS_SHM_GET_BOOL : s = "SHM_GET_BOOL"; break; - case STATUS_SHM_GET_HIDDEN : s = "SHM_GET_HIDDEN"; break; - case STATUS_NEED_PASSPHRASE: s = "NEED_PASSPHRASE"; break; - case STATUS_VALIDSIG : s = "VALIDSIG"; break; - case STATUS_SIG_ID : s = "SIG_ID"; break; - case STATUS_ENC_TO : s = "ENC_TO"; break; - case STATUS_NODATA : s = "NODATA"; break; - case STATUS_BAD_PASSPHRASE : s = "BAD_PASSPHRASE"; break; - case STATUS_NO_PUBKEY : s = "NO_PUBKEY"; break; - case STATUS_NO_SECKEY : s = "NO_SECKEY"; break; - case STATUS_NEED_PASSPHRASE_SYM: s = "NEED_PASSPHRASE_SYM"; break; - case STATUS_DECRYPTION_FAILED: s = "DECRYPTION_FAILED"; break; - case STATUS_DECRYPTION_OKAY: s = "DECRYPTION_OKAY"; break; - case STATUS_MISSING_PASSPHRASE: s = "MISSING_PASSPHRASE"; break; - case STATUS_GOOD_PASSPHRASE : s = "GOOD_PASSPHRASE"; break; - case STATUS_GOODMDC : s = "GOODMDC"; break; - case STATUS_BADMDC : s = "BADMDC"; break; - case STATUS_ERRMDC : s = "ERRMDC"; break; - case STATUS_IMPORTED : s = "IMPORTED"; break; - case STATUS_IMPORT_OK : s = "IMPORT_OK"; break; - case STATUS_IMPORT_RES : s = "IMPORT_RES"; break; - case STATUS_FILE_START : s = "FILE_START"; break; - case STATUS_FILE_DONE : s = "FILE_DONE"; break; - case STATUS_FILE_ERROR : s = "FILE_ERROR"; break; - case STATUS_BEGIN_DECRYPTION:s = "BEGIN_DECRYPTION"; break; - case STATUS_END_DECRYPTION : s = "END_DECRYPTION"; break; - case STATUS_BEGIN_ENCRYPTION:s = "BEGIN_ENCRYPTION"; break; - case STATUS_END_ENCRYPTION : s = "END_ENCRYPTION"; break; - case STATUS_DELETE_PROBLEM : s = "DELETE_PROBLEM"; break; - case STATUS_PROGRESS : s = "PROGRESS"; break; - case STATUS_SIG_CREATED : s = "SIG_CREATED"; break; - case STATUS_SESSION_KEY : s = "SESSION_KEY"; break; - case STATUS_NOTATION_NAME : s = "NOTATION_NAME" ; break; - case STATUS_NOTATION_DATA : s = "NOTATION_DATA" ; break; - case STATUS_POLICY_URL : s = "POLICY_URL" ; break; - case STATUS_BEGIN_STREAM : s = "BEGIN_STREAM"; break; - case STATUS_END_STREAM : s = "END_STREAM"; break; - case STATUS_KEY_CREATED : s = "KEY_CREATED"; break; - case STATUS_UNEXPECTED : s = "UNEXPECTED"; break; - case STATUS_INV_RECP : s = "INV_RECP"; break; - case STATUS_NO_RECP : s = "NO_RECP"; break; - case STATUS_ALREADY_SIGNED : s = "ALREADY_SIGNED"; break; - case STATUS_EXPSIG : s = "EXPSIG"; break; - case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break; - case STATUS_TRUNCATED : s = "TRUNCATED"; break; - case STATUS_ERROR : s = "ERROR"; break; - case STATUS_IMPORT_PROBLEM : s = "IMPORT_PROBLEM"; break; - default: s = "?"; break; - } - return s; -} - - -void -gpgsm_status2 (CTRL ctrl, int no, ...) -{ - va_list arg_ptr; - const char *text; - - va_start (arg_ptr, no); - - if (ctrl->no_server) - { - if (ctrl->status_fd == -1) - return; /* no status wanted */ - if (!statusfp) - { - if (ctrl->status_fd == 1) - statusfp = stdout; - else if (ctrl->status_fd == 2) - statusfp = stderr; - else - statusfp = fdopen (ctrl->status_fd, "w"); - - if (!statusfp) - { - log_fatal ("can't open fd %d for status output: %s\n", - ctrl->status_fd, strerror(errno)); - } - } - - fputs ("[GNUPG:] ", statusfp); - fputs (get_status_string (no), statusfp); - - while ( (text = va_arg (arg_ptr, const char*) )) - { - putc ( ' ', statusfp ); - for (; *text; text++) - { - if (*text == '\n') - fputs ( "\\n", statusfp ); - else if (*text == '\r') - fputs ( "\\r", statusfp ); - else - putc ( *(const byte *)text, statusfp ); - } - } - putc ('\n', statusfp); - fflush (statusfp); - } - else - { - ASSUAN_CONTEXT ctx = ctrl->server_local->assuan_ctx; - char buf[950], *p; - size_t n; - - p = buf; - n = 0; - while ( (text = va_arg (arg_ptr, const char *)) ) - { - if (n) - { - *p++ = ' '; - n++; - } - for ( ; *text && n < DIM (buf)-2; n++) - *p++ = *text++; - } - *p = 0; - assuan_write_status (ctx, get_status_string (no), buf); - } - - va_end (arg_ptr); -} - -void -gpgsm_status (CTRL ctrl, int no, const char *text) -{ - gpgsm_status2 (ctrl, no, text, NULL); -} - -void -gpgsm_status_with_err_code (CTRL ctrl, int no, const char *text, - gpg_err_code_t ec) -{ - char buf[30]; - - sprintf (buf, "%u", (unsigned int)ec); - if (text) - gpgsm_status2 (ctrl, no, text, buf, NULL); - else - gpgsm_status2 (ctrl, no, buf, NULL); -} - -#if 0 -/* - * Write a status line with a buffer using %XX escapes. If WRAP is > - * 0 wrap the line after this length. If STRING is not NULL it will - * be prepended to the buffer, no escaping is done for string. - * A wrap of -1 forces spaces not to be encoded as %20. - */ -void -write_status_text_and_buffer ( int no, const char *string, - const char *buffer, size_t len, int wrap ) -{ - const char *s, *text; - int esc, first; - int lower_limit = ' '; - size_t n, count, dowrap; - - if( !statusfp ) - return; /* not enabled */ - - if (wrap == -1) { - lower_limit--; - wrap = 0; - } - - text = get_status_string (no); - count = dowrap = first = 1; - do { - if (dowrap) { - fprintf (statusfp, "[GNUPG:] %s ", text ); - count = dowrap = 0; - if (first && string) { - fputs (string, statusfp); - count += strlen (string); - } - first = 0; - } - for (esc=0, s=buffer, n=len; n && !esc; s++, n-- ) { - if ( *s == '%' || *(const byte*)s <= lower_limit - || *(const byte*)s == 127 ) - esc = 1; - if ( wrap && ++count > wrap ) { - dowrap=1; - break; - } - } - if (esc) { - s--; n++; - } - if (s != buffer) - fwrite (buffer, s-buffer, 1, statusfp ); - if ( esc ) { - fprintf (statusfp, "%%%02X", *(const byte*)s ); - s++; n--; - } - buffer = s; - len = n; - if ( dowrap && len ) - putc ( '\n', statusfp ); - } while ( len ); - - putc ('\n',statusfp); - fflush (statusfp); -} -#endif diff --git a/sm/sign.c b/sm/sign.c deleted file mode 100644 index 5deef6088..000000000 --- a/sm/sign.c +++ /dev/null @@ -1,666 +0,0 @@ -/* sign.c - Sign a message - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - - -static void -hash_data (int fd, gcry_md_hd_t md) -{ - FILE *fp; - char buffer[4096]; - int nread; - - fp = fdopen ( dup (fd), "rb"); - if (!fp) - { - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - return; - } - - do - { - nread = fread (buffer, 1, DIM(buffer), fp); - gcry_md_write (md, buffer, nread); - } - while (nread); - if (ferror (fp)) - log_error ("read error on fd %d: %s\n", fd, strerror (errno)); - fclose (fp); -} - -static int -hash_and_copy_data (int fd, gcry_md_hd_t md, ksba_writer_t writer) -{ - gpg_error_t err; - FILE *fp; - char buffer[4096]; - int nread; - int rc = 0; - int any = 0; - - fp = fdopen ( dup (fd), "rb"); - if (!fp) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - return tmperr; - } - - do - { - nread = fread (buffer, 1, DIM(buffer), fp); - if (nread) - { - any = 1; - gcry_md_write (md, buffer, nread); - err = ksba_writer_write_octet_string (writer, buffer, nread, 0); - if (err) - { - log_error ("write failed: %s\n", gpg_strerror (err)); - rc = err; - } - } - } - while (nread && !rc); - if (ferror (fp)) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("read error on fd %d: %s\n", fd, strerror (errno)); - } - fclose (fp); - if (!any) - { - /* We can't allow to sign an empty message because it does not - make much sense and more seriously, ksba-cms_build has - already written the tag for data and now expects an octet - string but an octet string of zeize 0 is illegal. */ - log_error ("cannot sign an empty message\n"); - rc = gpg_error (GPG_ERR_NO_DATA); - } - if (!rc) - { - err = ksba_writer_write_octet_string (writer, NULL, 0, 1); - if (err) - { - log_error ("write failed: %s\n", gpg_strerror (err)); - rc = err; - } - } - - return rc; -} - - -/* Get the default certificate which is defined as the first one our - keyDB returns and has a secret key available. */ -int -gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert) -{ - KEYDB_HANDLE hd; - ksba_cert_t cert = NULL; - int rc; - char *p; - - hd = keydb_new (0); - if (!hd) - return gpg_error (GPG_ERR_GENERAL); - rc = keydb_search_first (hd); - if (rc) - { - keydb_release (hd); - return rc; - } - - do - { - rc = keydb_get_cert (hd, &cert); - if (rc) - { - log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc)); - keydb_release (hd); - return rc; - } - - p = gpgsm_get_keygrip_hexstring (cert); - if (p) - { - if (!gpgsm_agent_havekey (ctrl, p)) - { - xfree (p); - keydb_release (hd); - *r_cert = cert; - return 0; /* got it */ - } - xfree (p); - } - - ksba_cert_release (cert); - cert = NULL; - } - while (!(rc = keydb_search_next (hd))); - if (rc && rc != -1) - log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc)); - - ksba_cert_release (cert); - keydb_release (hd); - return rc; -} - - -static ksba_cert_t -get_default_signer (ctrl_t ctrl) -{ - KEYDB_SEARCH_DESC desc; - ksba_cert_t cert = NULL; - KEYDB_HANDLE kh = NULL; - int rc; - - if (!opt.local_user) - { - rc = gpgsm_get_default_cert (ctrl, &cert); - if (rc) - { - if (rc != -1) - log_debug ("failed to find default certificate: %s\n", - gpg_strerror (rc)); - return NULL; - } - return cert; - } - - rc = keydb_classify_name (opt.local_user, &desc); - if (rc) - { - log_error ("failed to find default signer: %s\n", gpg_strerror (rc)); - return NULL; - } - - kh = keydb_new (0); - if (!kh) - return NULL; - - rc = keydb_search (kh, &desc, 1); - if (rc) - { - log_debug ("failed to find default certificate: rc=%d\n", rc); - } - else - { - rc = keydb_get_cert (kh, &cert); - if (rc) - { - log_debug ("failed to get cert: rc=%d\n", rc); - } - } - - keydb_release (kh); - return cert; -} - -/* Depending on the options in CTRL add the certificate CERT as well as - other certificate up in the chain to the Root-CA to the CMS - object. */ -static int -add_certificate_list (CTRL ctrl, ksba_cms_t cms, ksba_cert_t cert) -{ - gpg_error_t err; - int rc = 0; - ksba_cert_t next = NULL; - int n; - int not_root = 0; - - ksba_cert_ref (cert); - - n = ctrl->include_certs; - log_debug ("adding certificates at level %d\n", n); - if (n == -2) - { - not_root = 1; - n = -1; - } - if (n < 0 || n > 50) - n = 50; /* We better apply an upper bound */ - - /* First add my own certificate unless we don't want any certificate - included at all. */ - if (n) - { - if (not_root && gpgsm_is_root_cert (cert)) - err = 0; - else - err = ksba_cms_add_cert (cms, cert); - if (err) - goto ksba_failure; - if (n>0) - n--; - } - /* Walk the chain to include all other certificates. Note that a -1 - used for N makes sure that there is no limit and all certs get - included. */ - while ( n-- && !(rc = gpgsm_walk_cert_chain (cert, &next)) ) - { - if (not_root && gpgsm_is_root_cert (next)) - err = 0; - else - err = ksba_cms_add_cert (cms, next); - ksba_cert_release (cert); - cert = next; next = NULL; - if (err) - goto ksba_failure; - } - ksba_cert_release (cert); - - return rc == -1? 0: rc; - - ksba_failure: - ksba_cert_release (cert); - log_error ("ksba_cms_add_cert failed: %s\n", gpg_strerror (err)); - return err; -} - - - - -/* Perform a sign operation. - - Sign the data received on DATA-FD in embedded mode or in detached - mode when DETACHED is true. Write the signature to OUT_FP. The - keys used to sign are taken from SIGNERLIST or the default one will - be used if the value of this argument is NULL. */ -int -gpgsm_sign (CTRL ctrl, CERTLIST signerlist, - int data_fd, int detached, FILE *out_fp) -{ - int i, rc; - gpg_error_t err; - Base64Context b64writer = NULL; - ksba_writer_t writer; - ksba_cms_t cms = NULL; - ksba_stop_reason_t stopreason; - KEYDB_HANDLE kh = NULL; - gcry_md_hd_t data_md = NULL; - int signer; - const char *algoid; - int algo; - ksba_isotime_t signed_at; - CERTLIST cl; - int release_signerlist = 0; - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - ctrl->pem_name = "SIGNED MESSAGE"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - - err = ksba_cms_new (&cms); - if (err) - { - rc = err; - goto leave; - } - - err = ksba_cms_set_reader_writer (cms, NULL, writer); - if (err) - { - log_debug ("ksba_cms_set_reader_writer failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - /* We are going to create signed data with data as encap. content */ - err = ksba_cms_set_content_type (cms, 0, KSBA_CT_SIGNED_DATA); - if (!err) - err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA); - if (err) - { - log_debug ("ksba_cms_set_content_type failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - /* If no list of signers is given, use a default one. */ - if (!signerlist) - { - ksba_cert_t cert = get_default_signer (ctrl); - if (!cert) - { - log_error ("no default signer found\n"); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - /* Although we don't check for ambigious specification we will - check that the signer's certificate is is usable and - valid. */ - rc = gpgsm_cert_use_sign_p (cert); - if (!rc) - rc = gpgsm_validate_chain (ctrl, cert, NULL, 0, NULL, 0); - if (rc) - goto leave; - - /* That one is fine - create signerlist. */ - signerlist = xtrycalloc (1, sizeof *signerlist); - if (!signerlist) - { - rc = OUT_OF_CORE (errno); - ksba_cert_release (cert); - goto leave; - } - signerlist->cert = cert; - release_signerlist = 1; - } - - - /* Gather certificates of signers and store them in the CMS object. */ - for (cl=signerlist; cl; cl = cl->next) - { - rc = gpgsm_cert_use_sign_p (cl->cert); - if (rc) - goto leave; - - err = ksba_cms_add_signer (cms, cl->cert); - if (err) - { - log_error ("ksba_cms_add_signer failed: %s\n", gpg_strerror (err)); - rc = err; - goto leave; - } - rc = add_certificate_list (ctrl, cms, cl->cert); - if (rc) - { - log_error ("failed to store list of certificates: %s\n", - gpg_strerror(rc)); - goto leave; - } - /* Set the hash algorithm we are going to use */ - err = ksba_cms_add_digest_algo (cms, "1.3.14.3.2.26" /*SHA-1*/); - if (err) - { - log_debug ("ksba_cms_add_digest_algo failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - - /* Prepare hashing (actually we are figuring out what we have set above)*/ - rc = gcry_md_open (&data_md, 0, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if (DBG_HASHING) - gcry_md_start_debug (data_md, "sign.data"); - - for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++) - { - algo = gcry_md_map_name (algoid); - if (!algo) - { - log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?"); - rc = gpg_error (GPG_ERR_BUG); - goto leave; - } - gcry_md_enable (data_md, algo); - } - - if (detached) - { /* we hash the data right now so that we can store the message - digest. ksba_cms_build() takes this as an flag that detached - data is expected. */ - unsigned char *digest; - size_t digest_len; - /* Fixme do this for all signers and get the algo to use from - the signer's certificate - does not make mich sense, but we - should do this consistent as we have already done it above. */ - algo = GCRY_MD_SHA1; - hash_data (data_fd, data_md); - digest = gcry_md_read (data_md, algo); - digest_len = gcry_md_get_algo_dlen (algo); - if ( !digest || !digest_len) - { - log_error ("problem getting the hash of the data\n"); - rc = gpg_error (GPG_ERR_BUG); - goto leave; - } - for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) - { - err = ksba_cms_set_message_digest (cms, signer, digest, digest_len); - if (err) - { - log_error ("ksba_cms_set_message_digest failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - } - - gnupg_get_isotime (signed_at); - for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) - { - err = ksba_cms_set_signing_time (cms, signer, signed_at); - if (err) - { - log_error ("ksba_cms_set_signing_time failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - - /* We need to write at least a minimal list of our capabilities to - try to convince some MUAs to use 3DEs and not the crippled - RC2. Our list is: - - aes128-CBC - des-EDE3-CBC - */ - err = ksba_cms_add_smime_capability (cms, "2.16.840.1.101.3.4.1.2", NULL, 0); - if (!err) - err = ksba_cms_add_smime_capability (cms, "1.2.840.113549.3.7", NULL, 0); - if (err) - { - log_error ("ksba_cms_add_smime_capability failed: %s\n", - gpg_strerror (err)); - goto leave; - } - - - /* Main building loop. */ - do - { - err = ksba_cms_build (cms, &stopreason); - if (err) - { - log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err)); - rc = err; - goto leave; - } - - if (stopreason == KSBA_SR_BEGIN_DATA) - { /* hash the data and store the message digest */ - unsigned char *digest; - size_t digest_len; - - assert (!detached); - /* Fixme: get the algo to use from the signer's certificate - - does not make much sense, but we should do this - consistent as we have already done it above. Code is - mostly duplicated above. */ - - algo = GCRY_MD_SHA1; - rc = hash_and_copy_data (data_fd, data_md, writer); - if (rc) - goto leave; - digest = gcry_md_read (data_md, algo); - digest_len = gcry_md_get_algo_dlen (algo); - if ( !digest || !digest_len) - { - log_error ("problem getting the hash of the data\n"); - rc = gpg_error (GPG_ERR_BUG); - goto leave; - } - for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) - { - err = ksba_cms_set_message_digest (cms, signer, - digest, digest_len); - if (err) - { - log_error ("ksba_cms_set_message_digest failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - } - else if (stopreason == KSBA_SR_NEED_SIG) - { /* calculate the signature for all signers */ - gcry_md_hd_t md; - - algo = GCRY_MD_SHA1; - rc = gcry_md_open (&md, algo, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if (DBG_HASHING) - gcry_md_start_debug (md, "sign.attr"); - ksba_cms_set_hash_function (cms, HASH_FNC, md); - for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) - { - char *sigval = NULL; - char *buf, *fpr; - - if (signer) - gcry_md_reset (md); - rc = ksba_cms_hash_signed_attrs (cms, signer); - if (rc) - { - log_debug ("hashing signed attrs failed: %s\n", - gpg_strerror (rc)); - gcry_md_close (md); - goto leave; - } - - rc = gpgsm_create_cms_signature (ctrl, cl->cert, - md, algo, &sigval); - if (rc) - { - gcry_md_close (md); - goto leave; - } - - err = ksba_cms_set_sig_val (cms, signer, sigval); - xfree (sigval); - if (err) - { - log_error ("failed to store the signature: %s\n", - gpg_strerror (err)); - rc = err; - gcry_md_close (md); - goto leave; - } - - /* write a status message */ - fpr = gpgsm_get_fingerprint_hexstring (cl->cert, GCRY_MD_SHA1); - if (!fpr) - { - rc = gpg_error (GPG_ERR_ENOMEM); - gcry_md_close (md); - goto leave; - } - { - int pkalgo = gpgsm_get_key_algo_info (cl->cert, NULL); - rc = asprintf (&buf, "%c %d %d 00 %s %s", - detached? 'D':'S', - pkalgo, - algo, - signed_at, - fpr); - } - xfree (fpr); - if (rc < 0) - { - rc = gpg_error (GPG_ERR_ENOMEM); - gcry_md_close (md); - goto leave; - } - rc = 0; - gpgsm_status (ctrl, STATUS_SIG_CREATED, buf); - free (buf); /* yes, we must use the regular free() here */ - } - gcry_md_close (md); - - } - } - while (stopreason != KSBA_SR_READY); - - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - log_info ("signature created\n"); - - - leave: - if (rc) - log_error ("error creating signature: %s <%s>\n", - gpg_strerror (rc), gpg_strsource (rc) ); - if (release_signerlist) - gpgsm_release_certlist (signerlist); - ksba_cms_release (cms); - gpgsm_destroy_writer (b64writer); - keydb_release (kh); - gcry_md_close (data_md); - return rc; -} diff --git a/sm/verify.c b/sm/verify.c deleted file mode 100644 index 410e86de7..000000000 --- a/sm/verify.c +++ /dev/null @@ -1,540 +0,0 @@ -/* verify.c - Verify a messages signature - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - -static char * -strtimestamp_r (ksba_isotime_t atime) -{ - char *buffer = xmalloc (15); - - if (!atime || !*atime) - strcpy (buffer, "none"); - else - sprintf (buffer, "%.4s-%.2s-%.2s", atime, atime+4, atime+6); - return buffer; -} - - - -/* Hash the data for a detached signature */ -static void -hash_data (int fd, gcry_md_hd_t md) -{ - FILE *fp; - char buffer[4096]; - int nread; - - fp = fdopen ( dup (fd), "rb"); - if (!fp) - { - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - return; - } - - do - { - nread = fread (buffer, 1, DIM(buffer), fp); - gcry_md_write (md, buffer, nread); - } - while (nread); - if (ferror (fp)) - log_error ("read error on fd %d: %s\n", fd, strerror (errno)); - fclose (fp); -} - - - - -/* Perform a verify operation. To verify detached signatures, data_fd - must be different than -1. With OUT_FP given and a non-detached - signature, the signed material is written to that stream. */ -int -gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) -{ - int i, rc; - Base64Context b64reader = NULL; - Base64Context b64writer = NULL; - ksba_reader_t reader; - ksba_writer_t writer = NULL; - ksba_cms_t cms = NULL; - ksba_stop_reason_t stopreason; - ksba_cert_t cert; - KEYDB_HANDLE kh; - gcry_md_hd_t data_md = NULL; - int signer; - const char *algoid; - int algo; - int is_detached; - FILE *fp = NULL; - char *p; - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - - fp = fdopen ( dup (in_fd), "rb"); - if (!fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("fdopen() failed: %s\n", strerror (errno)); - goto leave; - } - - rc = gpgsm_create_reader (&b64reader, ctrl, fp, 0, &reader); - if (rc) - { - log_error ("can't create reader: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (out_fp) - { - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - } - - rc = ksba_cms_new (&cms); - if (rc) - goto leave; - - rc = ksba_cms_set_reader_writer (cms, reader, writer); - if (rc) - { - log_error ("ksba_cms_set_reader_writer failed: %s\n", - gpg_strerror (rc)); - goto leave; - } - - rc = gcry_md_open (&data_md, 0, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if (DBG_HASHING) - gcry_md_start_debug (data_md, "vrfy.data"); - - is_detached = 0; - do - { - rc = ksba_cms_parse (cms, &stopreason); - if (rc) - { - log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (stopreason == KSBA_SR_NEED_HASH) - { - is_detached = 1; - if (opt.verbose) - log_info ("detached signature\n"); - } - - if (stopreason == KSBA_SR_NEED_HASH - || stopreason == KSBA_SR_BEGIN_DATA) - { /* We are now able to enable the hash algorithms */ - for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++) - { - algo = gcry_md_map_name (algoid); - if (!algo) - log_error ("unknown hash algorithm `%s'\n", - algoid? algoid:"?"); - else - gcry_md_enable (data_md, algo); - } - if (is_detached) - { - if (data_fd == -1) - log_info ("detached signature w/o data " - "- assuming certs-only\n"); - else - hash_data (data_fd, data_md); - } - else - { - ksba_cms_set_hash_function (cms, HASH_FNC, data_md); - } - } - else if (stopreason == KSBA_SR_END_DATA) - { /* The data bas been hashed */ - - } - } - while (stopreason != KSBA_SR_READY); - - if (b64writer) - { - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - } - - if (data_fd != -1 && !is_detached) - { - log_error ("data given for a non-detached signature\n"); - rc = gpg_error (GPG_ERR_CONFLICT); - goto leave; - } - - for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++) - { - /* Fixme: it might be better to check the validity of the - certificate first before entering it into the DB. This way - we would avoid cluttering the DB with invalid - certificates. */ - keydb_store_cert (cert, 0, NULL); - ksba_cert_release (cert); - } - - cert = NULL; - for (signer=0; ; signer++) - { - char *issuer = NULL; - ksba_sexp_t sigval = NULL; - ksba_isotime_t sigtime, keyexptime; - ksba_sexp_t serial; - char *msgdigest = NULL; - size_t msgdigestlen; - char *ctattr; - - rc = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial); - if (!signer && gpg_err_code (rc) == GPG_ERR_NO_DATA - && data_fd == -1 && is_detached) - { - log_info ("certs-only message accepted\n"); - rc = 0; - break; - } - if (rc) - { - if (signer && rc == -1) - rc = 0; - break; - } - - gpgsm_status (ctrl, STATUS_NEWSIG, NULL); - - if (DBG_X509) - { - log_debug ("signer %d - issuer: `%s'\n", - signer, issuer? issuer:"[NONE]"); - log_debug ("signer %d - serial: ", signer); - gpgsm_dump_serial (serial); - log_printf ("\n"); - } - - rc = ksba_cms_get_signing_time (cms, signer, sigtime); - if (gpg_err_code (rc) == GPG_ERR_NO_DATA) - *sigtime = 0; - else if (rc) - { - log_error ("error getting signing time: %s\n", gpg_strerror (rc)); - *sigtime = 0; /* (we can't encode an error in the time string.) */ - } - - rc = ksba_cms_get_message_digest (cms, signer, - &msgdigest, &msgdigestlen); - if (!rc) - { - size_t is_enabled; - - algoid = ksba_cms_get_digest_algo (cms, signer); - algo = gcry_md_map_name (algoid); - if (DBG_X509) - log_debug ("signer %d - digest algo: %d\n", signer, algo); - is_enabled = sizeof algo; - if ( gcry_md_info (data_md, GCRYCTL_IS_ALGO_ENABLED, - &algo, &is_enabled) - || !is_enabled) - { - log_error ("digest algo %d has not been enabled\n", algo); - goto next_signer; - } - } - else if (gpg_err_code (rc) == GPG_ERR_NO_DATA) - { - assert (!msgdigest); - rc = 0; - algoid = NULL; - algo = 0; - } - else /* real error */ - break; - - rc = ksba_cms_get_sigattr_oids (cms, signer, - "1.2.840.113549.1.9.3", &ctattr); - if (!rc) - { - const char *s; - - if (DBG_X509) - log_debug ("signer %d - content-type attribute: %s", - signer, ctattr); - - s = ksba_cms_get_content_oid (cms, 1); - if (!s || strcmp (ctattr, s)) - { - log_error ("content-type attribute does not match " - "actual content-type\n"); - ksba_free (ctattr); - ctattr = NULL; - goto next_signer; - } - ksba_free (ctattr); - ctattr = NULL; - } - else if (rc != -1) - { - log_error ("error getting content-type attribute: %s\n", - gpg_strerror (rc)); - goto next_signer; - } - rc = 0; - - - sigval = ksba_cms_get_sig_val (cms, signer); - if (!sigval) - { - log_error ("no signature value available\n"); - goto next_signer; - } - if (DBG_X509) - log_debug ("signer %d - signature available", signer); - - /* Find the certificate of the signer */ - keydb_search_reset (kh); - rc = keydb_search_issuer_sn (kh, issuer, serial); - if (rc) - { - if (rc == -1) - { - log_error ("certificate not found\n"); - rc = gpg_error (GPG_ERR_NO_PUBKEY); - } - else - log_error ("failed to find the certificate: %s\n", - gpg_strerror(rc)); - { - char numbuf[50]; - sprintf (numbuf, "%d", rc); - - gpgsm_status2 (ctrl, STATUS_ERROR, "verify.findkey", - numbuf, NULL); - } - /* fixme: we might want to append the issuer and serial - using our standard notation */ - goto next_signer; - } - - rc = keydb_get_cert (kh, &cert); - if (rc) - { - log_error ("failed to get cert: %s\n", gpg_strerror (rc)); - goto next_signer; - } - - log_info (_("Signature made ")); - if (*sigtime) - gpgsm_dump_time (sigtime); - else - log_printf (_("[date not given]")); - log_printf (_(" using certificate ID %08lX\n"), - gpgsm_get_short_fingerprint (cert)); - - - if (msgdigest) - { /* Signed attributes are available. */ - gcry_md_hd_t md; - unsigned char *s; - - /* check that the message digest in the signed attributes - matches the one we calculated on the data */ - s = gcry_md_read (data_md, algo); - if ( !s || !msgdigestlen - || gcry_md_get_algo_dlen (algo) != msgdigestlen - || !s || memcmp (s, msgdigest, msgdigestlen) ) - { - char *fpr; - - log_error ("invalid signature: message digest attribute " - "does not match calculated one\n"); - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - gpgsm_status (ctrl, STATUS_BADSIG, fpr); - xfree (fpr); - goto next_signer; - } - - rc = gcry_md_open (&md, algo, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - goto next_signer; - } - if (DBG_HASHING) - gcry_md_start_debug (md, "vrfy.attr"); - - ksba_cms_set_hash_function (cms, HASH_FNC, md); - rc = ksba_cms_hash_signed_attrs (cms, signer); - if (rc) - { - log_error ("hashing signed attrs failed: %s\n", - gpg_strerror (rc)); - gcry_md_close (md); - goto next_signer; - } - rc = gpgsm_check_cms_signature (cert, sigval, md, algo); - gcry_md_close (md); - } - else - { - rc = gpgsm_check_cms_signature (cert, sigval, data_md, algo); - } - - if (rc) - { - char *fpr; - - log_error ("invalid signature: %s\n", gpg_strerror (rc)); - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - gpgsm_status (ctrl, STATUS_BADSIG, fpr); - xfree (fpr); - goto next_signer; - } - rc = gpgsm_cert_use_verify_p (cert); /*(this displays an info message)*/ - if (rc) - { - gpgsm_status_with_err_code (ctrl, STATUS_ERROR, "verify.keyusage", - gpg_err_code (rc)); - rc = 0; - } - - if (DBG_X509) - log_debug ("signature okay - checking certs\n"); - rc = gpgsm_validate_chain (ctrl, cert, keyexptime, 0, NULL, 0); - if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED) - { - gpgsm_status (ctrl, STATUS_EXPKEYSIG, NULL); - rc = 0; - } - else - gpgsm_status (ctrl, STATUS_GOODSIG, NULL); - - { - char *buf, *fpr, *tstr; - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - tstr = strtimestamp_r (sigtime); - buf = xmalloc ( strlen(fpr) + strlen (tstr) + 120); - sprintf (buf, "%s %s %s %s", fpr, tstr, - *sigtime? sigtime : "0", - *keyexptime? keyexptime : "0" ); - xfree (tstr); - xfree (fpr); - gpgsm_status (ctrl, STATUS_VALIDSIG, buf); - xfree (buf); - } - - if (rc) /* of validate_chain */ - { - log_error ("invalid certification chain: %s\n", gpg_strerror (rc)); - if (gpg_err_code (rc) == GPG_ERR_BAD_CERT_CHAIN - || gpg_err_code (rc) == GPG_ERR_BAD_CERT - || gpg_err_code (rc) == GPG_ERR_BAD_CA_CERT - || gpg_err_code (rc) == GPG_ERR_CERT_REVOKED) - gpgsm_status_with_err_code (ctrl, STATUS_TRUST_NEVER, NULL, - gpg_err_code (rc)); - else - gpgsm_status_with_err_code (ctrl, STATUS_TRUST_UNDEFINED, NULL, - gpg_err_code (rc)); - goto next_signer; - } - - for (i=0; (p = ksba_cert_get_subject (cert, i)); i++) - { - log_info (!i? _("Good signature from") - : _(" aka")); - log_printf (" \""); - gpgsm_print_name (log_get_stream (), p); - log_printf ("\"\n"); - ksba_free (p); - } - - gpgsm_status (ctrl, STATUS_TRUST_FULLY, NULL); - - - next_signer: - rc = 0; - xfree (issuer); - xfree (serial); - xfree (sigval); - xfree (msgdigest); - ksba_cert_release (cert); - cert = NULL; - } - rc = 0; - - leave: - ksba_cms_release (cms); - gpgsm_destroy_reader (b64reader); - gpgsm_destroy_writer (b64writer); - keydb_release (kh); - gcry_md_close (data_md); - if (fp) - fclose (fp); - - if (rc) - { - char numbuf[50]; - sprintf (numbuf, "%d", rc ); - gpgsm_status2 (ctrl, STATUS_ERROR, "verify.leave", - numbuf, NULL); - } - - return rc; -} - diff --git a/tests/567064FE6D14A17B2D811ABB407728BC558AA455 b/tests/567064FE6D14A17B2D811ABB407728BC558AA455 deleted file mode 100644 index cf0535ff7..000000000 --- a/tests/567064FE6D14A17B2D811ABB407728BC558AA455 +++ /dev/null @@ -1,18 +0,0 @@ -(private-key - (oid.1.2.840.113549.1.1.1 - (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#) - (e #010001#) - (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B117D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BDC543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#) - (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#) - (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f935a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#) - (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891eebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#) - ) -) - - - - - - - - diff --git a/tests/ChangeLog b/tests/ChangeLog deleted file mode 100644 index 68f9b4e21..000000000 --- a/tests/ChangeLog +++ /dev/null @@ -1,73 +0,0 @@ -2004-02-20 Werner Koch <wk@gnupg.org> - - * Makefile.am: Reset GPG_AGENT_INFO here - * runtest: and not anymore here. - -2002-12-04 Werner Koch <wk@gnupg.org> - - * inittests (gpgsm.conf): Fake system time. - -2002-10-31 Neal H. Walfield <neal@g10code.de> - - * Makefile.am (inittests.stamp): Do not set LD_LIBRARY_PATH here. - (TESTS_ENVIRONMENT): Do it here. And also frob $(LIBGCRYPT_LIBS) - and $(PTH_LIBS). - -2002-10-31 Neal H. Walfield <neal@g10code.de> - - * asschk.c (die): New macro. - (read_assuan): If in verbose mode, dump the string that was read. - (write_assuan): Be more verbose on failure. - -2002-09-04 Neal H. Walfield <neal@g10code.de> - - * Makefile.am (inittests.stamp): Do not set LD_LIBRARY_PATH, but - rather prepend it. Be more robust and prefer printf over echo -n. - -2002-09-04 Marcus Brinkmann <marcus@g10code.de> - - * asschk.c (start_server): Close the parent's file descriptors in - the child. - (read_assuan): Variable NREAD removed. Cut off the received line - currectly if more than one line was read. - -2002-09-03 Neal H. Walfield <neal@g10code.de> - - * Makefile.am (inittests.stamp): Construct an LD_LIBRARY_PATH from - LDFLAGS. - -2002-08-09 Werner Koch <wk@gnupg.org> - - * asschk.c (cmd_getenv): New. - (expand_line): Allow / as variable name delimiter. - * sm-sign+verify, sm-verify: Use $srcdir so that a VPATH build works. - - * Makefile.am: Fixes for make dist. - * samplekets/Makefile.am: New. - -2002-08-08 Werner Koch <wk@gnupg.org> - - * asschk.c: Added some new features. - * runtest, inittests: New. - * text-1.txt, text-2.txt, text-3.txt: New. - * text-1.osig.pem, text-1.dsig.pem, text-1.osig-bad.pem: New. - * text-2.osig.pem, text-2.osig-bad.pem: New. - * samplekeys : New directory - * sm-verify, sm-sign+verify: The first test scripts. - -2002-08-06 Werner Koch <wk@gnupg.org> - - * Makefile.am, asschk.c: New. - - - Copyright 2002 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. - - diff --git a/tests/Makefile.am b/tests/Makefile.am deleted file mode 100644 index 791829a07..000000000 --- a/tests/Makefile.am +++ /dev/null @@ -1,77 +0,0 @@ -# Makefile.am -tests makefile for libxtime -# Copyright (C) 2002 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -GPGSM = ../sm/gpgsm - -TESTS_ENVIRONMENT = GNUPGHOME=`pwd` GPG_AGENT_INFO= LC_ALL=C GPGSM=$(GPGSM) \ - LD_LIBRARY_PATH=$$(seen=0; \ - for i in $(LDFLAGS) $(LIBGCRYPT_LIBS) $(PTH_LIBS); \ - do \ - if echo "$$i" | egrep '^-L' >/dev/null 2>&1; \ - then \ - if test $$seen = 0; \ - then \ - seen=1; \ - else \ - printf ":"; \ - fi; \ - printf "%s" "$${i}" | sed 's/^-L//'; \ - fi; \ - done; \ - if test $$seen != 0 \ - && test x$${LD_LIBRARY_PATH} != x; \ - then \ - printf ":"; \ - fi; \ - printf "%s" "$${LD_LIBRARY_PATH}") $(srcdir)/runtest - -testscripts = sm-sign+verify sm-verify - -EXTRA_DIST = runtest inittests $(testscripts) \ - text-1.txt text-2.txt text-3.txt \ - text-1.osig.pem text-1.dsig.pem text-1.osig-bad.pem \ - text-2.osig.pem text-2.osig-bad.pem \ - samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key \ - samplekeys/cert_g10code_pete1.pem \ - samplekeys/cert_g10code_test1.pem \ - samplekeys/cert_g10code_theo1.pem - -TESTS = $(testscripts) - -CLEANFILES = inittests.stamp x y y z out err - *.lock .\#lk* - -DISTCLEANFILES = pubring.kbx~ random_seed - -noinst_PROGRAMS = asschk - -asschk_SOURCES = asschk.c - - -all-local: inittests.stamp - -clean-local: - srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests --clean - -inittests.stamp: inittests - srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests - echo timestamp >./inittests.stamp - diff --git a/tests/asschk.c b/tests/asschk.c deleted file mode 100644 index 83a8ca5af..000000000 --- a/tests/asschk.c +++ /dev/null @@ -1,1059 +0,0 @@ -/* asschk.c - Assuan Server Checker - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* This is a simple stand-alone Assuan server test program. We don't - want to use the assuan library because we don't want to hide errors - in that library. - - The script language is line based. Empty lines or lines containing - only white spaces are ignored, line with a hash sign as first non - white space character are treated as comments. - - A simple macro mechanism is implemnted. Macros are expanded before - a line is processed but after comment processing. Macros are only - expanded once and non existing macros expand to the empty string. - A macro is dereferenced by prefixing its name with a dollar sign; - the end of the name is currently indicated by a white space, a - dollar sign or a slash. To use a dollor sign verbatim, double it. - - A macro is assigned by prefixing a statement with the macro name - and an equal sign. The value is assigned verbatim if it does not - resemble a command, otherwise the return value of the command will - get assigned. The command "let" may be used to assign values - unambigiously and it should be used if the value starts with a - letter. - - Conditions are not yes implemented except for a simple evaluation - which yields false for an empty string or the string "0". The - result may be negated by prefixing with a '!'. - - The general syntax of a command is: - - [<name> =] <statement> [<args>] - - If NAME is not specifed but the statement returns a value it is - assigned to the name "?" so that it can be referenced using "$?". - The following commands are implemented: - - let <value> - Return VALUE. - - echo <value> - Print VALUE. - - openfile <filename> - Open file FILENAME for read access and retrun the file descriptor. - - createfile <filename> - Create file FILENAME, open for write access and retrun the file - descriptor. - - pipeserver <program> - Connect to the Assuan server PROGRAM. - - send <line> - Send LINE to the server. - - expect-ok - Expect an OK response from the server. Status and data out put - is ignored. - - expect-err - Expect an ERR response from the server. Status and data out put - is ignored. - - count-status <code> - Initialize the assigned variable to 0 and assign it as an counter for - status code CODE. This command must be called with an assignment. - - quit - Terminate the process. - - quit-if <condition> - Terminate the process if CONDITION evaluates to true. - - fail-if <condition> - Terminate the process with an exit code of 1 if CONDITION - evaluates to true. - - cmpfiles <first> <second> - Returns true when the content of the files FIRST and SECOND match. - - getenv <name> - Return the value of the environment variable NAME. - -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <stdarg.h> -#include <assert.h> -#include <unistd.h> -#include <fcntl.h> - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) -# define ATTR_PRINTF(f,a) __attribute__ ((format (printf,f,a))) -#else -# define ATTR_PRINTF(f,a) -#endif - -#define spacep(p) (*(p) == ' ' || *(p) == '\t') - -#define MAX_LINELEN 2048 - -typedef enum { - LINE_OK = 0, - LINE_ERR, - LINE_STAT, - LINE_DATA, - LINE_END, -} LINETYPE; - -typedef enum { - VARTYPE_SIMPLE = 0, - VARTYPE_FD, - VARTYPE_COUNTER -} VARTYPE; - - -struct variable_s { - struct variable_s *next; - VARTYPE type; - unsigned int count; - char *value; - char name[1]; -}; -typedef struct variable_s *VARIABLE; - - -static void die (const char *format, ...) ATTR_PRINTF(1,2); - - -/* Name of this program to be printed in error messages. */ -static const char *invocation_name; - -/* Talk a bit about what is going on. */ -static int opt_verbose; - -/* Option to ignore the echo command. */ -static int opt_no_echo; - -/* File descriptors used to communicate with the current server. */ -static int server_send_fd = -1; -static int server_recv_fd = -1; - -/* The Assuan protocol limits the line length to 1024, so we can - safely use a (larger) buffer. The buffer is filled using the - read_assuan(). */ -static char recv_line[MAX_LINELEN]; -/* Tell the status of the current line. */ -static LINETYPE recv_type; - -/* This is our variable storage. */ -static VARIABLE variable_list; - - -static void -die (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", invocation_name); - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - putc ('\n', stderr); - - exit (1); -} - -#define die(format, args...) (die) ("%s: " format, __FUNCTION__ , ##args) - -static void -err (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", invocation_name); - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - putc ('\n', stderr); -} - -static void * -xmalloc (size_t n) -{ - void *p = malloc (n); - if (!p) - die ("out of core"); - return p; -} - -static void * -xcalloc (size_t n, size_t m) -{ - void *p = calloc (n, m); - if (!p) - die ("out of core"); - return p; -} - -static char * -xstrdup (const char *s) -{ - char *p = xmalloc (strlen (s)+1); - strcpy (p, s); - return p; -} - - -/* Write LENGTH bytes from BUFFER to FD. */ -static int -writen (int fd, const char *buffer, size_t length) -{ - while (length) - { - int nwritten = write (fd, buffer, length); - - if (nwritten < 0) - { - if (errno == EINTR) - continue; - return -1; /* write error */ - } - length -= nwritten; - buffer += nwritten; - } - return 0; /* okay */ -} - - - - -/* Assuan specific stuff. */ - -/* Read a line from FD, store it in the global recv_line, analyze the - type and store that in recv_type. The function terminates on a - communication error. Returns a pointer into the inputline to the - first byte of the arguments. The parsing is very strict to match - excalty what we want to send. */ -static char * -read_assuan (int fd) -{ - static char pending[MAX_LINELEN]; - static size_t pending_len; - size_t nleft = sizeof recv_line; - char *buf = recv_line; - char *p; - - while (nleft > 0) - { - int n; - - if (pending_len) - { - if (pending_len >= nleft) - die ("received line too large"); - memcpy (buf, pending, pending_len); - n = pending_len; - pending_len = 0; - } - else - n = read (fd, buf, nleft); - - if (opt_verbose) - { - int i; - printf ("%s: read \"", __FUNCTION__); - for (i = 0; i < n; i ++) - putc (buf[i], stdout); - printf ("\"\n"); - } - - if (n < 0) - { - if (errno == EINTR) - continue; - die ("reading fd %d failed: %s", fd, strerror (errno)); - } - else if (!n) - die ("received incomplete line on fd %d", fd); - p = buf; - nleft -= n; - buf += n; - - for (; n && *p != '\n'; n--, p++) - ; - if (n) - { - if (n>1) - { - n--; - memcpy (pending, p + 1, n); - pending_len = n; - } - *p = '\0'; - break; - } - } - if (!nleft) - die ("received line too large"); - - p = recv_line; - if (p[0] == 'O' && p[1] == 'K' && (p[2] == ' ' || !p[2])) - { - recv_type = LINE_OK; - p += 3; - } - else if (p[0] == 'E' && p[1] == 'R' && p[2] == 'R' - && (p[3] == ' ' || !p[3])) - { - recv_type = LINE_ERR; - p += 4; - } - else if (p[0] == 'S' && (p[1] == ' ' || !p[1])) - { - recv_type = LINE_STAT; - p += 2; - } - else if (p[0] == 'D' && p[1] == ' ') - { - recv_type = LINE_DATA; - p += 2; - } - else if (p[0] == 'E' && p[1] == 'N' && p[2] == 'D' && !p[3]) - { - recv_type = LINE_END; - p += 3; - } - else - die ("invalid line type (%.5s)", p); - - return p; -} - -/* Write LINE to the server using FD. It is expected that the line - contains the terminating linefeed as last character. */ -static void -write_assuan (int fd, const char *line) -{ - char buffer[1026]; - size_t n = strlen (line); - - if (n > 1024) - die ("line too long for Assuan protocol"); - strcpy (buffer, line); - if (!n || buffer[n-1] != '\n') - buffer[n++] = '\n'; - - if (writen (fd, buffer, n)) - die ("sending line (\"%s\") to %d failed: %s", buffer, fd, - strerror (errno)); -} - - -/* Start the server with path PGMNAME and connect its stdout and - strerr to a newly created pipes; the file descriptors are then - store in the gloabl variables SERVER_SEND_FD and - SERVER_RECV_FD. The initial handcheck is performed.*/ -static void -start_server (const char *pgmname) -{ - int rp[2]; - int wp[2]; - pid_t pid; - - if (pipe (rp) < 0) - die ("pipe creation failed: %s", strerror (errno)); - if (pipe (wp) < 0) - die ("pipe creation failed: %s", strerror (errno)); - - fflush (stdout); - fflush (stderr); - pid = fork (); - if (pid < 0) - die ("fork failed"); - - if (!pid) - { - const char *arg0; - - arg0 = strrchr (pgmname, '/'); - if (arg0) - arg0++; - else - arg0 = pgmname; - - if (wp[0] != STDIN_FILENO) - { - if (dup2 (wp[0], STDIN_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); - close (wp[0]); - } - if (rp[1] != STDOUT_FILENO) - { - if (dup2 (rp[1], STDOUT_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); - close (rp[1]); - } - if (!opt_verbose) - { - int fd = open ("/dev/null", O_WRONLY); - if (fd == -1) - die ("can't open `/dev/null': %s", strerror (errno)); - if (dup2 (fd, STDERR_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); - close (fd); - } - - close (wp[1]); - close (rp[0]); - execl (pgmname, arg0, "--server", NULL); - die ("exec failed for `%s': %s", pgmname, strerror (errno)); - } - close (wp[0]); - close (rp[1]); - server_send_fd = wp[1]; - server_recv_fd = rp[0]; - - read_assuan (server_recv_fd); - if (recv_type != LINE_OK) - die ("no greating message"); -} - - - - - -/* Script intepreter. */ - -static void -unset_var (const char *name) -{ - VARIABLE var; - - for (var=variable_list; var && strcmp (var->name, name); var = var->next) - ; - if (!var) - return; -/* fprintf (stderr, "unsetting `%s'\n", name); */ - - if (var->type == VARTYPE_FD && var->value) - { - int fd; - - fd = atoi (var->value); - if (fd != -1 && fd != 0 && fd != 1 && fd != 2) - close (fd); - } - - free (var->value); - var->value = NULL; - var->type = 0; - var->count = 0; -} - - -static void -set_type_var (const char *name, const char *value, VARTYPE type) -{ - VARIABLE var; - - if (!name) - name = "?"; - for (var=variable_list; var && strcmp (var->name, name); var = var->next) - ; - if (!var) - { - var = xcalloc (1, sizeof *var + strlen (name)); - strcpy (var->name, name); - var->next = variable_list; - variable_list = var; - } - else - free (var->value); - - if (var->type == VARTYPE_FD && var->value) - { - int fd; - - fd = atoi (var->value); - if (fd != -1 && fd != 0 && fd != 1 && fd != 2) - close (fd); - } - - var->type = type; - var->count = 0; - if (var->type == VARTYPE_COUNTER) - { - /* We need some extra sapce as scratch area for get_var. */ - var->value = xmalloc (strlen (value) + 1 + 20); - strcpy (var->value, value); - } - else - var->value = xstrdup (value); -} - -static void -set_var (const char *name, const char *value) -{ - set_type_var (name, value, 0); -} - - -static const char * -get_var (const char *name) -{ - VARIABLE var; - - for (var=variable_list; var && strcmp (var->name, name); var = var->next) - ; - if (!var) - return NULL; - if (var->type == VARTYPE_COUNTER && var->value) - { /* Use the scratch space allocated by set_var. */ - char *p = var->value + strlen(var->value)+1; - sprintf (p, "%u", var->count); - return p; - } - else - return var->value; -} - - -/* Incremente all counter type variables with NAME in their VALUE. */ -static void -inc_counter (const char *name) -{ - VARIABLE var; - - if (!*name) - return; - for (var=variable_list; var; var = var->next) - { - if (var->type == VARTYPE_COUNTER - && var->value && !strcmp (var->value, name)) - var->count++; - } -} - - -/* Expand variables in LINE and return a new allocated buffer if - required. The function might modify LINE if the expanded version - fits into it. */ -static char * -expand_line (char *buffer) -{ - char *line = buffer; - char *p, *pend; - const char *value; - size_t valuelen, n; - char *result = NULL; - - while (*line) - { - p = strchr (line, '$'); - if (!p) - return result; /* nothing more to expand */ - - if (p[1] == '$') /* quoted */ - { - memmove (p, p+1, strlen (p+1)+1); - line = p + 1; - continue; - } - for (pend=p+1; *pend && !spacep (pend) - && *pend != '$' && *pend != '/'; pend++) - ; - if (*pend) - { - int save = *pend; - *pend = 0; - value = get_var (p+1); - *pend = save; - } - else - value = get_var (p+1); - if (!value) - value = ""; - valuelen = strlen (value); - if (valuelen <= pend - p) - { - memcpy (p, value, valuelen); - p += valuelen; - n = pend - p; - if (n) - memmove (p, p+n, strlen (p+n)+1); - line = p; - } - else - { - char *src = result? result : buffer; - char *dst; - - dst = xmalloc (strlen (src) + valuelen + 1); - n = p - src; - memcpy (dst, src, n); - memcpy (dst + n, value, valuelen); - n += valuelen; - strcpy (dst + n, pend); - line = dst + n; - free (result); - result = dst; - } - } - return result; -} - - -/* Evaluate COND and return the result. */ -static int -eval_boolean (const char *cond) -{ - int true = 1; - - for ( ; *cond == '!'; cond++) - true = !true; - if (!*cond || (*cond == '0' && !cond[1])) - return !true; - return true; -} - - - - - -static void -cmd_let (const char *assign_to, char *arg) -{ - set_var (assign_to, arg); -} - - -static void -cmd_echo (const char *assign_to, char *arg) -{ - if (!opt_no_echo) - printf ("%s\n", arg); -} - -static void -cmd_send (const char *assign_to, char *arg) -{ - if (opt_verbose) - fprintf (stderr, "sending `%s'\n", arg); - write_assuan (server_send_fd, arg); -} - -static void -handle_status_line (char *arg) -{ - char *p; - - for (p=arg; *p && !spacep (p); p++) - ; - if (*p) - { - int save = *p; - *p = 0; - inc_counter (arg); - *p = save; - } - else - inc_counter (arg); -} - -static void -cmd_expect_ok (const char *assign_to, char *arg) -{ - if (opt_verbose) - fprintf (stderr, "expecting OK\n"); - do - { - char *p = read_assuan (server_recv_fd); - if (opt_verbose > 1) - fprintf (stderr, "got line `%s'\n", recv_line); - if (recv_type == LINE_STAT) - handle_status_line (p); - } - while (recv_type != LINE_OK && recv_type != LINE_ERR); - if (recv_type != LINE_OK) - die ("expected OK but got `%s'", recv_line); -} - -static void -cmd_expect_err (const char *assign_to, char *arg) -{ - if (opt_verbose) - fprintf (stderr, "expecting ERR\n"); - do - { - char *p = read_assuan (server_recv_fd); - if (opt_verbose > 1) - fprintf (stderr, "got line `%s'\n", recv_line); - if (recv_type == LINE_STAT) - handle_status_line (p); - } - while (recv_type != LINE_OK && recv_type != LINE_ERR); - if (recv_type != LINE_ERR) - die ("expected ERR but got `%s'", recv_line); -} - -static void -cmd_count_status (const char *assign_to, char *arg) -{ - char *p; - - if (!*assign_to || !*arg) - die ("syntax error: count-status requires an argument and a variable"); - - for (p=arg; *p && !spacep (p); p++) - ; - if (*p) - { - for (*p++ = 0; spacep (p); p++) - ; - if (*p) - die ("cmpfiles: syntax error"); - } - set_type_var (assign_to, arg, VARTYPE_COUNTER); -} - -static void -cmd_openfile (const char *assign_to, char *arg) -{ - int fd; - char numbuf[20]; - - do - fd = open (arg, O_RDONLY); - while (fd == -1 && errno == EINTR); - if (fd == -1) - die ("error opening `%s': %s", arg, strerror (errno)); - - sprintf (numbuf, "%d", fd); - set_type_var (assign_to, numbuf, VARTYPE_FD); -} - -static void -cmd_createfile (const char *assign_to, char *arg) -{ - int fd; - char numbuf[20]; - - do - fd = open (arg, O_WRONLY|O_CREAT|O_TRUNC, 0666); - while (fd == -1 && errno == EINTR); - if (fd == -1) - die ("error creating `%s': %s", arg, strerror (errno)); - - sprintf (numbuf, "%d", fd); - set_type_var (assign_to, numbuf, VARTYPE_FD); -} - - -static void -cmd_pipeserver (const char *assign_to, char *arg) -{ - if (!*arg) - die ("syntax error: servername missing"); - - start_server (arg); -} - - -static void -cmd_quit_if(const char *assign_to, char *arg) -{ - if (eval_boolean (arg)) - exit (0); -} - -static void -cmd_fail_if(const char *assign_to, char *arg) -{ - if (eval_boolean (arg)) - exit (1); -} - - -static void -cmd_cmpfiles (const char *assign_to, char *arg) -{ - char *p = arg; - char *second; - FILE *fp1, *fp2; - char buffer1[2048]; /* note: both must be of equal size. */ - char buffer2[2048]; - size_t nread1, nread2; - int rc = 0; - - set_var (assign_to, "0"); - for (p=arg; *p && !spacep (p); p++) - ; - if (!*p) - die ("cmpfiles: syntax error"); - for (*p++ = 0; spacep (p); p++) - ; - second = p; - for (; *p && !spacep (p); p++) - ; - if (*p) - { - for (*p++ = 0; spacep (p); p++) - ; - if (*p) - die ("cmpfiles: syntax error"); - } - - fp1 = fopen (arg, "rb"); - if (!fp1) - { - err ("can't open `%s': %s", arg, strerror (errno)); - return; - } - fp2 = fopen (second, "rb"); - if (!fp2) - { - err ("can't open `%s': %s", second, strerror (errno)); - fclose (fp1); - return; - } - while ( (nread1 = fread (buffer1, 1, sizeof buffer1, fp1))) - { - if (ferror (fp1)) - break; - nread2 = fread (buffer2, 1, sizeof buffer2, fp2); - if (ferror (fp2)) - break; - if (nread1 != nread2 || memcmp (buffer1, buffer2, nread1)) - { - rc = 1; - break; - } - } - if (feof (fp1) && feof (fp2) && !rc) - { - if (opt_verbose) - err ("files match"); - set_var (assign_to, "1"); - } - else if (!rc) - err ("cmpfiles: read error: %s", strerror (errno)); - else - err ("cmpfiles: mismatch"); - fclose (fp1); - fclose (fp2); -} - -static void -cmd_getenv (const char *assign_to, char *arg) -{ - const char *s; - s = *arg? getenv (arg):""; - set_var (assign_to, s? s:""); -} - - - - -/* Process the current script line LINE. */ -static int -interpreter (char *line) -{ - static struct { - const char *name; - void (*fnc)(const char*, char*); - } cmdtbl[] = { - { "let" , cmd_let }, - { "echo" , cmd_echo }, - { "send" , cmd_send }, - { "expect-ok" , cmd_expect_ok }, - { "expect-err", cmd_expect_err }, - { "count-status", cmd_count_status }, - { "openfile" , cmd_openfile }, - { "createfile", cmd_createfile }, - { "pipeserver", cmd_pipeserver }, - { "quit" , NULL }, - { "quit-if" , cmd_quit_if }, - { "fail-if" , cmd_fail_if }, - { "cmpfiles" , cmd_cmpfiles }, - { "getenv" , cmd_getenv }, - { NULL } - }; - char *p, *save_p; - int i, save_c; - char *stmt = NULL; - char *assign_to = NULL; - char *must_free = NULL; - - for ( ;spacep (line); line++) - ; - if (!*line || *line == '#') - return 0; /* empty or comment */ - p = expand_line (line); - if (p) - { - must_free = p; - line = p; - for ( ;spacep (line); line++) - ; - if (!*line || *line == '#') - { - free (must_free); - return 0; /* empty or comment */ - } - } - for (p=line; *p && !spacep (p) && *p != '='; p++) - ; - if (*p == '=') - { - *p = 0; - assign_to = line; - } - else if (*p) - { - for (*p++ = 0; spacep (p); p++) - ; - if (*p == '=') - assign_to = line; - } - if (!*line) - die ("syntax error"); - stmt = line; - save_c = 0; - save_p = NULL; - if (assign_to) - { /* this is an assignment */ - for (p++; spacep (p); p++) - ; - if (!*p) - { - unset_var (assign_to); - free (must_free); - return 0; - } - stmt = p; - for (; *p && !spacep (p); p++) - ; - if (*p) - { - save_p = p; - save_c = *p; - for (*p++ = 0; spacep (p); p++) - ; - } - } - for (i=0; cmdtbl[i].name && strcmp (stmt, cmdtbl[i].name); i++) - ; - if (!cmdtbl[i].name) - { - if (!assign_to) - die ("invalid statement `%s'\n", stmt); - if (save_p) - *save_p = save_c; - set_var (assign_to, stmt); - free (must_free); - return 0; - } - - if (cmdtbl[i].fnc) - cmdtbl[i].fnc (assign_to, p); - free (must_free); - return cmdtbl[i].fnc? 0:1; -} - - - -int -main (int argc, char **argv) -{ - char buffer[2048]; - char *p, *pend; - - if (!argc) - invocation_name = "asschk"; - else - { - invocation_name = *argv++; - argc--; - p = strrchr (invocation_name, '/'); - if (p) - invocation_name = p+1; - } - - - set_var ("?","1"); /* defaults to true */ - - for (; argc; argc--, argv++) - { - p = *argv; - if (*p != '-') - break; - if (!strcmp (p, "--verbose")) - opt_verbose++; - else if (!strcmp (p, "--no-echo")) - opt_no_echo++; - else if (*p == '-' && p[1] == 'D') - { - p += 2; - pend = strchr (p, '='); - if (pend) - { - int tmp = *pend; - *pend = 0; - set_var (p, pend+1); - *pend = tmp; - } - else - set_var (p, "1"); - } - else if (*p == '-' && p[1] == '-' && !p[2]) - { - argc--; argv++; - break; - } - else - break; - } - if (argc) - die ("usage: asschk [--verbose] {-D<name>[=<value>]}"); - - - while (fgets (buffer, sizeof buffer, stdin)) - { - p = strchr (buffer,'\n'); - if (!p) - die ("incomplete script line"); - *p = 0; - if (interpreter (buffer)) - break; - fflush (stdout); - } - return 0; -} - diff --git a/tests/cert_cci_sphinx_ca.pem b/tests/cert_cci_sphinx_ca.pem deleted file mode 100644 index b426c2f33..000000000 --- a/tests/cert_cci_sphinx_ca.pem +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIEOp0SzjANBgkqhkiG9w0BAQUFADAzMQswCQYDVQQGEwJERTERMA8G -A1UEChQIVEVTVF9QS0kxETAPBgNVBAMUCFRFU1RfUENBMB4XDTAxMDIyODE1MDEzNFoXDTAx -MDQxMTE0MDEzNFowNDELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRIwEAYDVQQD -EwlTUEhJTlgtQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAP9STo2ReixFod9ItCJJ -QtmAs0Emajr9SvKmE8xzHmEmOP1rZzYZtqkSScIeVaOD1+6GMhNLHGxn+laAbANuxbV489yF -XjpiKlFKOKTzUyuZOO9BJDnRGaSyRyKICK9787RkP377lorO1eziqkCoxP75NIqVlOjajHVH -z0pzZCNNAgMBAAGjgeowgecwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8BAf8EBAMCAQYw -FgYDVR0gBA8wDTALBgkrBgEEAbMBAQEwTAYDVR0fBEUwQzBBoD+gPYY7bGRhcDovLy9jbj1U -RVNUX1BDQSxvPVRFU1RfUEtJLGM9REU/YXV0aG9yaXR5UmV2b2NhdGlvbkxpc3QwSAYDVR0j -BEEwP6E3pDUwMzELMAkGA1UEBhMCREUxETAPBgNVBAoUCFRFU1RfUEtJMREwDwYDVQQDFAhU -RVNUX1BDQYIEOo0HwTARBgNVHQ4ECgQITJJvsx0o58QwDQYJKoZIhvcNAQEFBQADggEBAHjK -fRKOo2uzIyVH5s8ii+hIqJiPL6Z06siqo0XeVxoY3BTtfMo089q1krWJuSIoUPSeg4+OG7Go -Ga3qb33TF7zghUayLwWt4vsXBYkrU5VEEc6jN4NO80rPHsaMHPfGDko5BKmeXVkHPOBaFVLk -I6BuOCNQtRQrVaCbeEjqJkAWJtYG4Yhh63Vyv+bpfMfbm8oBE186pnUxZT1XHynIvrh5gjlX -9sbqqPPd5VqAmql+j4Hy1eC2XpU8JOqX1mif5uIdz0a8FtJP4bBX9lwL3zIhTtNOGiMYKxbT -TOpjDRA9dfpYS7qEq3kYNtqttfAxS67iq1BHafjskOF9jaStk+Y= ------END CERTIFICATE----- diff --git a/tests/cert_cci_test_wzs.pem b/tests/cert_cci_test_wzs.pem deleted file mode 100644 index 7ba60ce0c..000000000 --- a/tests/cert_cci_test_wzs.pem +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN CERTIFICATE----- -LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEw -RlVSUzB0TFMwdENnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= ------END CERTIFICATE----- diff --git a/tests/cert_cci_test_zs.pem b/tests/cert_cci_test_zs.pem deleted file mode 100644 index 025a22c8c..000000000 --- a/tests/cert_cci_test_zs.pem +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICyzCCAjSgAwIBAgIBBTANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxGDAWBgNVBAMTD1NQSElOWC1UZXN0LVdaUzAeFw0wMTA4MjQxMDA5MDNa -Fw0wMzA4MjQxMDA5MDNaMDkxCzAJBgNVBAYTAkRFMREwDwYDVQQKEwhDQ0kgR21iSDEXMBUG -A1UEAxMOU1BISU5YLVRlc3QtWlMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAP+E1LeX -nwq5qAmfHX+zfabAaeMR9Ufow/1ojNg8md+XGVUFJ0a9GZJVQ4ngmxKHmO+6fT77Z0Sj7BQT -bxLbZEqvBxYDSoJgN6K7q2LdbTPIKMOzVF+TxtNyauZx+yxJxTMYYkyVmAlfjAx8Wlznf8Aj -kZywmjVtYWpoN0WedGsbAgMBAAGjgeEwgd4wVwYDVR0fBFAwTjBMoEqgSIZGbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1XWlMsIG89Q0NJIEdtYkgsIEM9REU/Y2VydGlmaWNhdGVSZXZvY2F0 -aW9uTGlzdDASBgNVHRMBAf8ECDAGAQH/AgEAMBEGA1UdIAQKMAgwBgYEgnEJCTAOBgNVHQ8B -Af8EBAMCAQYwTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBH -bWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQEwDQYJKoZIhvcNAQEFBQADgYEAGWjq -TsoWQmUiY3c5Tju+jL51AapWWZbZP8xpBTFjXNRQcRPzWrtHCWS3fhae+aMyGFxiqEhGLePc -QvNdgZmZtzNYSfmeS3iji3zSj7CFmUQKwFrAXUDQNvkS+87FwVno8LilnC0zMfhSW699HtWe -DW/o0CuhXX6IJXXWuSudCH8= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user02.pem b/tests/cert_cci_user02.pem deleted file mode 100644 index b1fba0df7..000000000 --- a/tests/cert_cci_user02.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAm2gAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTA3MTYyMloX -DTAyMTIxMTA3MTYyMlowODELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRYwFAYD -VQQDEw1TcGhpbnggVXNlcjAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD+Gt/ahGJL -uEUVFgceVUsShMgJirndaGjJb/kR3cHQ4Yh4XM9WvP2ze6SRb1cn3Xq9bR1RTFwRoupp9h94 -OwhxjhOTKtTtwFv/OcffJPwAF6K+ms5s8oSBzNX6mo+sLwoVWHaXaSP7rzvOhvYPJpCE6zrS -GO4aUcH50f63wusSKQIDAQABo4IBGzCCARcwVgYDVR0fBE8wTTBLoEmgR4ZFbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1aUywgbz1DQ0kgR21iSCwgYz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRp -b25MaXN0MAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFoEUc3BoaW54X3VzZXIwMkBjY2kuZGUw -EQYDVR0gBAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUZpxNoy1I5cIT -OmeF8LSUJjWnlaowTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCEND -SSBHbWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEA -UU1L9U5LOBaa99Q2ogsLS3PuSOhMKSKWwK+rG5YzNGh9L3+Ecp6/cdZeGY8IV4kQHx2YDhon -tX+SfEnAU5WKN+YfxbLQz5jbDYeyIkFXPFn4Pzt4+1gFLOVvdHFJKT6tb0ZbbLkJkrK+gf29 -sFHz/tVEIiwvWdzCQh669TvmSLc= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user03.pem b/tests/cert_cci_user03.pem deleted file mode 100644 index 44a8510d2..000000000 --- a/tests/cert_cci_user03.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAm2gAwIBAgIBHzANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTA4NDMwNVoX -DTAyMTIxMTA4NDMwNVowODELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRYwFAYD -VQQDEw1TcGhpbnggVXNlcjAzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWLHGzEVlh -NKr5RkWi80jZpuVg20C+1W4H/ez2fuGP8IXZAyy6MYPLQSsFuuwfTtLwFDccJ4PubN/JhSLj -37/AGyygJODQd41CcQxLyB4NqhsYz+dXJv/Rx/E9HDbgsf7fCVwmCpF71phTzeq+zzJYYlDK -uLLvr2auODr4h24jSwIDAQABo4IBGzCCARcwVgYDVR0fBE8wTTBLoEmgR4ZFbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1aUywgbz1DQ0kgR21iSCwgYz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRp -b25MaXN0MAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFoEUc3BoaW54X3VzZXIwM0BjY2kuZGUw -EQYDVR0gBAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQU04AGVPNiznW2 -ZoKD0hqNulIe0zIwTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCEND -SSBHbWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEA -qvifydhixBkVQ0ZesWHXVDwhPOjWtHMuYafMP+9Vn46HCqsbl4gnQqwdwHKl2ox4qd4VOOu8 -PmfKgLysWq11tp/+LCFIEDSLHKCQ1YpBaAxbBg4JxqeTXDF3a3u1RnYOEaVhMZ6L91u16vHT -MJ93W8Fphgf2Fj7EUBPhpyhsnKw= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user04.pem b/tests/cert_cci_user04.pem deleted file mode 100644 index e76880162..000000000 --- a/tests/cert_cci_user04.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAm2gAwIBAgIBGzANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTA3MTIxM1oX -DTAyMTIxMTA3MTIxM1owODELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRYwFAYD -VQQDEw1TcGhpbnggVXNlcjA0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrExMHDJKt -W6ByaO3hVYJCZXJmyMAhHxm31yLXzbd2V5R3Q6ZH4ARk00AMRPDgPLf/NK913OcUFJDrlhLh -aVUfdtz7V095S6Xl38gaClidx2ZJ2EwM4pNxCDeWS1ZFsJMGcis74L5QGrn3/L+76psz7erW -usP+qwy3+3HzL6/hWQIDAQABo4IBGzCCARcwVgYDVR0fBE8wTTBLoEmgR4ZFbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1aUywgbz1DQ0kgR21iSCwgYz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRp -b25MaXN0MAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFoEUc3BoaW54X3VzZXIwNEBjY2kuZGUw -EQYDVR0gBAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQU/UkAw08BpS4w -bM1Eo5MTX21niG4wTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCEND -SSBHbWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEA -3mZM7XFH3CuiGQYe7Wrom+t/QH9BWwORHrskGiVyzBh5Z40HboB8vIN6I6CrQYJHK9DGKnAL -x5AjZ8MUUG3le5M2G6QdhbtGW0jZg5nF1LHx8QYIx8NJSoYa6uPcfr7Q9WgMvTcmA+gXGgzY -Uqv0AMWOx0f3ww0gUpFYIp22ZCc= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user06.pem b/tests/cert_cci_user06.pem deleted file mode 100644 index 7026112b4..000000000 --- a/tests/cert_cci_user06.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAm2gAwIBAgIBIzANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTEyNDMwNVoX -DTAyMTIxMTEyNDMwNVowODELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRYwFAYD -VQQDEw1TcGhpbnggVXNlcjA2MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQ/o0hz0Uz -OGOUfDkzeburb1AO9VChEkO+x8ROoepsjJjkNDtC/4924biA8irfAymzqWP/QwQryS4+Zy6S -O9Jl4yoYNswoZuVhTc+WBkjFMC6qz/Y8mZZb5Fgysf+KAz0Swm0FlWjCYNMcWUp4FHJluG1m -iBarOZRharIVj+HNBwIDAQABo4IBGzCCARcwVgYDVR0fBE8wTTBLoEmgR4ZFbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1aUywgbz1DQ0kgR21iSCwgYz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRp -b25MaXN0MAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFoEUc3BoaW54X3VzZXIwNkBjY2kuZGUw -EQYDVR0gBAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUSIIT/NH6GsX/ -f1C44FyKEokGNVswTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCEND -SSBHbWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEA -aBq+Qi0+Cb8XpnZqUITOmRC9VspxnMcE5IskEtbb2aCU2WkCGCTYMrVzug3BIKo4eNnOHl4k -2oKL8tANapawZSMQb3DtnAvQykYK9DAMYjojOao/2doYKNFoUszg1k+PI+Q1IuV4VjM79R9s -OwpipIj2q08Kx0NrliREuzB75Sg= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user07.pem b/tests/cert_cci_user07.pem deleted file mode 100644 index 2dfadf872..000000000 --- a/tests/cert_cci_user07.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC/jCCAmegAwIBAgIBIDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTA4NTgzOFoX -DTAyMTIxMTA4NTgzOFowMzELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMREwDwYD -VQQDEwhTcGhpbngwNzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtV86FCbl5CQqthMK -vjWjCFOfQZW2v66oiIuE/WZjyOIu1n4FC6z0+pI3FmeKrKhiYeXP8A2J/BzwS9ZD+0as5EyU -+QUzMPdm8pkzvkZCUPKRVi2cyRrBwwqnhH8Bwk2L2o2WMe46D3WBx4hSG+vhQvNMP4nrIGbs -oh+3XJjkoXcCAwCnU6OCARowggEWMFYGA1UdHwRPME0wS6BJoEeGRWxkYXA6Ly8vY249U1BI -SU5YLVRlc3QtWlMsIG89Q0NJIEdtYkgsIGM9REU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlz -dDAMBgNVHRMBAf8EAjAAMB4GA1UdEQQXMBWBE3NwaGlueDA3QGl0cy5jY2kuZGUwEQYDVR0g -BAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUdyGyVPOTruMiE7OLekoP -8oJttzcwTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJI -MRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEABjjhOFKV -3cVF7EGsPfnCq9CYjanFr7jhPxEYG0BuY+x1zgpsTkJm4/wk+NhGo/sFjrq7YExkhQgQViGt -9UhnXZQPsayna1lmkwl/edzpR3A1ELbiULTVGdLarP3MmWEMzKl/Z6prbb+cD1Qwb8D5DG+Q -u3E39VxgzG8i9wMSFh8= ------END CERTIFICATE----- diff --git a/tests/cert_testpki_testpca.pem b/tests/cert_testpki_testpca.pem deleted file mode 100644 index 255d6f4af..000000000 --- a/tests/cert_testpki_testpca.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDzDCCArSgAwIBAgIEOo0HwTANBgkqhkiG9w0BAQUFADAzMQswCQYDVQQGEwJERTERMA8G -A1UEChQIVEVTVF9QS0kxETAPBgNVBAMUCFRFU1RfUENBMB4XDTAxMDIxNjExMDAwNloXDTA2 -MDIxNjExMDAwNlowMzELMAkGA1UEBhMCREUxETAPBgNVBAoUCFRFU1RfUEtJMREwDwYDVQQD -FAhURVNUX1BDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANTELO2lGugWqO5B -cLGU61TMZzUoR0yDAhPOjNU/CkLy9x+bDLJFAuvYQOm7SRcbTNcviUyot064ROWCcVn51kNf -+fmZhTyMix36ffcEERO7NaN4ZN7eXi39u9udTfPoQjUpy2tBVOwHlzBdHhklG1hBodqlmbfE -5Yt6ku0jm4wfxoiqgbF2dh9PhuCClt4YuBcnELw52duAKYNiHwfIqrwgDvAdi/J+mdgcxy1Z -xl/oIIVEy5FiQlMkleCDxstuEhVde8/ZzzyDbC+22Ok5xr6wexgUK792G6NZ+q+0BK+9Hqtw -m8/7UHyuUGboyHAT8V7ecgrpEg5rvJgRxtxUYA8CAwEAAaOB5zCB5DAPBgNVHRMBAf8EBTAD -AQH/MBYGA1UdIAQPMA0wCwYJKwYBBAGzAQEBMEwGA1UdHwRFMEMwQaA/oD2GO2xkYXA6Ly8v -Y249VEVTVF9QQ0Esbz1URVNUX1BLSSxjPURFP2F1dGhvcml0eVJldm9jYXRpb25MaXN0MBEG -A1UdDgQKBAhOFXmpxh5ysDBIBgNVHSMEQTA/oTekNTAzMQswCQYDVQQGEwJERTERMA8GA1UE -ChQIVEVTVF9QS0kxETAPBgNVBAMUCFRFU1RfUENBggQ6jQfBMA4GA1UdDwEB/wQEAwIBBjAN -BgkqhkiG9w0BAQUFAAOCAQEAs/wp8umfNLnEQ56DyIAOdWUwgJNrLYK2hk84G+lQKhem+jD0 -BoklUd/DifJxXE6QVFMxjr9aoYjMcloCuYV2jLd0kdebDmFvFNl3O9+mR0br8wHRCXhfPMwg -dThmhdtDs9qfyfStNStLch4F0edDYJtO3XaGWlQk52ykJy3yoyxmDUIzPTIKCV3LYO7bOXfw -FVECQaoO2+HrrZef6d3h3XL7leWhGYZ2YV77yzfZuN41y8aXQKF/1J7mYvpjceUJAyMZCUMz -FLDH4Zj4YGc8OH1xpAvGgztDuPQU8JXJBXuXIL0jmUcJRAZmgbeWWOgGIhYtJ4Stoy0pnHTZ -dcn+jw== ------END CERTIFICATE----- diff --git a/tests/crl_testpki_testpca.pem b/tests/crl_testpki_testpca.pem deleted file mode 100644 index 458c48164..000000000 --- a/tests/crl_testpki_testpca.pem +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDWTCCAkECAQEwDQYJKoZIhvcNAQEFBQAwMzELMAkGA1UEBhMCREUxETAPBgNVBAoUCFRF -U1RfUEtJMREwDwYDVQQDFAhURVNUX1BDQRcNMDIwMTE0MDcwMDI4WhcNMDIwMjE0MDcwMDI4 -WjCCAXIwIwIEOpzbCxcNMDEwMjI4MTQ1NTE5WjAMMAoGA1UdFQQDCgEDMCMCBDr7z9QXDTAx -MDUxNDExMTY0M1owDDAKBgNVHRUEAwoBAzAjAgQ7Cmq5Fw0wMTA1MjkxMzE1NTNaMAwwCgYD -VR0VBAMKAQMwIwIEOxOgZBcNMDEwNjI5MDcwNzMwWjAMMAoGA1UdFQQDCgEDMCMCBDs8KH4X -DTAxMDYyOTA3MTA0MVowDDAKBgNVHRUEAwoBAzAjAgQ7xr4IFw0wMTEwMzAwODIwMDdaMAww -CgYDVR0VBAMKAQAwIwIEO95jKhcNMDExMTA3MTIxNzE2WjAMMAoGA1UdFQQDCgEAMCMCBDvp -JwAXDTAxMTEwNzE0MTEwMFowDDAKBgNVHRUEAwoBAzAjAgQ8GHpuFw0wMTEyMTMxMDAzNTFa -MAwwCgYDVR0VBAMKAQMwIwIEPBh8ihcNMDExMjEzMTAxMjE3WjAMMAoGA1UdFQQDCgEDoGQw -YjALBgNVHRQEBAICAVAwSAYDVR0jBEEwP6E3pDUwMzELMAkGA1UEBhMCREUxETAPBgNVBAoU -CFRFU1RfUEtJMREwDwYDVQQDFAhURVNUX1BDQYIEOo0HwTAJBgNVHRwEAjAAMA0GCSqGSIb3 -DQEBBQUAA4IBAQCCTBKii6N4bX7sH6d3fq6yFbn2Xr5xDbDkpjHYSvHhBnfEnFAQOjOsn9ar -qk8NDUCT4j4AWD//i/9l5YbvY+32/ER32vZ5PDtSyhZ/pHIOaYUy0haf2pwDSXf7ESZKUM5a -O8UOVBlXhniClnakZHI6z7r7Md5xIJ5C2W8JaLUswiycvyMg37eM6a+d+J+ZlFXQZNO/9cfN -ItcSCBaRgUWm4LNdTJllNeZ9HMBOJ3pgS7yta4WNQi2mNgRzCcJJuVm5qmXo/9v7hMLmL+pb -YUPnQIfyjYmJK0ea+8KsKsgIKtiU8xteqTxPQ3VJBbH7ChcO4SMUPq5yL3otGZu5zOoQ ------END CERTIFICATE----- diff --git a/tests/extrasamples/README b/tests/extrasamples/README deleted file mode 100644 index 3102eac15..000000000 --- a/tests/extrasamples/README +++ /dev/null @@ -1,5 +0,0 @@ -Extra test data where it is not clear whether we may distribute them. This -we only keep them in the CVS. - -dod-test9.p12 A file from the DoD X.509 tests suite, September 2001. - Passphrase is "password". diff --git a/tests/extrasamples/dod-test9.p12 b/tests/extrasamples/dod-test9.p12 deleted file mode 100644 index a109b1aa9fe6c89f680ba5348b45a79fe95fd4c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3934 zcmY+HcQ70Z*T#2Qt0k)w(K{>HjS_YBx|Xm+CwdK{w;-#9kmx-+!735mC3@6Ev}hMm zR<F_foBPdI?)S_*bIzQ3&Yx%IcVHMYV>}=}EEG%(jZ}*~yALD;=7oYVWE3zA+5LZy z!Fi!D4Cyc)5b&q;{woe+1e5&t?mZwF1_2RywU&(ZBXm{q@Q47R7}E5hsok56uyKi& zcZLcVfD?^*BhsC{vy?6k3}OA};Bm=ujjPoiI#~B&_{RWD2|4J}*!ng!DtACdQ|MKa zluZqJ3Y3+gc&BWx9NeeiHE`9fO4!E<+mj?I;*SQ&idGCn#4+D&qUMlWF^7z?mjnZ4 zXDr4acYB>yhdle;%^kMIJX0+jIi6c5npBAI$-l&!_}E$^!bR%{AQOXpBQ-guD-Y8z zQ{+tNb_JijFQKmD&dmOp2mbbEbX@NdAMK}Y0k)EB{#q~V0Nf(wnrgsmNydItv_dSX zZ&{)jhUgN#|L)^(Tz!1Ot$iR?AnRncyaw7S;1dDV2|HoM8w+!IHb|W?G72Nkrf@RY z7YSFXrm{LIEKq;T$^7F>RB|Q)Okn8pvSZ5WPK!ez7I~1|P#f4pZ#8}Uvqb`D*aLs0 zrW{*enijLz&N}=#oAH5tW{eiI&P79&e(By2A6Y6Y`lx9eUvi&@&AUX^XuVDQ;q-Z+ zk4of=0TK>jXapIp-RB6O4p2jmv|@hIY8NuGm9bn*p`1$v<Mytz^#+C6+I`dG-dyr4 z!+0kyOxA4qV;E`w+J~l^vk&3gO-&SYFR>uua?d~=#w{1&q2ErobXKY9ExfWM6G~yH z#+1ErSw8Z0*h=;f5)g8xJv$k?u;6PYKJysg91+DOuf~rZPK1h(nK`c`(PBN$q@wz& z;7T3V`r<Ykt-K&w9*UxBEkJWfKo0z6IsxVB39Ij40nPfrHLhj|;QZ-97-uy7S%V7) z**N61CUWfb>X1_E!VxFecUj$eR!+EXM-?-TYwUj(??L6d7D^n7hF5T@yiM<@pD8tR zby9xg%N^&Fjz4n8uCI)KB6w?8y85Dn)3uQSQJS({$3YME7I{bCkTGe8MohV<I77Lv z-vcIQ9ul?Q(ix7{CyZfZNbxwphGX-nv#yJ-(L-j`PK5Bc)n{8YNFn|aCP6mGLTZV2 z0tr!sMQ&Yvc!uM?Wlw+cIZ)7Z84flHT8MAqzj&ZPKS7YY=M=Zx$p9@gewk%*OhNXE z^n1}ei>2;1h2wQ&Ib|%bqp70DP{>M)r@`v>dn0zWwA(5Aw6USXllGhOcwM{*U!D$F zyvEGu;dRaJbt(&7Xg!rE;_S5(WLdXoB*2i-_z^QS*NNR>*9HyY*I7%->&{1*6Sq-z zhRw2S`OzhoUX$eBRzFK^q5~|ZF{!?T^!$L`PR8n7>%6L#%e*@ErL`E$D!(Gi)hK4p z+2W+Zp_1c0eIEz;0iO0gqX&#4`f$T_u<99RYBct#jmCyxgBgP2bM4l{jGu6<6b_=b zhwh<O53eb<uVN**b?aS-5_(%X=}r*N;Sk&ubXZH;Pq{^oLb>VPJj`<jaFMqWL<;j% zNk$q%!9D8MGJp^}$FNXtjZql_TZvf{BE{M!jtC(!Y(xBlb8j19#kpYkqU+Uh#5GfJ zMuUr9W0~JgvzklhrV%QSoW)4riuO_#idRlo!D|*-xx%^cyb3Rns4NVf#S_=t`B(vG zynLG+LDE#2UDkPB2(c|%E*A6f6Y%$ort6`;Aj`EnoF3hszX2#Zju~ufM75sH>Ui6t zZGjpIcT?<L`o@dD`MY~#ecszI0jTMhG>*W!2C3{V%w}E|{#J2HZTOku3{<M$*4Q79 zicGzl<m|zXir>s}LTPtA_$QyD$JP7!EUtmtkQ!ewH1lUYgv$A*%9`brNy_vLovtM8 z@tOrCY3>>b*IHDz^24p0859(DO-ZrPaox0&9w%jOj>0$;(G@h?AApZy(-TA{T<HAM z+_tC*19p^EHE3$cLXt_u1#EQQ0()uo)Ds;sZ*9F3Rl6`hYP+#JUq8!~9ff`sv)|&A za;3dQ6#4Jd1_x95+3mXWUPO&Gfl?k#9Cv3nK|dH8KIEz_Sw3hRnKBR0-Xs2Ixl-E` z#89qKb4Q<*=UDLCLJ5UU^y7GRMk1E;kcVc)n}heOEA^3rf;H4QqUY~{((ftC*o?|2 z_o?^iLXzZ2jW>Dl3Y&8KjMc(uCWUvG7G^3trE4_O{pLbNmROZaaYfu^=s^lBR~grZ zTPenjz&V(&{7LwzZy`SIU-FD1pBi-ITeie2v>e<enc}Z#OSR|rk(x+x!QT;eZ#vkz z29HHtZ`g(UH5Z>pYl<De;23vN)<0QU+)d?MeNKXD_D5gHgNL+{A3Ez@Q+K&Qt#j)$ zPpq1M1wLjGYt>&EfkSaXWX@!QQ8T=2$lV!KGu982j!9IBH!-X=_fDY!Gc*agZ-j5S zs<wVIVlm?=WZLiNmU=TGZMq>|!AWHLBB^-vZ~N3qX6VU-c=Brx?P;e^L~uQKDMo<5 zOTONLTcD|9$lTpRW?2B}$J%ty_dAR!uh35icWrx!uyjK$3)zo7H%K!1`($k7{j0tZ zB&DdVX%SIMlUP5AO(GMobar`qiaZ`&sB^8b`6R)+O5qLr8V3-$i)`^x+be;P@bHOC zUg71}j80Rf5`vHUVgB}75PYek^I_t;HFICrrm2wOrEQDn%vFQ+7X%=eeS*Cj>1>V9 zIy?0Wh0@h1vgJ1zPWp{Qw4&HrVkztTtq&U=q0$4%?f^QMsA&etAC*=~CRH}B6qL9T z?6OD2&)}2ULJJ;f2`@Jk6X0IareNM?YDU)v_El7!9~ZZ8<B076@`j%-&b+pGmW6{V zkH%L*gQb79{Ph(n)5LaGn;%JaZZ^6AQ8s$|J1EdO`)MSL+RAN|QT%Q87)T<Q)yJ^z z@CD)?TP~s@HpA*{D?fC(!w{<7?CF5d%lm5`G+6AH&iD~N)|{hS&L+`#|NOE_N!!kD z4t1a2Gt<d9MjzhbAZWi_sIhi>yL*0(NF<MDEO-DEWpCix5z!&T-bVi&*Xhyw!d6bg z7?d&j#CHUfyqMR7uS7Bbp7Kqu@kglZrZWlJA*P9*-FuAP_5i;+xZ;q-(*?~n!lhZO z_^GnLe}f7az+BuVNHDa6Jz%~22B=ziA1~9)@i;GQ%FvKI(0lM@Tj>bTRO2V}R#i%m zn-w1NMA`GY{v__exOVO4g3E5*C@q<8-7xvH3}SPo><bWT<N6#qhj^7q@t4iTL4x_P z>7#q8?^zp)Ejw<io}U%IDk5&&87YN^KwbJPOxwR!2O8;~THPaQ`R<h`ULchFVw>`G zM1~T?riJobBuR)+Et}+*AtFZY?S~2Wiyy+EnoGaGT;y>T)bHK7c?{B?Z1PX6`ThQ) zTWXVwrlIj&&I405`!M&Ioi?s*N_4oe&@DgS(V4{+IEHVN#5vpQMb>R{l(PD0lQbuq z&K1KJbH*9fH2laS1E@+;`TOFAD5U4DJjI<tv~!xVUny3M9(XvXtP6Z;REGOF2khb4 zc%Mlq!Kx8C`H#ULEMl@s(*0+qQBBzI)V#x@In4TA1%c@bVPnJm1K;B+(o~pYR;v#v z!tW_iKt4Y)p2@$wo(-u}9<=5ypu-z$mu)wa`XbMZ8mOZT4G+5~W46DaA3FXs$wgNH zekTNTX`9@t0XfYa7s`B#l9T{mpL4!c36>|$G1}47T6-YAl-s`DQSvjn?fCoN(Iq$c z@I+!?Krrr_(vsAi?gY6EpGcMnm!0`^BEAycZXs3OT9^K&^QR9MLo{aEzeLgF&x{Nn zX-|Xq3DE>>(N<r1DDs_6p*V_z7`eKu=S?%uyD}9KHqnA*$Xksps?NOZp{OFcpKDY( zh9+N<%isSvFu(Y_M&k+bx9;5H@0)9sud2k0m)hyI0|{HjbrOdxY*>KyE2rLThpFH5 zz|CH2`6Z;+9i_zqaZ&1*TePrCFaM(gX~i&{PI!=I*yo;wtnLThuSO^$ZT$<M8eUB{ zyS=#RLllwjEPh+)?t03X;>T>D!F(0(H6N+(N<}I#!A5STE7hWl%a<4v1pLvz5&yr) zAD;?_!6*A;QZVWNU_A*CFAsxP0>j`H{6E^q|A+Rcq(6=I8s9hkhxS1jyiogWLF@Q9 zgWYC`duHI%t7gI{=;~mkO0!#}Noupgyn)wYCJ)zQaVJnd?rMN*+~Qd&dFgxw;S4s) zHwZXXA@yYHTT({2DO;Q~>oK?92+LX60F%i}U;VW+bVSzr4}$zwv<aTg!tH~5t%X66 zdKEP4qL6z>{z`KF43}S9{YXUI#V&2V%dFHFjvkE(8t`$5k-fpGyCy36t@)oN3nx^` z^&>3VG&Obb7m;}tIx5dA%)It^w{KnvU}BRh6MPv`^x2Q8MP`mvTN!@Ywd4}Q@<M7N z)0Pg9&{lIAh1uWZ;V)lCL`jE|X68=?5Uxy5yzgJV7l#jFJWfG-`hC|U1v0^-BYJda zk|oXWOyaa^NYvA4Ld+jYuXa=JpgOFa?Y0hYF<VqZsrnnzK1dG2$NEI<jR>Eiyf<nw z<%-COhaJD{;Qo{wWW%rSql-9S>pbUw;V-6qv*IQ0y~>>zCJX&bc4qpkF7Y!P!CEzI zS$d`cPa=9d@ucd%k#fDnGO{gMwID9*Od*8O>oU5p7<UG$2{SD5$?pd54%`R%d>$vi z<mX+6V8Z3v1{VTQ2qe<-p(c@9d~$#80*bX%tP5_#X7G_MHZw4xfP*WpyW=!>R#w=^ z)<+^HWrs%8>P$8}pw57d<rDs}gG`%3_aJY5;i;hB8cTveiRBH)Yx%kQ=|Czj$U6np zJjk7|s!fxdXkUZ1>r$c0#jDkG)B(Sl4$J_H6n?xkTe~`;%LS0JKJqx6RIkf^+)#}< zoJG1B)}rMAhnfvY$<HKnU@dm>Zcax}^L3hpgaNZzH?ij*4(c9#jhNZYZJ9RQS2(^K zYoks}N016@j61@0VI2Sao)Xi*X+hNN@<4h?=^nPR;Zto*e>^Xqrz0US{{IV6!<m^G z0Vse!fEAz!umyMkya0{>yFa!DSpMm4|GAWZ1QUR<!HB^G{1AM+hXeo+HHAu^t796Q b!4$EV-49tah84o}0T9t<NCCX2YLNdw(O*ZW diff --git a/tests/inittests b/tests/inittests deleted file mode 100755 index 05a94eb68..000000000 --- a/tests/inittests +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/sh -# Copyright (C) 2002 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. - -set -e - -sample_certs=' -cert_g10code_test1.pem -cert_g10code_pete1.pem -cert_g10code_theo1.pem -' - -private_keys=' -32100C27173EF6E9C4E9A25D3D69F86D37A4F939 -' - -clean_files=' -gpgsm.conf gpg-agent.conf trustlist.txt pubring.kbx -msg msg.sig msg.unsig -' - - -[ -z "$srcdir" ] && srcdir=. -[ -z "$GPGSM" ] && GPGSM=../sm/gpgsm - -if [ -d $srcdir/samplekeys ] \ - && grep TESTS_ENVIRONMENT Makefile >/dev/null 2>&1; then - : -else - # During make distclean the Makefile has already been removed, - # so we need this extra test. - if ! grep gnupg-test-directory testdir.stamp >/dev/null 2>&1; then - echo "inittests: please cd to the tests directory first" >&2 - exit 1 - fi -fi - -if [ "$1" = "--clean" ]; then - if [ -d private-keys-v1.d ]; then - rm private-keys-v1.d/* 2>/dev/null || true - rmdir private-keys-v1.d - fi - rm ${clean_files} testdir.stamp 2>/dev/null || true - exit 0 -fi - -if [ "$GNUPGHOME" != "`pwd`" ]; then - echo "inittests: please set GNUPGHOME to the test directory" >&2 - exit 1 -fi - -if [ -n "$GPG_AGENT_INFO" ]; then - echo "inittests: please unset GPG_AGENT_INFO" >&2 - exit 1 -fi - -# A stamp file used with --clean -echo gnupg-test-directory > testdir.stamp - - -# Create the private key directy if it does not exists and copy -# the sample keys. -[ -d private-keys-v1.d ] || mkdir private-keys-v1.d -for i in ${private_keys}; do - cat ${srcdir}/samplekeys/$i.key >private-keys-v1.d/$i.key -done - -# Create the configuration scripts -# Note, die to an expired test certificate, we need to use -# the faked system time option. -cat > gpgsm.conf <<EOF -no-secmem-warning -disable-crl-checks -agent-program ../agent/gpg-agent -faked-system-time 1038835799 -EOF - -cat > gpg-agent.conf <<EOF -no-grab -pinentry-program /home/wk/work/pinentry/gtk/pinentry-gtk -EOF - -cat > trustlist.txt <<EOF -# CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Düsseldorf,C=DE -3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E S -EOF - -# Make sure that the sample certs are available but ignore errors here -# because we are not a test script. -for i in ${sample_certs}; do - $GPGSM --import ${srcdir}/samplekeys/$i || true -done diff --git a/tests/key_g10code_pete1.pem b/tests/key_g10code_pete1.pem deleted file mode 100644 index dc26c8eda..000000000 --- a/tests/key_g10code_pete1.pem +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,A4885DDADE65FCB5 - -6mK4tsaqaMQVILY2b0Wku2dGp0GmqJMXRb49Xl/hlDhqO6rF30ZnCbFSOWS0O74a -+QydvNhACt+0lrIYv9E1pfU8ibmlPF1ei6n2GBcXgZGT8nFd5sb/+UJ1hEB9cRny -BuWjUOWB4uFnNkkIcWJEK98Yfmiiisp8kjoW3SgWQPXW/WaZkclpgbk8SVWeZ+14 -S6GXvQsaVhiXGN1Kv5nL6Qk1LSCg8rS1jMAPsQEO/KhRCogVmjw06x2RuqM6eISz -9mAio4AFMEhcY9Dg+2Ybf+iB4NnsvTaygUIZDDZ5TZGbr3O52CDblbKjswr2fO6B -PqoBLODmhb1ZTEq0tf9kQAs0SPek8Rd7xYIQrEBmmZz7v0sU4yROyMkRU3EzEYXV -Qsue1tqVtnBXB/d/Y0GG5NR4bo1oUwjzv8oUTxzPh8uDYDTNW2+KwPBmOx0hN2LG -FkN5KzBeHmGyACvQTVZndzEBHuult+6lfdDFMkopt9dp8ePlUC0s+61x+fi3nfEs -6AZLvRNDoi8Zv1+42RAbOA5ZKC1H9zjcbF5WzOCegRgKZyhZ+1+9IIoWqoCgK841 -pn/Iaog43Ba/npyNpJE63Q7khJueSkeN0NwtV9EeYB8xSF3RMlPDrakTdTTJJIAi -wUFXCbUieMsOj5b9jw6A5H0Zls0HcUdBos/ipiE8jdAjyxOp+q2hXTaOn7eK3WaD -CadRmfnRp383pfzFM+93MhsRZHg+Mw1BTnRghM4l/flykYXgDTFR+9citxbRzQfu -sVfrcqNmHvjqdhR5054oZjZMUP0SxRm13XsUfUMhIWsB1wrqHkYa/A== ------END RSA PRIVATE KEY----- diff --git a/tests/key_g10code_theo1.pem b/tests/key_g10code_theo1.pem deleted file mode 100644 index 9722be26d..000000000 --- a/tests/key_g10code_theo1.pem +++ /dev/null @@ -1,21 +0,0 @@ - - Passphrase is "test" - ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,C1E4BE50963AE732 - -xtD0InNwYZnG0z61ydRQ+UmDoKiUiiXiwbmZQREZUG2E5Tat77WAkiA8lwjqimmC -kGPWnCUtoMpuXrBl4JC1fsvNCsOhPu9w90JcuNqlxzUltZjP9M9uj9Ic4Hut9FoR -uSKY4sz7zGlOg+1kGZu1lXEKvGgrHO7sq66Q2Y1ugaWrlvdQt+1m2mTpk01rj2vZ -fqZO2EZFYNPAgQRpfnHmfaD1zIefRLbxwjQUTUvLWTN4aOaOBBNE6AlzwSK4w0Ba -4RAJpHuk7Kk6UNvNQriMjXMBvHCZLqKIJXGn99o8acK4E/Hrsyq8CHKT3ye81FoF -JsJf1n6W9NG21BH/HuS6uDcyvhhBpgP9yJclRiHd29t0pmM2v+FQxlpycEIwMLcT -hu7BaxdVrMmZHwwZXjFW8W0paltN65U3AevAddwyh6tmMRZR7OJP5P4qws4ehzWB -M9VPgHiWHkCwgjMH1EjhCXqChj0KCW4pHHXevA3eNJP8yEuGzlHwvh6Y4b+FFqtO -gib1MfWPsSYP2kW8XPrVzb2VMMWlqepUeKdBtZSC0s7TW7+bN7sgyWJYInBtqTZT -VCTauwUaFfRflp1l+jPofypaVs5Dsom96kMjqe9Tg9b409ZvWps5A7lG1Q26Nkyk -6/GA7Elt0lArwEs7lcHy40/5cIB5Bjgj7AL5B2/1hwoxFBsNa3k69OssJC6tY6ek -qwwa2KfXHsG6gHlFgMW/gRCJENy4dqtxkaVM27d+ulRlWYP5INyXFiH0NPeSR9i0 -LUDpQoKaexXG3DSQZcGSdDGlBa16iuPfKOEQMqQiymgxjG5umSKrZQ== ------END RSA PRIVATE KEY----- diff --git a/tests/runtest b/tests/runtest deleted file mode 100755 index 8d5078647..000000000 --- a/tests/runtest +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -[ -x "$1" ] && exec $1 $2 -exec ./asschk --no-echo -DGPGSM=${GPGSM} <"$1" - diff --git a/tests/samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key b/tests/samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key deleted file mode 100644 index cf0535ff7..000000000 --- a/tests/samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key +++ /dev/null @@ -1,18 +0,0 @@ -(private-key - (oid.1.2.840.113549.1.1.1 - (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#) - (e #010001#) - (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B117D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BDC543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#) - (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#) - (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f935a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#) - (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891eebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#) - ) -) - - - - - - - - diff --git a/tests/samplekeys/8D6D17B4B94BBE8304926C016D2C5C7805EB6705.key b/tests/samplekeys/8D6D17B4B94BBE8304926C016D2C5C7805EB6705.key deleted file mode 100644 index 2063610dc..000000000 --- a/tests/samplekeys/8D6D17B4B94BBE8304926C016D2C5C7805EB6705.key +++ /dev/null @@ -1,10 +0,0 @@ -(private-key - (rsa - (n #00DB26862FD7EAF7AC9A52BA22473E28C8DF4637B0A048230772F6D5CD96EEF905D7D650A84957CBD3CCCD720A9C941EB430FE5088E6A8DDD0D5770506A314DDB4F579A2696FB53E98E7A8750F400016A9885D1C1F5D19AC90D186186DF4B354F3BDCA978BCBFB1810DFE5AB68AFE4B2B09D1F8223265514AFECDF596628F8C58F#) - (e #010001#) - (d #674F76ECB0FE0CBA2A9A1B3333A0A2FB66FE241CB8C2A8F8C70283F202582FBEC86C38E3CC877E081FC12E24C081B723BD00F698431C924CF384C332C8C87A67080A88A0700DC36D671ECB4D7AE0EE9C645AF932B9B55BD3E16C043E9D972202399F021374C358E8B77CA37CFAC642637CFF31E6E5839A89CBD3E32B9BEF9A01#) - (p #00EB664011AD44EFEDE2B40A3F753373F7CE39E2CF4A5E7812ABF5B957AFA8C9F9FEE1EE9D8F2FF7369B553749EADD0C605A581111A4D532ECC3ED3DC46DB1A501#) - (q #00EE543E10FD86829889682BC4BECA1230924B7B4A19823566FA056C9033937B97F29665CF21F6F097F9BAB24D6F596C93EE348568FAA59BB325EA66DFBE7B9A8F#) - (u #008BD460358A993D2B442BC7DC3F1E6EF9470F17E3E3BD85A496690A50D564BB585B66A3BF841B8FF9513293EA02C784C6142008A79948020FFF03440D9591C7D7#) - ) - ) diff --git a/tests/samplekeys/README b/tests/samplekeys/README deleted file mode 100644 index 0e8877907..000000000 --- a/tests/samplekeys/README +++ /dev/null @@ -1,17 +0,0 @@ -This is a collection of keys we use with the regression tests. - -opensc-tests.p12 PKCS#12 key and certificates taken from OpenSC. - Passphrase is "password" - -ov-user.p12 Private tests keys from www.openvalidation.org. -ov-server.p12 Passphrase for both is "start" - -ossl-rentec-user.pem An OpenSSL generated user certificate using a - bunch of attributes and DC RDNs. - -webderoot.der trust.web.de Root CA certificate [2004-02-17] -webdeca.der trust.web.de CA certificate [2004-02-17] - - - - diff --git a/tests/samplekeys/cert_g10code_enconly_1.pem b/tests/samplekeys/cert_g10code_enconly_1.pem deleted file mode 100644 index ef28b6924..000000000 --- a/tests/samplekeys/cert_g10code_enconly_1.pem +++ /dev/null @@ -1,26 +0,0 @@ -Issuer ...: /CN=Root-Test-CA/OU=Test CA on Kerckhoffs/O=g10 Code GmbH/L=Düsseldorf/ST=NRW/C=de/EMail=test-ca@kerckhoffs.g10code.de -Serial ...: 03 -Subject ..: /CN=Encrypt Only Key 1/OU=Testlab/O=g10 code/C=de - ------BEGIN CERTIFICATE----- -MIIDmDCCAwGgAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBrTELMAkGA1UEBhMCZGUx -DDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEw -IENvZGUgR21iSDEeMBwGA1UECxMVVGVzdCBDQSBvbiBLZXJja2hvZmZzMRUwEwYD -VQQDEwxSb290LVRlc3QtQ0ExLDAqBgkqhkiG9w0BCQEWHXRlc3QtY2FAa2VyY2to -b2Zmcy5nMTBjb2RlLmRlMB4XDTAyMDkwMzEwMzg1NloXDTEyMDgzMTEwMzg1Nlow -TzELMAkGA1UEBhMCZGUxETAPBgNVBAoTCGcxMCBjb2RlMRAwDgYDVQQLEwdUZXN0 -bGFiMRswGQYDVQQDExJFbmNyeXB0IE9ubHkgS2V5IDEwgZ8wDQYJKoZIhvcNAQEB -BQADgY0AMIGJAoGBANsmhi/X6vesmlK6Ikc+KMjfRjewoEgjB3L21c2W7vkF19ZQ -qElXy9PMzXIKnJQetDD+UIjmqN3Q1XcFBqMU3bT1eaJpb7U+mOeodQ9AABapiF0c -H10ZrJDRhhht9LNU873Kl4vL+xgQ3+WraK/ksrCdH4IjJlUUr+zfWWYo+MWPAgMB -AAGjggEjMIIBHzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFIDAdBgNVHQ4EFgQUxWTi -IXcx29tl0D0TYl9sQ4z4foIwgdoGA1UdIwSB0jCBz4AUilgNzsWIc4O+ang1CsXu -Xu1NypOhgbOkgbAwga0xCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcxEzARBgNV -BAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxHjAcBgNVBAsT -FVRlc3QgQ0Egb24gS2VyY2tob2ZmczEVMBMGA1UEAxMMUm9vdC1UZXN0LUNBMSww -KgYJKoZIhvcNAQkBFh10ZXN0LWNhQGtlcmNraG9mZnMuZzEwY29kZS5kZYIBADAJ -BgNVHREEAjAAMA0GCSqGSIb3DQEBBQUAA4GBAGPwl3GN6TxYlwnN7Za2H4lJthUk -Bdxrjoh7D7z4kxpo0JGgcBbDEpGPDNtwNg73ukwruGOiOJPGk6qZI1TtI+7joScH -f1dtGUTcfFW+qpGkImJDrY1IV+ud6qhL2LxY4FLAuEv2iPNSbM9N3X8nB0ofWoPe -fISRwikYCdR83m+t ------END CERTIFICATE----- diff --git a/tests/samplekeys/cert_g10code_pete1.pem b/tests/samplekeys/cert_g10code_pete1.pem deleted file mode 100644 index c6f778a56..000000000 --- a/tests/samplekeys/cert_g10code_pete1.pem +++ /dev/null @@ -1,24 +0,0 @@ ------BEGIN CERTIFICATE----- -MIID7jCCA1egAwIBAgIBADANBgkqhkiG9w0BAQQFADCBsTELMAkGA1UEBhMCREUx -DDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEw -IENvZGUgR21iSDEbMBkGA1UECxMSS2VyY2tob2ZmcyBUZXN0bGFiMRYwFAYDVQQD -Ew1QZXRlciBQYW50aGVyMTIwMAYJKoZIhvcNAQkBFiNwZXRlci5wYW50aGVyQGtl -cmNraG9mZnMuZzEwY29kZS5kZTAeFw0wMjA0MTIxNjU4MzFaFw0wMzA0MTIxNjU4 -MzFaMIGxMQswCQYDVQQGEwJERTEMMAoGA1UECBMDTlJXMRMwEQYDVQQHFApE/HNz -ZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBHbWJIMRswGQYDVQQLExJLZXJja2hv -ZmZzIFRlc3RsYWIxFjAUBgNVBAMTDVBldGVyIFBhbnRoZXIxMjAwBgkqhkiG9w0B -CQEWI3BldGVyLnBhbnRoZXJAa2VyY2tob2Zmcy5nMTBjb2RlLmRlMIGfMA0GCSqG -SIb3DQEBAQUAA4GNADCBiQKBgQC/UYKEu+IZgvoUwbBaKT96SDsgnsOLkC7TWuP+ -td9qyjF+tQCSUdTqRDYyP44hLH24v4h9KsVxwl5iuncJCdNmpTHL4ika+3v7arGU -DmGEHZOC3mHMzD+/dfqotse7C37AEMWSXguh4x2vmSESG9wnAxCgLl78j+RIuKUE -RVK55wIDAQABo4IBEjCCAQ4wHQYDVR0OBBYEFDhJ93SfqHOecsryvYN01++o7qh/ -MIHeBgNVHSMEgdYwgdOAFDhJ93SfqHOecsryvYN01++o7qh/oYG3pIG0MIGxMQsw -CQYDVQQGEwJERTEMMAoGA1UECBMDTlJXMRMwEQYDVQQHFApE/HNzZWxkb3JmMRYw -FAYDVQQKEw1nMTAgQ29kZSBHbWJIMRswGQYDVQQLExJLZXJja2hvZmZzIFRlc3Rs -YWIxFjAUBgNVBAMTDVBldGVyIFBhbnRoZXIxMjAwBgkqhkiG9w0BCQEWI3BldGVy -LnBhbnRoZXJAa2VyY2tob2Zmcy5nMTBjb2RlLmRlggEAMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQEEBQADgYEADoBAUnaZIjp+T60s1at/tLa03TfYT8DdTQz+p/UF -MFGPz9CTqsoN7NLFoXyq+RN9FipsGEKLMif7e/buRqlcir+ntxqQFdy6EYfxfu4n -Dys8JxnhjcEqXSz+uPUE8jiGho5Tkveo+hurDKZ54CVTeJtvKrWpA6YkuhmL/zRz -T7Y= ------END CERTIFICATE----- diff --git a/tests/samplekeys/cert_g10code_test1.pem b/tests/samplekeys/cert_g10code_test1.pem deleted file mode 100644 index 61d1f9813..000000000 --- a/tests/samplekeys/cert_g10code_test1.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDFTCCAn6gAwIBAgIBADANBgkqhkiG9w0BAQQFADBrMQswCQYDVQQGEwJERTET -MBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEwIENvZGUgR21iSDEZMBcG -A1UECxMQQWVneXB0ZW4gUHJvamVjdDEUMBIGA1UEAxMLdGVzdCBjZXJ0IDEwHhcN -MDExMjAzMDkzNjM4WhcNMDIxMjAzMDkzNjM4WjBrMQswCQYDVQQGEwJERTETMBEG -A1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEwIENvZGUgR21iSDEZMBcGA1UE -CxMQQWVneXB0ZW4gUHJvamVjdDEUMBIGA1UEAxMLdGVzdCBjZXJ0IDEwgZ8wDQYJ -KoZIhvcNAQEBBQADgY0AMIGJAoGBAODOlvkLbJ4C85Ir6tqT/lCoderGvMGLuanP -LoSWXKotH/laf1QkZcbAwZ0nbkUmzgSIaKepFP00PMOofddCkf/FZVBtW7sly6xq -Di3R+LyqsNSinC83yVDzY0hL8mn3iRRARkuveYJ+A6NucLgUk47r3GPpZCR7513F -iwFLfqJRAgMBAAGjgcgwgcUwHQYDVR0OBBYEFDM3jRKRwFRxgzhfCGW/qUv5jjTz -MIGVBgNVHSMEgY0wgYqAFDM3jRKRwFRxgzhfCGW/qUv5jjTzoW+kbTBrMQswCQYD -VQQGEwJERTETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEwIENvZGUg -R21iSDEZMBcGA1UECxMQQWVneXB0ZW4gUHJvamVjdDEUMBIGA1UEAxMLdGVzdCBj -ZXJ0IDGCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBshwQeijio -2hsXZxZEIFoNldDpdxcbWUws5utNJ7hqxQr74fn2cL9rH7AycNWtZnyCTAk7Uqwc -bH3z6CNoJH6U/k//ITk7w8PtM6nw6JhlXLD+C65Bifip6id2JtRQwl4kJ/tPpx+/ -42Muki3yVFN+BEGFPpI6hdJmh1Hz81k8GQ== ------END CERTIFICATE----- diff --git a/tests/samplekeys/cert_g10code_test_ca.pem b/tests/samplekeys/cert_g10code_test_ca.pem deleted file mode 100644 index d65a84c52..000000000 --- a/tests/samplekeys/cert_g10code_test_ca.pem +++ /dev/null @@ -1,27 +0,0 @@ -Issuer ...: /CN=Root-Test-CA/OU=Test CA on Kerckhoffs/O=g10 Code GmbH/L=Düsseldorf/ST=NRW/C=de/EMail=test-ca@kerckhoffs.g10code.de -Serial ...: 00 -Subject ..: /CN=Root-Test-CA/OU=Test CA on Kerckhoffs/O=g10 Code GmbH/L=Düsseldorf/ST=NRW/C=de/EMail=test-ca@kerckhoffs.g10code.de - ------BEGIN CERTIFICATE----- -MIID4jCCA0ugAwIBAgIBADANBgkqhkiG9w0BAQQFADCBrTELMAkGA1UEBhMCZGUx -DDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEw -IENvZGUgR21iSDEeMBwGA1UECxMVVGVzdCBDQSBvbiBLZXJja2hvZmZzMRUwEwYD -VQQDEwxSb290LVRlc3QtQ0ExLDAqBgkqhkiG9w0BCQEWHXRlc3QtY2FAa2VyY2to -b2Zmcy5nMTBjb2RlLmRlMB4XDTAyMDMxMTA5MjUwMVoXDTAzMDMxMTA5MjUwMVow -ga0xCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8c3NlbGRv -cmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxHjAcBgNVBAsTFVRlc3QgQ0Egb24g -S2VyY2tob2ZmczEVMBMGA1UEAxMMUm9vdC1UZXN0LUNBMSwwKgYJKoZIhvcNAQkB -Fh10ZXN0LWNhQGtlcmNraG9mZnMuZzEwY29kZS5kZTCBnzANBgkqhkiG9w0BAQEF -AAOBjQAwgYkCgYEAyyMceR+2i6B111NZDqVzCWjB+vcymaKoNxM58+4nNjr08afx -3M2duMX6oOapbxvpgdZOZhV9lbDMFsZ9Sc/8r8nPwKuTW93cS2qceTI12fOPd1am -td53adxR9/7HdnG+2EUWcEO6bNtXSxHcWhGGFjSspKQekrszFZFabdTwGR0CAwEA -AaOCAQ4wggEKMB0GA1UdDgQWBBSKWA3OxYhzg75qeDUKxe5e7U3KkzCB2gYDVR0j -BIHSMIHPgBSKWA3OxYhzg75qeDUKxe5e7U3Kk6GBs6SBsDCBrTELMAkGA1UEBhMC -ZGUxDDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMN -ZzEwIENvZGUgR21iSDEeMBwGA1UECxMVVGVzdCBDQSBvbiBLZXJja2hvZmZzMRUw -EwYDVQQDEwxSb290LVRlc3QtQ0ExLDAqBgkqhkiG9w0BCQEWHXRlc3QtY2FAa2Vy -Y2tob2Zmcy5nMTBjb2RlLmRlggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEE -BQADgYEAkYHZYROou2z2MavOVFOdY5nUPqgqTHlD5z2ADotCekdiRQ7YsJHHqDaE -wRdGxVxNvFPa31iA+VeZu4YTaOiAW0lFZ7SYYwjRvKjs+CDQxkPVBWxyB7JNeIOj -tWyK4FTrzcu3aNgfIJxMuzYU8EUwuwwPr+GxYP5GUFSVhP+VOsw= ------END CERTIFICATE----- diff --git a/tests/samplekeys/cert_g10code_theo1.pem b/tests/samplekeys/cert_g10code_theo1.pem deleted file mode 100644 index a7685c415..000000000 --- a/tests/samplekeys/cert_g10code_theo1.pem +++ /dev/null @@ -1,40 +0,0 @@ - - <GnupgKeyblock> - <mainkey> - <keyid></keyid> - <fpr>E76B5D4BA2CF0B05BBBE425CDBF4E9DC4904941D</fpr> - <algo>0</algo> - <len>1024</len> - <created>1017250241</created> - <expire>1048786241</expire> - </mainkey> - <userid> - <raw>1.2.840.113549.1.9.1=#7468656F62616C642E7469676572406B6572636B686F6666732E673130636F64652E6465,CN=Theobald Tiger,OU=Kerckhoffs Testlab,O=g10 Code GmbH,L=Düsseldorf,ST=NRW,C=de</raw> - </userid> - </GnupgKeyblock> - - ------BEGIN CERTIFICATE----- -MIID9DCCA12gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBszELMAkGA1UEBhMCZGUx -DDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEw -IENvZGUgR21iSDEbMBkGA1UECxMSS2VyY2tob2ZmcyBUZXN0bGFiMRcwFQYDVQQD -Ew5UaGVvYmFsZCBUaWdlcjEzMDEGCSqGSIb3DQEJARYkdGhlb2JhbGQudGlnZXJA -a2VyY2tob2Zmcy5nMTBjb2RlLmRlMB4XDTAyMDMyNzE3MzA0MVoXDTAzMDMyNzE3 -MzA0MVowgbMxCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8 -c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGzAZBgNVBAsTEktlcmNr -aG9mZnMgVGVzdGxhYjEXMBUGA1UEAxMOVGhlb2JhbGQgVGlnZXIxMzAxBgkqhkiG -9w0BCQEWJHRoZW9iYWxkLnRpZ2VyQGtlcmNraG9mZnMuZzEwY29kZS5kZTCBnzAN -BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2N+6T7awrnWhg1g+HIE8TGn3e8OOkqmE -v2k7uazL2aGUIk2Omg+2Jjq2dovotiSAjoVQFtJ+Ahk4aiGFA4Zdp34ZzijpXhD+ -+xbFt1Vz/zBWlExpN9A5m2XPAbcW5rTMcl9O6jXKgu4sLDXOGOVCSOIpaQGwB3g3 -ti/p7J4lvFcCAwEAAaOCARQwggEQMB0GA1UdDgQWBBQTVJsLsvwdrA5XJMZyCECy -gFdHGzCB4AYDVR0jBIHYMIHVgBQTVJsLsvwdrA5XJMZyCECygFdHG6GBuaSBtjCB -szELMAkGA1UEBhMCZGUxDDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9y -ZjEWMBQGA1UEChMNZzEwIENvZGUgR21iSDEbMBkGA1UECxMSS2VyY2tob2ZmcyBU -ZXN0bGFiMRcwFQYDVQQDEw5UaGVvYmFsZCBUaWdlcjEzMDEGCSqGSIb3DQEJARYk -dGhlb2JhbGQudGlnZXJAa2VyY2tob2Zmcy5nMTBjb2RlLmRlggEAMAwGA1UdEwQF -MAMBAf8wDQYJKoZIhvcNAQEEBQADgYEASILHzi6O8Gf4Xd98FFtln3FGLhlHlxKV -xuO4Qn+qcBN7dFfQE3B/WKRR5jC8NTZHgGzAzcVv/ha2AAVs/zbSxE6lU04OOSJv -qm9lo6lsm5P+C/NH/hSdlUfSoKbmt5ZAPYpOhHvmPQpLi4Iv4hjeFqoCN5OVXOXN -OSgvBzegSSA= ------END CERTIFICATE----- diff --git a/tests/samplekeys/cryptlib-key.p12 b/tests/samplekeys/cryptlib-key.p12 deleted file mode 100644 index 5c23e95a7f771231c438cf1d0ab574263219760b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1559 zcmY+Ec{G%39LL}HHB0v0WGR`^HKFO91}#b$ie$+aLe}hQW{~A3O~#Zugz3t3)7V0h zU3JS&Q_@u;j*BeW${pKfLd$)1?yb`wzw`W_&+qwu&vVZ6JrB&p$U~qA%tUu$M75JF zl7x~V7UVI}jVLDiF@hh!Oo;Z=2=YNOAx{LmA?1t_|4$_$20}b0m;y7wWLOO&_CH3< zrBEAYZolK)oA6hGAnZ#N6AXOl?F*!I>~~ocUVlJ9N53(MYdyDORL{?>3?|Ojh6lD| z{bJ12<tycdF2?|Jjwv4Zh#L1mg`g-Vr@Pgy%0ijg<6nM(c68*07q%$3H(t&mztbaS zvOD!X;{t&NMsbu@?UL;a9M;ChIMy*DC!7{5cGlPz__A$-!tq#Y-KlWObgOBB+pQHF z;(oR`cGuh9yu~U%uH22}Ay)3qy9wIYctsUcgt|H0u+s6u`<LT-?Hvs`)3X`!<qHF} z!sNXa@r&_}5pv8U$93nGQ+w18n18YU>#FcpWbxos;_Exh<`>ewG$;pId`*(#f2>mL zlbY><Jk+&`qQEY^5vFUDs53rp5|e$iz&$E!V_V_$?bW@|u-&)>Km87SE6Xc=lFIK8 z@b<*NI4-z2-yGLb*5;1p+fsX0y!s=e9}<05wtv<HYt-_lJ`30M1h`WVvnw+ij+n8A zC=29DDevWa#wE!WF8O>lEQt}-!GI``xl0xz1F-z}*A!JGV^Am%004N~52!#^+pGdO z0)ap{5C(Vy3}6f3jPwCODBus!Vc#EiAlZ4dBVY{#0lokoIl@5dBoKiJOuq^Jk&cQ? zVt~^KUALek{4`>{uGj+DeN#mtJHK^nghT;kfCRuWQ{=$+8(}d#rpP+dg+KsVw*Hua zKP3&bo-{|xi@J>FurupPOJG7D{b*bBZg^{O$jwf2d*g?2lONIPmJ)krjdyFX^;X&o zC_+nJ%WBKr(y?jzkcd*gjlsbj#^vhH!!9$=-`7RBrUvg`72Y=#>&nO<bkkkEK&YS3 zk)pL749Tk0JE7Vj*S*ODtX?n;A*J2MQ><nit(=xNcIf>Q%F>^UG<w0+>5kR@@EFb= z5j@KuGz`;6-LrY~DzKHq2yG28w#q--TXYjOap@jUF}{$iwPwy@OXK!gmJ?3}czW3% zw8yn7Tc4@9<HT#XCKY%30ZlDci9Mp4dTw0N?xmw;C5?2d@Rc{`SuoiwM_5uTYhh-Z z_-kL!DFyemfmBwsT5SQ!W^yT@ocey=N_#(DX|wESRkBtr_xI3Ep$1yngt_TMlM|9v zXEkS!cO9tEvSw^d>LoYsy3#^gJ8kZ(FqW8gA`cUF*3W0|$*V1MBLf*H2PK4m=EgVt z-FHMWr&Q-a@?&Da`PzWXtuvSOLhv>es8mKK#$*sx6f~n={xx&dtRy~V>}dO~So#21 z&vuGaF_lr4?=15ml|V^DO@YIr(TlM`0}-DHJH&(bStXb#7pUu(1ZQgG&j>C(Z5E)f za#4F<KWg?Oo!n&eTEDZq+Gp6cLe-?dN7nf+;ac<3b1uaNN1Hx;O{q;9PL&Na`08c* zD3YnMne)${TJta0gtc7>&#oNKJ%2l|@2Cn%GO;hy;>lC0`jBe}UfZBQu4F}Z-fx>& zx(sggFv0j<82hE%GJXfYWvZ$1d6DM!(ZJ!ixpvT<$S(sbSBOqB0?|W#r3|6uT3f3R z{0G)g;O=olsA29K;c&fTY>F;3j`DoR_3ZJlyKGiNEPC2vYqY^RDz<$293{g<dSWOp z-GjD!|NDt!JB`jU-tx5)g5Ak%*UGGib8O=fyI3be3$133zwaI9*O5<UuUZO?66H!# zWEYM+QEj-0zu#FzA6HRKpIVJJ=ItaE^_QZH)qeB+sNrBSzqF~==UtC-SGQyHXtsv4 z6P^4THiXq-EC#J3B?76S6i7-o35Kr9_}UL?_|lQ$zPv~V7p1V+w6YjL#^I%Spx~`l Mf96^}>)RLoFV)SL!vFvP diff --git a/tests/samplekeys/opensc-test.p12 b/tests/samplekeys/opensc-test.p12 deleted file mode 100644 index 990b1279ae427ef6471b82c864bad83f2cee3582..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2397 zcmV-j38MBef(cmy0Ru3C2_FUtDuzgg_YDCD0ic2j5Cnn=3^0NT2rz;M2L=f$hDe6@ z4FLxRpn?VXFoFg20s#Opf(7jc2`Yw2hW8Bt2LUh~1_~;MNQU<f0So~KFb)I=>mAsy zI6Jm=0s;sCfPw|UhjCH}pQab}-1${G6ux3<!9h{M^t{)#cVST}B0gt9SG2+W*%hH< zwJ;S<T}umW{>FGPY+{(vtvMO7AaSr0W_@BR+=^7}>UGt6{kbeJ0pZsUXkgqi5pN=q z7f3jB)IoFhuLB0rk1~t$O}Bx$HOdVqvyU2WIT&u8Ui>NVqDVqqUTU3Ts_*USt1%V_ zSmPrQ!j$9&Mx<sbp7=I`!A((=@L9YZbM85I(NRlt0@WwMVmXav_i`3*+>Q$#XDXAK z!}G$%qSAI%k>y!!FGO=5ZSl)pt1He|Svm*KcSOZ8F*Acb%Nn@Qy&oYvtiBT`)#Dv6 zT(}8Xdkp%}kG_t@KGF?Z>&FRf48^O(LJAij^T8>~c(Tb%^->W5J?MR?iNiC3$0dDI zSQO;x`oH6^zw$0BBp2tE95m~`i`PSSfJhFT5!7m-H0XXM6h?7=g^JxdhC;{01MBHg z6u@&YKj}Rr@e>>CP(U~X<S3a{*!c9W>d}qA;h93WgPTX~|4$|Q%fWQ=Om<<<7B#VU z*P~KQxdas!jA+urK+FqM$3>|`Gvbk;*ZH$&KlM4k5GbWFWUoVppq$YV@QM6hV_#LA zF5VB6LFisLA+dSmz6y@8p=q?tA6@y2m#sG|m1f*v{W8>>->~z0pyI@RgyL=b)?YS` zb2)=RF~r=uu>nfBqHoS(SEQki1#6wpbk5JXZ34n4E6*WGRs@+12q>%L%exdt=W8d9 z0Xi}Xk0&GmKi|G1J)VF)Q8y_bPoGZMNJ7+ALSA>*)WLO|=)PEIhs$JGeeNr$gPIHK zYvh#&IuT$~GNpD0%K`)Ho|;pAj5$eM>uL=aK-aZivTGIq(i5>-Vd`UUHe7aIdHxih zN#5Su?4~3+_xr5r&T4d)W>s8afR9LF%ml(wnmsyM;j_M2lt)>R(U)}Tln>I)MHZd= zD`_IP&#coWMhsW11dmqzXnkfgcyqRRp1rK>ZLA*x(y@Oxb;PRQr@?mZ{yHwT49<_> zcvn+fI$c0q3Z%i;8mD>g=#yS{v};4cBmURqaP%V+6Y&!(^L1!BPpkyatm(VeL7ZHu zgQ|2X<Bi^&Btk`Bt0sRc65x!tDV&YE#c)cZ^AJA(1krY=AL8g{u@;jCN;+b{BZ}|9 zhym<nGmBT%uPzYOQ4rs%<Qsugr8dRapG)h#vD}hDTszC~_az2Epi`_Hr;<^+BSnpX zM%IhlX4PT@v2Ye^aYAB+mPUL5KIJCf$B#d=qZN8z9rD+YV3XE+FU-LTf5-4D0Ge@j zYyqnpqU0v?^h<>O5Ed~1F19jv>kS&j5PS`a(-_Uxy??%!&wuQM6a5kJgj(@NRao&L z#=Y^FOZ4R%AV*PTfeQAyy%q6J+t>mQh19CCoD*H~$nRn&7KKn9vtps97*doH=#C=J z3;QeFzT$F+#>1tBVCSz1@#y@F(yR86w@pPlJgV~7AX{_ck0s)2r?6q4AOgvO^}SUn z5q7g?a$PHZ(L~x}IEBM7MT|b;21c+;J*%cATQaQR8TO8({qb@Ec4g0#I9w<QaT1|S z&r(F`qaNFm-`Yj9BA0iI!d`LE1W+;l0eMShMNqzP%#pKTkEAzbYUS>R;@>I@47fR0 zt3<YI^5!Jd8(^c5G2E}+d7J7B09sK956a$<rR6c^6A{yZ$C$4)9qPsir!oVD=tk}# z7MSNhdbQcyqx#`Bm8N0f;mxjevwpCx!wZh!eFUmonn7Vz9Dhj_nO>tmuI-%LvwI2T z@23Fg49Znp*WWhQPoHHm_U<enCBgC@o6UZCDZ`_;h+0Iam>O4J7%zjwgTfP&HlxRu zao1I_FG-CB(RDt%c{m8pB)A8FWvc-tPyQ&3GgM&wVD37;{o&80R)$Gh!+3f{z1a_? zqH}|wVkggOZNIH|kcoV(IJ8UDoXUnaxOLWDFoFX41_>&LNQU<f0S5t~f&%IUf&%6+ zf&$_&f&$(K3o3?4hW8Bt3<?1Ppn?LXFoFW2FdPO7Duzgg_YDCI0Ru1&1PC(_hNV`( zR%!wQ2ml0v0)Q<A<O}*?m2w<th!<mp;w858|Lwc<RssSMyH1O+FT1&X4+)$UM7<o2 z;rRQgDp2PvJjV_3j_BG_DIHUR%ryrx;=4dn6#&B&pz+0OjTYzT8c-kqadcVg?6B}i zUd<Eu!Y65qYl6uoG#;7M2oZJe&1+bYygdJ!fZB4Mw=co@h>X(3fjOU!cT7;~IvVk5 z3zmJJTUyXT9g-)fEG*Q(zJrhU{QZvPzdnlpXLE0ACj7ivAQqfLdwZ<bkQ!x<V$IJc zW1KPU|A&>gD~i#GatJ%POMawHYlcFoY}tXjERIv^1Zmw{^d~CBzpF?P9H#;%cp024 z5p7Hxf44nax3&ZNm};&jk-W|GGSY*dpv6i#MOq$1(dTG3`F8cduJeXRKYQ(7d1p|l zKjm@V?iTa1MJ9Dd>myY}C+^wgE=5;cfXIv8S5z%xfU{UP%Q`Cr*qIXzKDOfBFX^!z zsJk<6MnSVzLD3KSlJ?BfrYqo5FuAk0+_Zs-2gBAv!aung9$F-;QV|_IdkSdK@wscL zZ8eqVI70y9XKpBymKUo2C59N=04+&BFD&4}1Qu~#0A9jGwr_kfvMpUa>o%YDASTXT zymX$^Q91?$@BeB8sf^+yu1#B`F4>q!&onn4cak!%M2?2$#J|M|1VJ`+4_8+Zu(lnC zEW9;06K%kBLeO6*PJ*nQp9p`44qLzTYAk^_5wUL8XIN>{2GDq98JJh=IPtX?#66XW zYes9HNY^^#|LXzOlp~fj;T(obc)Pu*6}-708>yzgx(J4x0#i>N4=8zP!Zx>3#LDLD z5~C#~3(uFQd+B{skHszn_TgAzx7ZoUnYuA0Fe3&DDuzgg_YDCF6)_eB6cJj#!>(08 zlBIgybQgc^`9+%b(l9YFAutIB1uG5%0vZJX1Qdl;EleNQ?-KMVmKNYj0Fzg(i$w$o P6s*ca*=0YZ0s;sCD0E(z diff --git a/tests/samplekeys/ossl-rentec-user.pem b/tests/samplekeys/ossl-rentec-user.pem deleted file mode 100644 index 290b0ef0d..000000000 --- a/tests/samplekeys/ossl-rentec-user.pem +++ /dev/null @@ -1,44 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIHnTCCBYWgAwIBAgIBATANBgkqhkiG9w0BAQQFADBGMRMwEQYKCZImiZPyLGQB -GRYDY29tMRYwFAYKCZImiZPyLGQBGRYGcmVudGVjMRcwFQYDVQQDDA5SZW5haXNz -YW5jZSBDQTAeFw0wNDAxMTAwNDE1NDZaFw0wNjAxMDkwNDE1NDZaMFcxEzARBgoJ -kiaJk/IsZAEZFgNjb20xFjAUBgoJkiaJk/IsZAEZFgZyZW50ZWMxDzANBgNVBAsM -BlBlb3BsZTEXMBUGA1UEAwwOS2Fyc3RlbiBLw7xubmUwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDBoZHGO+Ikq/Uhb9a4nUBuKayowUVga0wPQCiWhoLV -u2tDVWf7U9uzFrz/6JMIIBT3MIe5hBgQrYWq80/na3WO+H7vd4nR3gUfPBrfDPCm -HPm9nRMV1BsnFeg+2O0N+mfci2e/PLu7Ph9Arrr4+C0IVKQWxdNiqYj/gA0mSYvw -aThuBe8px3PZPAosZ9oGuhKmT+J9JtGe3qcyGPoW6yPEVpAUff0EFBGFI+wvaRV/ -vlK2omekQ2GkirzMqywTYiBPMuQ0abIjWZJn6ThR4FspIFLDAFnppwbZHMozrBYm -vS7pkoTK+DGVzk6kdbRxugWr61q0CQfL8b6VdfB6SGqxAgMBAAGjggODMIIDfzAJ -BgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCBeAwHQYD -VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMFAGCWCGSAGG+EIBDQRDFkFPcGVu -U1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZSwgaXNzdWVkIGJ5IFJlbmFpc3NhbmNl -IFRlY2huLiBDb3JwLjAdBgNVHQ4EFgQUh6HtcbLmbeEAQSpU73jYI7Ap0HUwbgYD -VR0jBGcwZYAUXqKKaiAqs5Gz38Yq0UGucAGbLd+hSqRIMEYxEzARBgoJkiaJk/Is -ZAEZFgNjb20xFjAUBgoJkiaJk/IsZAEZFgZyZW50ZWMxFzAVBgNVBAMMDlJlbmFp -c3NhbmNlIENBggEAMDgGA1UdEgQxMC+BDWNhQHJlbnRlYy5jb22GHmh0dHBzOi8v -d3d3LnJlbnRlYy5jb206ODQ0NC9jYTA9BgNVHR8ENjA0MDKgMKAuhixodHRwczov -L3d3dy5yZW50ZWMuY29tOjg0NDQvY2EvcmVudGVjX2NhLmNybDA6BggrBgEFBQcB -AQQuMCwwKgYIKwYBBQUHMAGGHmh0dHA6Ly9jb3VnYXIucmVudGVjLmNvbTo4MDgy -LzAuBglghkgBhvhCAQIEIRYfaHR0cHM6Ly93d3cucmVudGVjLmNvbTo4NDQ0L2Nh -LzAcBglghkgBhvhCAQgEDxYNY2Fwb2xpY3kuaHRtbDAlBglghkgBhvhCAQMEGBYW -Y2dpLWJpbi9jaGVjay1yZXYuY2dpPzCCAQUGA1UdIASB/TCB+jCB9wYKKwYBBAHD -SAMBATCB6DA4BggrBgEFBQcCARYsaHR0cHM6Ly93d3cucmVudGVjLmNvbTo4NDQ0 -L2NhL2NhcG9saWN5Lmh0bWwwgasGCCsGAQUFBwICMIGeGoGbT3BlblNTTCBHZW5l -cmF0ZWQgQ2VydGlmaWNhdGUsIGlzc3VlZCBieSBSZW5haXNzYW5jZSBUZWNobi4g -Q29ycC4sIFRoaXMgY2VydGlmaWNhdGUgaXMgdmFsaWQgb25seSBmb3IgU1NMIENs -aWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJlIEUtTWFpbCAoUy9NSU1FKS4w -HAYDVR0RBBUwE4ERa3Vlbm5lQHJlbnRlYy5jb20wDQYJKoZIhvcNAQEEBQADggIB -AGgYIKrR5nQKICNuXl1OwWFwk+CgnbDrVIrIoFiwRlSqaNsedXMXIDYHdyE/LYwR -VaiHFimV5WywIPeoBKiws67ZcWVfGGvxF2CZuCcnuQpAyKn+J0PDAaTi3z/uoi4n -YPUVMpfU/7TPXVo4pjFfUmm9XJ6dduC6SlAN+1/xDRR1dy2WqNLcN1dpyoUTtEWp -Xvp7I66oLfWahKs0d4fOXIrZmyLqKN3H8CLrZPz8b4Skw+wWxEUIqJEkRKez5adK -Ry1VK21nIwUUWHfLvrqw4CgZvpMQVEZRhsiOPqlHEH+epDV4hD5/OCG5oK+8RoKA -Yw1xjs3gOCCf6GDVrftBBLsYQufL7E4BOD4RKDYQCo6HD7cHXfy+RttdIcKzlq4u -6QbzFgIkc3KF0/U5FpvKxQHyfQwoD8AORWF6myjGtM13ij8yXg4Mx1sgKOY9IK1/ -muLauYAamNdCSkD5+0ecmYJ98G7022zUTBE8LR6FFHAG+3F8mzP+oI2eOwJYzMFW -Zw3MNUCarArIyxts/+izpOEIfkf0ztx1TckCTGd/F7WAkQcDHZHsf8Vb+eaLTltk -rEM6mnpov+YCO8qb/vmr2018fNS5haTJvECjLbYRy6RV2v6wRPNbYRHN3og87h/8 -2HUYfYCVebbJdzSwkQGApPty9mx2wr3EwB7KTT+IjXkp ------END CERTIFICATE----- - diff --git a/tests/samplekeys/ov-server.p12 b/tests/samplekeys/ov-server.p12 deleted file mode 100644 index 52f2d558d82ac366da2a894c77883c14dd801000..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2133 zcmY+EYd8}O8-TZ&wGrhMbIhr7-Y8_s%Otd6t%L|E#LAhM78*l_96}@;dmS@}%Auu^ zLXt8$q(shh%Cy(y5TCB=`@Z-4emsBf`+A;V&vhe6P#g#-fFMDoAu!DZ>x4BC;2t22 z1cic0Q1C7WAV}bye-wm90&{oKA_(}~O#fqm2ziLmzc1_sLJ*>0s6+lOdiZj<CkO-u z#FD^GUMnCg_WV%P%&j_~0xKVHf6f;)h|E=FstdvF8;p5ViW#((^<(aD^sH5sqkfIG zNAHZRzk0QBt*H`gai1{vHts?qs=Pb~5OTqLJl&X_FspOJ4OyvAz;ot&8xJsN!Y~HB z_Z@>#l)uNdD@a|k9$EUo?6$>TONlKijxPgBwTadKH;{yFIfEv+h+@xdTJX?G;*Mz7 z`S{^}H;zraA_6A1{YW+HyVho)PVw=jANUTLZ(Bwhwqj5^hx^q+{e?@+g{p0+m3T(! zCsBoIY)TgGgJyO6{$`vH8~}Iua#8VXyOUR|+e2bjS-)ari+c4}g7zre_{-Hxq?Mv4 z8fV*YlAjRcv(TDrX8^Yr0%~abKfO8H4*gupP($kTAL|~@QI*`h)cSq{PoOx~0prEo z5xviHGs~15*i_z&mNSHu^C1_h<GS(bqhbfl?>up8*4=)0zjL$T6Vm)I*KELML2%Z4 ziwi*}LU0*k9Hq8@99XYW-t6x^re}78snOU`{s%n`Ptj$#*gG{2maO(<ro3|WhlOa0 ze>{v_v<MOju;WR@o~?bqDQG+~AUs-jD5%x&YH0H*!7D}v?}LQ2&UQSu%w27B$8KM_ z<yu?%;RTRfKUl6y?ojxMsjZnwx$Pjbk2&$Ncy3smj?FbtQd6O3U?FO7v`nE%WrDw- z9Oq?LmNPSY!&a<tl|SAc-3>8opLA5v{Lv7B1G?z1`ADJJF>k!Dd1EFen|g-IyHLC+ zdT@RIc4F)l1U<E-ytVoCt#m$O5(mJr59cT@+7vjM1dUjkf9K@i%X;?I?rwoji(G;j zUXIlC?33DX9eir)X=Zw2K3p=c$Ufz#hdN33A$_&B&FCyGetoS3#%P@@Gzygz$|+u$ z^!PIoWgNsql^K3)<`<BIBf0`L7IB{PcISz<HYoKiU~@N`D<8OMDsfJ#+Di@c80=dV zQAsiJ#1ue*=LGPc0(J+F`T`|m>mQ}(5A5gIQf1x;oZ5TiE#)5U*PBPy3HX^dUUXc{ zvAz?=1FMl#E0}kI%Xz);Y7t(5r9ew%DHEqjdAdv$TW}uZb<xX_?kWd<f=4{a_GQN1 zY+~)db>-eVm9EMqPnu}?K>MrR>z2|74a~|}f`#QhUmIjBEi-(fDk~==U;#s^LQ|9c z=WZxhrRF}4&}3^`;)-G439iLC3p`G?YkJD+5_fN@kt%u{^c`CYVWZ}5CLN*D-FEK! zTEWurQ9)|?Y^rv*NQ5G#>JsWC@`z=<gvf?JHVvDT{-%$aV*BOLs#=*GM+Lj_SSY9S z8=S`X3zzGCd_Gwoqk^ctOq9KD1_&6g-@-*R^Gt{dehXHMH+|(J18gUn6S<8^A(B*d zV(X#9FT&w54kPKw;^4*&V!Gv#1lAKifftrL^G%0RZEfV^c#QlY>ALOmu*53gIZ_>Y z^IeT_%gH#Eo1Uxl!#QQHll03TnfBsE74pmp=|ZUpCClEFge%tCpxIXSmg*6l)4t*0 zSqen{y0}rWKo9O~FUK5glD9vv%`+AHdQZsq%Y})c2AhW?Wb3;`5KNVm)s<b7R@|%K z+Xx2mff^ilD1ro9|DVv&NT7Kz2{f~dCw6BPBK)812?0U7vUC>~|6dISe%COkH!aU2 zg6#OahP&&rF19~C6sjnno^n~tP={*mgPwAXcP)Is(|QbvKlQ1KExe<$3<JXK0n0sV zc_5O8cvQ@wW46UxRI*%AiGs)Ar}hwxetnk1jTc8??g!WWFQSp{f=0eS2Kwx!yp~dr zSiXMV4emDlb#kN3baKf5nNbF40FfA6SjuB29nRD{E%ME4Yd^hc?QiOBB5~{x<-jS~ z!apvsoPm`&XZGk{!zT-aE(2o9*?ZSm>h3JU;HGqk>7@`Um6B+hXow&~I7bxddna&o z+*LZBL3mEqTsRXMR=vkTonwI1^$J@L=VRU++Pd<vEdWH`^6YCTbYp}}U2K(*JMffO z!^_`iea3LWRPSa5La#s=)pFWyw1gog>-=LwuA+h?dAcB}!a3m_lfAG^s8Qn&<-JQ5 zq3k>mC^ZSRPcnJbzWDiSAIg`(68I)@s;pQnNxlplZk=Bz_fq=rGp2o)DndImBs&30 zN-}oViE~O3+Fos}AbyIF+X+%<2&fb)ID<`dWtT*eY)(vXYi0KxuTXx#%MA6iX+bwg z%HIvpj^<X0N9-h8f=Vm3f0=h>Umxo!5H=J|t`pH|E0f9|An@iF@|O}cl(kZB&z*^% zo*%jTIda>4)Kk5`$cN#pdJR7--y~FA?}jNbV!={pZifZN+srzs1f==+^^T7!b}QbQ zcp5sh??L9NAW(Bh7X?p~5U#~8GCoc{I~w-R9rE+lQj<SV$AVPC<{F3HK0a4xOMBZ< z6gc2wRkZ|HLAg!it%_(n7gJW8Yun9cj)r@0g}R_e3dQ__&IXG2Vm%T)x%(bQP^6!& zH?P>M=q<aD71+5=C<!2|^Lp31#b-05IzsioUk#H&9so<ib2r8aFKYy*;$1OJ<4x6E zBo2*0B9sv@h@h6J07zC40G3=CHx@Bwe8%Z*s%Fyjb3!9+O<Tawcxo*1gY{p~-{1W& Den#Rz diff --git a/tests/samplekeys/ov-user.p12 b/tests/samplekeys/ov-user.p12 deleted file mode 100644 index bb53a3d1a67e0eb047642d74fda038559f05eb7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2141 zcmY+EX*3j!8pq8TV`l7$5ZNhd%v58%j*#rzYu^>3ke#gWm}%^?WXql*vhOkW7$#$B zCbCAR2BXN<t0dCZIrrZ8-Ve`t&iVh&^L+ZB9|8}t2Lf0Tc!)R{st~Uqzt06=2N3WO zUJxF_c@jeqcsBNb5SV}meMjIydq4oo$=dvf01%>J*uOt;0>B7v5Jd45o142-);k~& z!h*wt`lW{OQ&l48b?0VlEh^GQu)=K>bGD)KBFvsLq1N~UY|92-XFJvko=?fqFzgMP zFz;0Yv(u1y_OrI^>@ifZ*6lvmvLE*11buV>q|H%MEF`RsXs;uDHj>5LmYNTp&%W<K z(oH;?p@?4LP9a<72cj?FrA+6CP&k<$n@XWH({0o%H>$W?N?W*kOy_#0h~v_1myC4d zBaVn)u5{13#>TgkY`T&AM%^J!YYAuJFCI6OZpJ=lnkegkuE_7yc`OUwjBsc3$CKO# zuq)0$!6X0se(v*u+)dYZG@eq8C<cD5E7(rQi5*>JjOMatSrRO<`KW`boKeuz95nV| zvQI11c<B8e5u*A+j60R1S<oi_d$RGt`Y^~SJWGnQ;umR=Cu6Gpb`93@jW5xsdJ~@V zjN&%spJ7>J*dRXgW`ER*P&iDy3zt$ezIML#+|ZA;$eQ={w+=7&&fcb|m+yc{sWQ^a zJC*@pE5m*#b*&m2uXyd!9mC)``7rQ6!_GaI={12#anAHGdyU6!=XxFvmwnI~FzD5h z12gG)By!K8Mq*zu_+o9$S^#nXmw=&3=h<-?&PGpSfWG#f+xC*w)9O{HRbzVApjBo# zjb$-&Z?IwLnca>D4;Qe<UFwWW$>BO{gq$j)9$$^Gcb5heZLN}nNZMdt?;GVEezPg9 zL$^H`s2!<3qk5IOy2Q$wUTcd2DKeoTXyGt09O1z0UuUPrMVhzpyc>XYT2zl~;`s|d z%oE0Ny%^OKpRL!uw{irH7(<!ALUs`wy52?HxJb9kKG(n1U!M%MaZz_zy-~8EY@wt( z$Mf|m>vXQUO*)Ovq9>ttpMU%SIPFf$<O~UAi`1mpb>wxXrJ%gN3mC5mhlP)%+EmX5 zS4YJ_(cEse{UMyk1|e+TMX*2sV=Z{pS*1E-mKYkh+T!u&8a>jZ7L%2@RyJa9d?D2~ zFiPZU61R$C@-cyB(n}tMRpY_rZSjc`&$)={mz|R@Q!AdHYJt^inO*82N7$;kvLvdo zo(XE~Dz|3}V-J=kTCX}eJ@EZH?edPdkL#WknMu52Cn2ptMsJl)ZgB;>+lq)6W$>#` z;s=??tQzl8H_WY`Cb%OsFoIt+nNgj<!d3XSqSv84`LDChxveg?)t6LVAw)}qY;6DY zLz?xqYK{mLMtWeLTWI0K%F*2O0-lYys7|eRw5O+m;&sXkAOrc5A~5~A{9dvgS;4fj zTMPCoBj6I>;pCr5wbva{qdqnQpl7UwCAca6TkjQ>#z3ZGLMnd!&)4hib*<zI!q#~t z4gYAq+A-=c9~vS%_9cf=v3_mwM;L~m>`B;DIHJOu%y+q_T#w`B@E+h+CRPga`SMrA zyMrix%Akk7*QinTaaebrixh2t?_u24;qy~KANUJI^-CQul24PbVOX?sdOazHfNkIs zGE6ue=oz+|pgYCopWXWPZEZbfb_mE;hDIya{+zJdl94-9(-LhYRHL$K`9|{W#V;wH zmRlyAxy6v~^ap523Kf)}Q`}aZ=AcP;e!h`FS2(!&o|?-6-4fPj)xJQ9`qZRR7Iv#& zPjJt2IxzY^E(hyfMK>&ei=2TX@W6xr5gq{#TnFKS%#)aLGD~2N|L6|}0G_~SCt=zD zS&{X(6|KPa(o1ju*7$A3lXF}p(_ql9+W@ZEPm694NNvw)r#HFSpmS${Atd<P)uz=# zPw65i+Vx{6Q--eDwPF6TglEB60u%V9Jt?;qbG*{`@d|my`bN0Q=bxD_Z{95vIBw1? zTo)+Gh6%_2V$(}QRd5gAX@h5<@f}XWko3KPlCd7dE2w^(^L+h3W695u=-o8q5<~++ z0Z5g>apm%1j*)z^*LSU+fF&+3KQ;ejVWpPcj+Sx<cS#(8s|+=HY0~YXV8i3?xvD|5 zo-oc6G<j119?#JvdjT}zrOrmBo#SUpv+~D%Ncx;3*|b>~%s5AW()yyx-2iBFi()We zv{SoxZb^>^IP&3EDUxU6$&c3L#k4(7?b~oW6>v?5L$oxMC%sK{U!!)%hQ+Ep!(;Ws zcT>8O49M(h3E-1J5F;!!lc)Rj&$t2LL~uf{*=wf9I!Ga^VmiI)7#^3w6$NueS#C$t zo{+_SQ|Vn-5T!-zZLjK=-QXYf9t-X{yZiKN8zZRN2a-=xd5f||ojmZWVy7k+3W0I4 zwZ6NAP~!-SYuV&N8WLw+m-~o;l+TKHI1)SP-y`xlQ{7799%KXcDvwr&VRe@`lN#Ld zZ)eZHEJ<AOYM4z^PCD)9zwvrXI)C|c`rH{ES<D-U{bJQD+$owPg(LB5!@j|<q#TvD zj2SbvqacTGZs?z)j!@j85Z?D;n)2o@5w|VjIls~sC7HzDl?hZRvcO5yAAHLy%^K{? zC2x!9HY<rR0xI5Nh8B0W8ED$0NHd&uMvJBLqEqAkvfbE7KxIkBU?Exky6k2&te*JA zaW3Y-?C_b8$=@F*lpGhweqqf6An0N6ifjR3=#e&379suLRzn4lf}qoSmesuPDbGi% z?x+z~<W&<*+y1~HkO)Zx6wG#!n-wU+#sWIM^ybSbRXahqXhbAq`JSm(vYUi42%>Yr NH22_BTITO|{|l6}@fiRB diff --git a/tests/samplekeys/webdeca.der b/tests/samplekeys/webdeca.der deleted file mode 100644 index 9532e3fa526f9d9bc4edfe978a9880c7ea155aed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1857 zcmbtUYfuwc6wW3gAqlZSFlcx!Pz3@ZH>gC!SOP(?h+-=u_=1oHRzk458x(03;uu7s z@)DIA2P%xTKC#6IQ{*wFQmQ~(u}Y~3;wTpIK|xVQy8#^-AN|vR_nh;6=YHqj?_Qu| z%7D&fRtb#?QK=9Oa2YJ2K3M;R3qf=f3dqQjZ~%)z3#T)9R7Idf0A?5iCeK14l6rf2 zN#T$fOpRmO1Vmy9%#AfRj};N<@2Loc<v|iFU}?;8c$}4(7AFD_4S`@18!*$DrSU9Z zA>S;%*1&@JW`vRGw;54-st{mr&GqpC-d=MglDX13k|=8~m`jF|S0TtK{eOC`!So5e z)22v*1LP79Ae@lw{I+CxRkB(wib5~~jYAV-2xNS~_s*b$oTeT#WJ00opbscO2eGL- z2%=Q29{r+n%&E}JvdZ~pTff)iOMBch!@67(E4&OALswfaF5CcBpEbMLa*dtD%^O{8 zcJ5(j-2(hzMF`@$Qpsa>Y$<WqF}qXdd0kqyCi<YE)u&^&BBi&B*>Er9meRgyZIyg* z&wVvI#?_t4sLgWVPrs7d%un<yvU=Xy_hP@JOw7v%%u~tb-&_6^y4lu1q;%#(OM;)t zTg-`u{avlr+wCvdr{$tGb@hg(_LAnhIGgn5do$-&oozIER2I~0&MZ6GtZ#Q4E<DvZ zQn_hQrtKn+U4x@;fBlx*SCcrjR}kIfP_cTJLwCV|d6xw4KHV<At&O%ht><Vy>9R-* zq|zV?bVNtZ1v+Xr@L;f_^}&$-sXs)gJMiri2x1eyKr9}&h3AAV#8^szT>KF(1J09Z zDxJ@_dKVh-CqXnii_awK<K!uM=0sjIo)=8wP3c@dM;wf*;}Eet$X^UBCTpZV8kNEX zW~5Q<cytp$gP@mSi7|rd{=g3`VsIu#351vs1jInZFm-1@CMHZO#CJ4GeRHmfjlz=E zXl$yOG|0!3yK(6{$d|8!q*INWlB|JW`BMZ>8WN5h!(bJPz;Z1fAEQKIBkoPpYS?TA z30bBkwrVx;MmUb(Q<{*$W)xG6b5)22maEnAND_i-$aN5c$0qc~5x5djp_+J-PbOW- z19F4KuUl+I5sWP07#f>Es8J0{LR4hax8D;E$0HaLkEjXHaY<w!9M)=7|J4ac$-36~ zyTI>1NSIWMBMHhF%##fy#*1;F3xO+`UGiaxlm4B=SWGRBjR6u*axwMQlAj|@M};UB zk1E=R2WzNkTi$V%K-4l|S08ieuCgfV=K=bzkwff=&wL|pwAPhlBFRzz$603_MJc!M zT5qF%p0JVLxtgBW`4#$@{oHDP4)YiLAMWf*U*wZ&k#_`ENE)AA-*+F=ch`=xIMOC} zS@dX}qICsS-+ehh;!<JHin?i(@D_XsYiK_#j7l3(9x#+M!cH`SZ9Big8^hdNE_CMl zQ0E13N1G$hU%o@>6F2qD+|l$>Ds#CSl==0owZh*6v@zlos~_)%<?miN;(R{x1Z3}T z4z3Tx-T3F)ykYIi-mXH;ixNY7TUl;Nc7bm-(NKFXM@7tFC&_{Z{m0^uJIuD-R3H~- zFO@D_?)%)|b6pW{hU2=V1M<U9cMI#6XFC;kcTNxKi<GfL%cJZ{)mD}}pVr0|;j_}* zToi?w7opvV>-8^(YxUv7(&+UMTy$dze!PSovg7Ejtk6G|E)OzUh5^Nf+T={ZmC7ad z<<J@x@oDw8hsD1#(>?z14%LR+35rciZ*1v2)-iPFc3E{>hl@+qzUZU<;A~p2!0z5y z8dpjr+IrjcZ#m-k?J|b#(wHYz1K$}I7i@3vT;x~mnojFuWqI%_!wtp4o)czxjZ8GZ zh_m0p)Lm9;UNCKaa7D<5#chKRO4awl^3=Z*BLzuE_f{5{oII7|x3RJFWCrzLMv|pn diff --git a/tests/samplekeys/webderoot.der b/tests/samplekeys/webderoot.der deleted file mode 100644 index 3fedd9cd091af3d4714e00d35f110634fd3dee47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2009 zcmd5+X;>3i6wOSA1cC@A7y<|kBC?YSK{0?VNq``-sE7*kv6z7jgv2i!i$x(wP|ymB zwJaiH-6|?7Zn%OJ5O+~jwyKqiXlqMx1HmSUAJ#6v`|sUz?mh2*_q}rwCGjqz)H+v* z2LTWS07Q?VW3S?=-sk}Uq=iGWH!^e)9RhwaM4*6NKZXfH(*#7y6t0uoY!??dI4Djc zluG0RltD%eG#rVdv&4_>%=LqP0~m$~S%c|Pbi*Zbsf>e)WT=E;iWqB9JcT@-`6c<O z2OWSqNv0|ENk!wG`6yy;q{m_*vt5`7i@}=Z8fm15XhLK>{NMGf1gC#KQa}rbSAzOD zL<y2WB?#c^t@BIlGor<%v1Jx<0&(Mg+n(NdmTA<i*2JQQ9^7Q+&ZCWr{e6G<YgaI0 zBM+Oc+3LRG5f9Jo=2|8l^(ydj$Jhr?92hp)mVbS5RO-pyy^*;3uVP3;Gaz50VtyOh zrY`#J548ImvP~G@({dKrw;GN%%Xi>!l_iV2m-334<xON>b4NmFUvNnk_eMoz$>C~t zjMvW2n3}fa_>rLe_I`t7A5@JiqZn?tQ<j^*ad~dTwD8?yYvGs<553;kI;~`Ba{s1- zwk;QVaba!cm0gO?noNEXH>9>ZD(Uq33II1`)UoPTS@~X|J#PoQWq1CghN9`g=M?Qh z@EN%IEuk7}%E(?cxZk7YRrQoi&OpM|i0FqLLC4BYmVLQum(Tho*CI$fYSAOt9M0|0 zlpGGvajoB-+?H*H4>(swJw-u1R+dMqmIiyooOPa;H5)S1v%gDUU;JT{m2^(xuMe2Z z&3RqV%{TfqMD8Ge-5bGKoqBVTb#*RbWH4{{9uIQu8}E_eIaiw-D~rUc0>DyIbAqzU z==j<f-^IbT_4S!m!+8otu21Kd67wa-Rtw)btdU!J_NQ%2X67VIIW}P9(xIln2z2_u zOVs=-dqYb~mwVuyLR}Nua4vG=80}tKtRY|3|GL(DHAS{)>JyLm2AQbvKtxD)>O*<~ z_sKI558!}ZO3+jNBjzBJ)UGh2Kw1bM06rjrnh1v2h!5gL(2Z5`0M%PRfT%Vp9dROP zI}iXZEg}d|Ed?^!N_RSa%qY$ujY8*P!UU8aCKh5V(&>m2up{VvRA2*okP<MVDgo+e zu7ed~5j<{2CwQS)EOUxPB{D1lOOBI~NL&nsL*%jyxhN6lW2h9B!V|PQNW~=lF$q2@ zf_;U;L^K7(MCx+@DqSIXk|2}DqkK%1sIFIow!Q&uJDC1SA_GGuYC<Z(RtRK5OoXXZ z_-fI=?*=KHh)U2zR48*EYe}smh2<jte<?{ZH80n!9r)kp1gpE1qJsE1i8Bc?nHZHe zq({{qpQZXTIzpY`h>#AINSBD{-qN|B<M@xbVhp#M$Oj=R)lk!d^ozGbrc5LO5QGPD zM8t6df*=d3*+13MB?^x3*e!ou+UgAh;GE_fr5Nhq`{y6@qdb0ayxi`_=9JL_udEBn zF<nNJT}!Wp&oQ7e)25w!%x%7s@cwq)fUIw7Z_he=kXvkHRG)hCzCZndO1rh`@v?f( z!nQrNX_(+%lC^2p^&4oiYuL{L3~m3>9A$dTrju5?+Vs<Zj~^k&a%D8{%<h&C(U%+Y zYxE3W8ff>G)hm7~O`EjF`N-P)CDXiu>nd4xo{W&ZA_1rB$2EZXX{bA_sylUP+beu` zL)So3A$BXbhd6kCmjJ#v+2)V>U*3gwXq^Gc8|sdq6x7u1ah$ukFvP*|b}%&1b!l~< zrAuoSX<2zTZCUkTaMR)Qp|aL?rFYrAl9`3`SQQI!l@4!=Y>3b9Lg6akQwu_iNy9TM zj8!`z-9s7S*~Fcf7J1u_l=)wXES$>2PL&VawzAlwr0t@${f?OSix8Uq>;7*oRsKQk zR&Lv8_<JVGkBO|KcDjHICs{QPpSMV}aS43;XvvhV*2^x3xf)mPj(FdZhnaa?#AWD5 zjOHs!9UR~N*5#&OeT-<5a=frj*}He>?CG?g;<5$I&N$)ot+p9guWU&Rm>Sqp<`&(n z>u0l3$JDecA!~oawDq$K>BjR7U7ETNZmJ^htF}e`+UjoV#|?&G^tBr*Ih+;$jX$L{ ey=xt1l{=;KLD<vFoPeh34&8TNbrd{CL;nPaefKK> diff --git a/tests/samplemsgs/webde-buenemann-signed.cms b/tests/samplemsgs/webde-buenemann-signed.cms deleted file mode 100644 index 9ed2dc1c42496226e91510d619639be311378975..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3368 zcmdT{dpK0<8lN>Yj9KFmMnmJaB)QLgYowuKqj4!jyHs>xn1!h^YAzIZF+Gu@gxDz^ z-JVoRDrGyBOIt}L+0`y7DH4ZnqR7r!gW}ZQ=b!V>+4ILd>%Fe`{l52ofA0c`s#L3F zujCIfL?IR=f<z(&p)^2MRk79}5t%9kFhKz#5DFADXP}@s0fmZL0f`6^i4Y0EUwuGi z+#)G`!~-dStV$>H+)*abQ^g4iU5jVSoyp;F5pTXkB$db`F;p99DrGR8y42l`#dAko zJy9K?t>n?@w8av+R5lkA%P<M552h%&B)ayP=C{Hxc~BvSx=d;45{reh1Q;;Vg&iHi zOpYCj&fwaiLAo%Qfs^PM36c){Z}IAa$)oXVOb7{?>x$X{tI?26zYiH%5-k$h24NDJ zFkHBXFT+L>{L35^(A0^?45<)E3TP4mC?J@qfFMHYvVosUhNfn7v`bB&G<0*`UE6M% z;@@JirjV1b)qA)8@|<9({Ji>;`ulJcylcQi{lc4+%30Dqh2EIO;!rxJX?=mUg3=me z&$+f_dB~pp+m21sc`<D*l<Jq>PeYArSCqQG+TJA+4#A2uNfoKajLEk))G^k$<mi05 z-T67!#EDJM1eD_FBj>cQ`o<dM%VL@{p?O||uJxL->fDywx|@uCF^bO+UaG9huf11L zR~fFKSod<ujMDQpDsK;awrNrhpQ=l~XW5rsT+?5&c6*9}v(4651D1~)GdeG=>D|c; zd1hR=%*?not4Fg1MOshabA2uk(LbF`6aUzv74J?YK?LZKf|vmm#57=|N)1W&f|5VF zL1eNq!!S}NTPvN#W{;EwYqTubl9;)!>>s2~z;s-jNM<l}{!AM%#+689DuaTXj~Gwj zQ%3pX5k7NVUyTeiXlyT`C>&$Edb+WJ*0>Chk3=L;fI40%hIFzDAVJVDn5U!=vKw## z&Z@N0RNNs71OYa%RaLWAg;Z21M2KOc4E5W*MqlI~EfR)pVB-ZcfBbDQSpm&vC?M{{ zLXC+QBV+Yxi;Nc}5<VnB1VRjPl}jV|p%|jn`?hGsFwDbM7RY6Ba&d%GU5ZI3IKhcn zp+qoZE5O8vt4I`qMPWiQ{_KfK!y?<lWztYgAQVU7_Bhi5KOjql{l!I`5R>2nsYDnS zDH93BLR>|FJN>?&q(}rN!6Gn`j5QJx?njEq#e)ClNh-wUa^-YE{`w#hJX$Fh8OoQi zV1Ozw#+YmcEWq@FX$4c0|I{!{B4UT}0m{N3CUz}897zfyM9_L$*wFXt5>eQ&t4P4K zt?x0c;_vGS%?Y~RL*ClI4_>-%_R@#9E00KQ(W7qfQqP#!#ys!P-AGJ`Tup9XM&8xD zSNIP8q~nlIxnXp%eQTn#;|8r=hY%iGGx%V4mn6BhVt`8H)>=D-421J;FNCUEZ)PsN zmi=sDr3N9OUfL_EzPH~hD84`R=lmn8{wHg}#x2LBHU8H1zcgn!67A>019gFAH`@uF z?Am8jHrEbwoy_lgrW|~_!s@rVay~mo=hqJZ%x!b}P0IpLLPl<y;6YFL!}s^?`{aw; zTC&BT3-a$Z9L^|6%bHy-tFE|^E|BTLQBGdW?h_G3#?uYfX1Q9W`Ecj>&Hm)ZTA4%F zGg%q+v+Mqk+pMbm(xzs&Hc$5M40M8hj|3SW5b0=d`B)L2BQ=Y+H0NcfT!yw`77upx zRU`-WaYI(UHdhQqy3ivxI~56^ruse#HGiE#&F|p_S45{UZ<Wk5Isz>h$QG4ve3N&F zl4$e$Oka6`Au~_yz{B;;Cz^WOpC2x7Xfii1-5qkY8=Q}CV;a63iif$fH3l>FyVoCb zIle&Ez=!{#wC8NTN7kllma|KqMIxz_nrcHY3CPd0dUjG>ddbPwA%~W0tY+<WKr>5Y zl~<v6ut&qI*9Syhz;DC9)&w%6j_xeUD>zl0?y|b3`BV}SC`beNoN65fP%>dSvhSNR z`CDKTj;jDiQI0+8fTH$5iK{roekDP|f5Pe*tgF#!JWMXbdtbyC3s45oQDP*84%>0K zGXcWGWKq!~0jh^j+!45+<bjEV>k&6OCdQ)pVlir_9N1$!3y$@SaHX6T`bGW)^^^WF z@l2I~nUs$2CaJ`vB*Kl8-st(@`{yj@cl=<QFe|ik)v~z93k!W>)?L)*l_fUQo$a*V zGVb=aU)_CTL(G$w=pW7)drK&jkericI;^Z0%M*U@-Anx`x#hx@CYbsM%kQkW!?B|E zoX+m+v#M|T4Ydvro6(M;(rgK0bSLKW>36xkIh%7+KFJz)gPx_u-lJ%h^b{mL{(r|R z%Zcb=z+ievF#H;XBE)^<KWub?3Bwnd?_urq#2XkHe)y(xwunE^QJ%Y{yv)R}Ib6|L zYLvRrmW4du7<ceI_n^7s=fr~!l9|;}`+v(z>}XAhHPa|D3~<?>cICs$Dz*2IWNyP? zU#8EUu97q2djBQGUOd9untwjY+m^EHxFOeasl&mZIpsF}i`2dRW(=9zzoUt77Ts-r zA4hp~#;U8c*TPt8s`KKy-j$LC_RjO$YBU5ck@}6dcB-}JQ}VCuHy|^PO<v>)^V`qG z>toUTXbaCmQH|3fX-90J^;;8o9jEtXt*h;{c+0hwdmOI6{6p=)@eG=0@QF7}jn$9k zR=(saN}N+#&R)?F>Xl$u=uQ>x(bj*K7Ga9=v%Af9_*|KWDxe}9l?(Aj8zde7J2X0R zbV5<az6lCePHaFj${_39L8tU<>NU(+q081R*4hE1liq*Cm;SF^N<wL02?_)Zz7kXw zbdqvx07ni7<=V}#w+{m2st`m@N}SRJ#cnmY5d5QbOWC!{kslncZ}Putceg$6#f@9P zs{1$|d)*b7&b%S<al{Tow&aVp?**}2*ZETXCwt_QEZ)q|tW*2YR8{mK$IP^AFeTKY z-YI{u{zRiF5_-9P-lgQ_lMCefdLK0;HDQBL<`a5ZRBpqKJHD(z2kjHu`^x7H5JrCg E2G=E*zyJUM diff --git a/tests/skey_g10code_test1.pem b/tests/skey_g10code_test1.pem deleted file mode 100644 index 9f2db8e68..000000000 --- a/tests/skey_g10code_test1.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,CFA7DAB8D1EEDCFF - -KTLOYLEGXYFQ63WnUsqFp/vM5HWsJq758AQ5RaYp7jbtCoZdrSp5GovmLUBTPfR+ -hjfcJgGlyWIPDhPAcOObz2XnnpzcKEfmPKR/W+Ou7DFX/6WUh1xwzHq+ddPnCMHJ -vfhx2iMf0e4Y9ZMATBPcU0YIE/Rp9F4wmMKmEAGtAPOSMNdvH17KHlNLXsX+VlXf -scGi9Hr0KFcC/5ehA3J40vBlAg6oZeXwNuERX1PXOpAIlcGY0RklJhTvTBonCfaV -7+CrfggFed3/b7QuqsNTlRdmW3ctf2rqNoFFIhRB5OVQsLG4CrzIQMdzxMqlZrGd -Eks+0HLOMGO41ioaenz6015ClHORpAf3VXN8NUUrrDAvJL2HVlqFgDBCi9qi9Dp2 -TuVePAkJlpBYodgIdwvLN//dav6ZJ+FOOk3A5AnKOtNyTGO4I2Bz8nAS3JpVudk9 -ca8CEIIj52dEric6YMiBFokoiIEgMOI/6wjatDL1Yldev+kjH/el+FZT4jZm2lvQ -l1xbg4sqmPNSyIKSv8V95gO2W5E5V9kO/MBiad2GdX4qrVT1c/LwFC96t+tZKFxr -rHdN31CzZE3bHnXxvss3ai+k9IO1NZHfeeb9uqSmGd3AxbmBwWA50bxCsee+HP0R -ihU2BE5NKdlw1faBk+DPVT569uScO4PDc6Jd4fh7g7oBzLhhhcCqNnLEZh8lqa3L -rsb880baq8dm72cz8IXj//x5AppfCz8M8od/UkaQ0/pN2GGTpe4qSPPK0YJ/4MfR -f9jdMbZA6O8si3t7I4jOF2z1UHkFGaseax54ILTsTVE= ------END RSA PRIVATE KEY----- - diff --git a/tests/sm-sign+verify b/tests/sm-sign+verify deleted file mode 100644 index 1c3ae7dbd..000000000 --- a/tests/sm-sign+verify +++ /dev/null @@ -1,73 +0,0 @@ -# sm-sign+verify -# -# Creating a signature and verifying it -# Requirements: a plain file "text-1.txt" - -srcdir = getenv srcdir -plaintext = let $srcdir/text-1.txt - -in = openfile $plaintext -out = createfile msg.sig -in2 = openfile msg.sig -out2 = createfile msg.unsig - -pipeserver $GPGSM -send INPUT FD=$in -expect-ok -send OUTPUT FD=$out -expect-ok -send SIGN -expect-ok - -send RESET -expect-ok -send INPUT FD=$in2 -expect-ok -send OUTPUT FD=$out2 -expect-ok -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo goodsig=$goodsig trusted=$trusted -fail-if !$goodsig -fail-if !$trusted -send BYE -expect-ok - -# Unset variables so that the files get closed. -in = -out = -in2 = -out2= - -cmpfiles $plaintext msg.unsig -fail-if !$? - -# Lets check it again with a new server instance, this time we keep -# the server running to check whether the entire message has been -# output after the VERIFY. -in = openfile msg.sig -out = createfile msg.unsig -pipeserver $GPGSM -send INPUT FD=$in -expect-ok -send OUTPUT FD=$out -expect-ok -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo goodsig=$goodsig trusted=$trusted -fail-if !$goodsig -fail-if !$trusted - -cmpfiles $plaintext msg.unsig -fail-if !$? - -send BYE -expect-ok - - -quit - diff --git a/tests/sm-verify b/tests/sm-verify deleted file mode 100644 index b06dc16a4..000000000 --- a/tests/sm-verify +++ /dev/null @@ -1,114 +0,0 @@ -# sm-verify -# -# Verify a few distributed signatures. -# Requirements: -# - -srcdir = getenv srcdir - -# Check an opaque signature -sig = openfile $srcdir/text-1.osig.pem -out = createfile msg.unsig -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -send OUTPUT FD=$out -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $badsig -fail-if !$goodsig -fail-if !$trusted -send BYE -expect-ok - -sig = -out = -cmpfiles $srcdir/text-1.txt msg.unsig -fail-if !$? - -# Check a detached signature. -sig = openfile $srcdir/text-1.dsig.pem -plain = openfile $srcdir/text-1.txt -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -send MESSAGE FD=$plain -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $badsig -fail-if !$goodsig -fail-if !$trusted -send BYE -expect-ok - -# Check a tampered opaque message -sig = openfile $srcdir/text-1.osig-bad.pem -out = createfile msg.unsig - -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -send OUTPUT FD=$out -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $goodsig -fail-if !$badsig -fail-if $trusted -send BYE -expect-ok - -# Check another opaque signature but without asking for the output. -sig = openfile $srcdir/text-2.osig.pem - -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $badsig -fail-if !$goodsig -fail-if !$trusted -send BYE -expect-ok - -# We als have tampered version. -sig = openfile $srcdir/text-2.osig-bad.pem - -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $goodsig -fail-if !$badsig -fail-if $trusted -send BYE -expect-ok - - -quit - - diff --git a/tests/text-1.dsig.pem b/tests/text-1.dsig.pem deleted file mode 100644 index a031ec259..000000000 --- a/tests/text-1.dsig.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAA -oIIDGTCCAxUwggJ+oAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMC -REUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgx -GTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAx -MB4XDTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkGA1UEBhMCREUx -EzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAX -BgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGf -MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzB -i7mpzy6EllyqLR/5Wn9UJGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7 -Jcusag4t0fi8qrDUopwvN8lQ82NIS/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQk -e+ddxYsBS36iUQIDAQABo4HIMIHFMB0GA1UdDgQWBBQzN40SkcBUcYM4Xwhlv6lL -+Y408zCBlQYDVR0jBIGNMIGKgBQzN40SkcBUcYM4Xwhlv6lL+Y4086FvpG0wazEL -MAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBD -b2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rl -c3QgY2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAbIcE -Hoo4qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJ -O1KsHGx98+gjaCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7 -T6cfv+NjLpIt8lRTfgRBhT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJ -BgNVBAYTAkRFMRMwEQYDVQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29k -ZSBHbWJIMRkwFwYDVQQLExBBZWd5cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0 -IGNlcnQgMQIBADAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJBTEPFw0wMjA4MDgxMjIy -NTRaMCMGCSqGSIb3DQEJBDEWBBR5MsAm+0wJAVQl3AAGYmnpxA4XLjALBgkqhkiG -9w0BAQEEgYAZpBbucgorq56kl2rokCV1EAZcKgylfpEkqSz4RU6qNid+0NtjSAxi -5164wjMLG71U9qSBX4XDdDQPHpH+PPF/8021kne2kPfeP68NiXK8CagdIqlnuJEj -K934mVre7AIjrXqoob1ipUtCWeK+2uHXsUjtUn3u1Y3eWVZ6+1hDTAAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-1.osig-bad.pem b/tests/text-1.osig-bad.pem deleted file mode 100644 index 0b5f4a439..000000000 --- a/tests/text-1.osig-bad.pem +++ /dev/null @@ -1,45 +0,0 @@ -The text in this message has been tampered. - ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCAJIAEggPh -SGlnaCBQcmllc3Q6CUFybWFtZW50cyBDaGFwdGVyIE9uZSwgdmVyc2VzIG5pbmUgdGhyb3Vn -aCB0d2VudHktc2V2ZW46CkJyby4gTWF5bmFyZDoJQW5kIFNhaW50IEF0dGlsYSByYWlzZWQg -dGhlIEhvbHkgSGFuZCBHcmVuYWRlIHVwIG9uIGhpZ2gKCXNheWluZywgIk9oIExvcmQsIEJs -ZXNzIHVzIHRoaXMgSG9seSBIYW5kIEdyZW5hZGUsIGFuZCB3aXRoIGl0CglzbWFzaCBvdXIg -ZW5lbWllcyB0byB0aW55IGJpdHMuIiAgQW5kIHRoZSBMb3JkIGRpZCBncmluLCBhbmQgdGhl -CglwZW9wbGUgZGlkIGZlYXN0IHVwb24gdGhlIGxhbWJzLCBhbmQgc3RvYXRzLCBhbmQgb3Jh -bmd1dGFucywgYW5kCglicmVha2Zhc3QgY2VyZWFscywgYW5kIGxpbWEgYmVhbi0KSGlnaCBQ -cmllc3Q6CVNraXAgYSBiaXQsIHNpc3Rlci4gCkJyby4gTWF5bmFyZDoJQW5kIHRoZW4gdGhl -IExvcmQgc3Bha2UsIHNheWluZzogIkZpcnN0LCBzaGFsdCB0aG91IHRha2UKCW91dCB0aGUg -aG9seSBwaW4uICBUaGVuIHNoYWx0IHRob3UgY291bnQgdG8gdGhyZWUuICBObyBtb3JlLCBu -byBsZXNzLgoJKlRocmVlKiBzaGFsbCBiZSB0aGUgbnVtYmVyIG9mIHRoZSBjb3VudGluZywg -YW5kIHRoZSBudW1iZXIgb2YgdGhlCgljb3VudGluZyBzaGFsbCBiZSB0aHJlZS4gICpGb3Vy -KiBzaGFsdCB0aG91IG5vdCBjb3VudCwgYW5kIG5laXRoZXIKCWNvdW50IHRob3UgdHdvLCBl -eGNlcHRpbmcgdGhhdCB0aG91IHRoZW4gZ29lc3Qgb24gdG8gdGhyZWUuICBGaXZlIGlzCglS -SUdIVCBPVVQuICBPbmNlIHRoZSBudW1iZXIgdGhyZWUsIGJlaW5nIHRoZSB0aGlyZCBudW1i -ZXIgYmUgcmVhY2hlZCwKCXRoZW4gbG9iYmVzdCB0aG91IHRoeSBIb2x5IEhhbmQgR3JlbmFk -ZSB0b3dhcmRzIHRoeSBmb2UsIHdobywgYmVpbmcKCW5hdWdodHkgaW4gbXkgc2lnaHQsIHNo -YWxsIHNudWZmIGl0LiAgQW1lbi4KQWxsOglBbWVuLgoJCS0tIE1vbnR5IFB5dGhvbiwgIlRo -ZSBIb2x5IEhhbmQgR3JlbmFkZSIKAAAAAAAAoIIDGTCCAxUwggJ+oAMCAQICAQAwDQYJKoZI -hvcNAQEEBQAwazELMAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoT -DWcxMCBDb2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rl -c3QgY2VydCAxMB4XDTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkGA1UEBhMC -REUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNV -BAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGfMA0GCSqGSIb3 -DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzBi7mpzy6EllyqLR/5Wn9U -JGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7Jcusag4t0fi8qrDUopwvN8lQ82NI -S/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQke+ddxYsBS36iUQIDAQABo4HIMIHFMB0GA1Ud -DgQWBBQzN40SkcBUcYM4Xwhlv6lL+Y408zCBlQYDVR0jBIGNMIGKgBQzN40SkcBUcYM4Xwhl -v6lL+Y4086FvpG0wazELMAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNV -BAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMT -C3Rlc3QgY2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAbIcEHoo4 -qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJO1KsHGx98+gj -aCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7T6cfv+NjLpIt8lRTfgRB -hT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJBgNVBAYTAkRFMRMwEQYDVQQHFApE -/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBHbWJIMRkwFwYDVQQLExBBZWd5cHRlbiBQ -cm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNlcnQgMQIBADAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJ -BTEPFw0wMjA4MDgxMjIyNDZaMCMGCSqGSIb3DQEJBDEWBBR5MsAm+0wJAVQl3AAGYmnpxA4X -LjALBgkqhkiG9w0BAQEEgYC+7rFtegP8v+Z5yI4CH/0Y4RK48DM1oFMSz4xySpERFTk9p5RP -BDhOqaaACVKUdmNW6xYJAFo53tQxbBTZ12woctFLbLm9rs/F6Tz2JIA9GxpXInkKYdvkaVHb -pvEQgeoezFc4fd4yB87kgq4zZTViFcCJ3OvjboCu9ltIeIn73AAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-1.osig-badusage.pem b/tests/text-1.osig-badusage.pem deleted file mode 100644 index 027f23ead..000000000 --- a/tests/text-1.osig-badusage.pem +++ /dev/null @@ -1,75 +0,0 @@ -This message was created by violating the keyUsage: keyEncipherment. - ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA -JIAEggPhSGlnaCBQcmllc3Q6CUFybWFtZW50cyBDaGFwdGVyIE9uZSwgdmVyc2Vz -IG5pbmUgdGhyb3VnaCB0d2VudHktc2V2ZW46CkJyby4gTWF5bmFyZDoJQW5kIFNh -aW50IEF0dGlsYSByYWlzZWQgdGhlIEhvbHkgSGFuZCBHcmVuYWRlIHVwIG9uIGhp -Z2gKCXNheWluZywgIk9oIExvcmQsIEJsZXNzIHVzIHRoaXMgSG9seSBIYW5kIEdy -ZW5hZGUsIGFuZCB3aXRoIGl0CglzbWFzaCBvdXIgZW5lbWllcyB0byB0aW55IGJp -dHMuIiAgQW5kIHRoZSBMb3JkIGRpZCBncmluLCBhbmQgdGhlCglwZW9wbGUgZGlk -IGZlYXN0IHVwb24gdGhlIGxhbWJzLCBhbmQgc3RvYXRzLCBhbmQgb3Jhbmd1dGFu -cywgYW5kCglicmVha2Zhc3QgY2VyZWFscywgYW5kIGxpbWEgYmVhbi0KSGlnaCBQ -cmllc3Q6CVNraXAgYSBiaXQsIGJyb3RoZXIuCkJyby4gTWF5bmFyZDoJQW5kIHRo -ZW4gdGhlIExvcmQgc3Bha2UsIHNheWluZzogIkZpcnN0LCBzaGFsdCB0aG91IHRh -a2UKCW91dCB0aGUgaG9seSBwaW4uICBUaGVuIHNoYWx0IHRob3UgY291bnQgdG8g -dGhyZWUuICBObyBtb3JlLCBubyBsZXNzLgoJKlRocmVlKiBzaGFsbCBiZSB0aGUg -bnVtYmVyIG9mIHRoZSBjb3VudGluZywgYW5kIHRoZSBudW1iZXIgb2YgdGhlCglj -b3VudGluZyBzaGFsbCBiZSB0aHJlZS4gICpGb3VyKiBzaGFsdCB0aG91IG5vdCBj -b3VudCwgYW5kIG5laXRoZXIKCWNvdW50IHRob3UgdHdvLCBleGNlcHRpbmcgdGhh -dCB0aG91IHRoZW4gZ29lc3Qgb24gdG8gdGhyZWUuICBGaXZlIGlzCglSSUdIVCBP -VVQuICBPbmNlIHRoZSBudW1iZXIgdGhyZWUsIGJlaW5nIHRoZSB0aGlyZCBudW1i -ZXIgYmUgcmVhY2hlZCwKCXRoZW4gbG9iYmVzdCB0aG91IHRoeSBIb2x5IEhhbmQg -R3JlbmFkZSB0b3dhcmRzIHRoeSBmb2UsIHdobywgYmVpbmcKCW5hdWdodHkgaW4g -bXkgc2lnaHQsIHNoYWxsIHNudWZmIGl0LiAgQW1lbi4KQWxsOglBbWVuLgoJCS0t -IE1vbnR5IFB5dGhvbiwgIlRoZSBIb2x5IEhhbmQgR3JlbmFkZSIKAAAAAAAAoIIH -gjCCA+IwggNLoAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwga0xCzAJBgNVBAYTAmRl -MQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcx -MCBDb2RlIEdtYkgxHjAcBgNVBAsTFVRlc3QgQ0Egb24gS2VyY2tob2ZmczEVMBMG -A1UEAxMMUm9vdC1UZXN0LUNBMSwwKgYJKoZIhvcNAQkBFh10ZXN0LWNhQGtlcmNr -aG9mZnMuZzEwY29kZS5kZTAeFw0wMjAzMTEwOTI1MDFaFw0wMzAzMTEwOTI1MDFa -MIGtMQswCQYDVQQGEwJkZTEMMAoGA1UECBMDTlJXMRMwEQYDVQQHFApE/HNzZWxk -b3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBHbWJIMR4wHAYDVQQLExVUZXN0IENBIG9u -IEtlcmNraG9mZnMxFTATBgNVBAMTDFJvb3QtVGVzdC1DQTEsMCoGCSqGSIb3DQEJ -ARYddGVzdC1jYUBrZXJja2hvZmZzLmcxMGNvZGUuZGUwgZ8wDQYJKoZIhvcNAQEB -BQADgY0AMIGJAoGBAMsjHHkftougdddTWQ6lcwlowfr3MpmiqDcTOfPuJzY69PGn -8dzNnbjF+qDmqW8b6YHWTmYVfZWwzBbGfUnP/K/Jz8Crk1vd3EtqnHkyNdnzj3dW -prXed2ncUff+x3ZxvthFFnBDumzbV0sR3FoRhhY0rKSkHpK7MxWRWm3U8BkdAgMB -AAGjggEOMIIBCjAdBgNVHQ4EFgQUilgNzsWIc4O+ang1CsXuXu1NypMwgdoGA1Ud -IwSB0jCBz4AUilgNzsWIc4O+ang1CsXuXu1NypOhgbOkgbAwga0xCzAJBgNVBAYT -AmRlMQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoT -DWcxMCBDb2RlIEdtYkgxHjAcBgNVBAsTFVRlc3QgQ0Egb24gS2VyY2tob2ZmczEV -MBMGA1UEAxMMUm9vdC1UZXN0LUNBMSwwKgYJKoZIhvcNAQkBFh10ZXN0LWNhQGtl -cmNraG9mZnMuZzEwY29kZS5kZYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB -BAUAA4GBAJGB2WETqLts9jGrzlRTnWOZ1D6oKkx5Q+c9gA6LQnpHYkUO2LCRx6g2 -hMEXRsVcTbxT2t9YgPlXmbuGE2jogFtJRWe0mGMI0byo7Pgg0MZD1QVscgeyTXiD -o7VsiuBU683Lt2jYHyCcTLs2FPBFMLsMD6/hsWD+RlBUlYT/lTrMMIIDmDCCAwGg -AwIBAgIBAzANBgkqhkiG9w0BAQUFADCBrTELMAkGA1UEBhMCZGUxDDAKBgNVBAgT -A05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEwIENvZGUgR21i -SDEeMBwGA1UECxMVVGVzdCBDQSBvbiBLZXJja2hvZmZzMRUwEwYDVQQDEwxSb290 -LVRlc3QtQ0ExLDAqBgkqhkiG9w0BCQEWHXRlc3QtY2FAa2VyY2tob2Zmcy5nMTBj -b2RlLmRlMB4XDTAyMDkwMzEwMzg1NloXDTEyMDgzMTEwMzg1NlowTzELMAkGA1UE -BhMCZGUxETAPBgNVBAoTCGcxMCBjb2RlMRAwDgYDVQQLEwdUZXN0bGFiMRswGQYD -VQQDExJFbmNyeXB0IE9ubHkgS2V5IDEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ -AoGBANsmhi/X6vesmlK6Ikc+KMjfRjewoEgjB3L21c2W7vkF19ZQqElXy9PMzXIK -nJQetDD+UIjmqN3Q1XcFBqMU3bT1eaJpb7U+mOeodQ9AABapiF0cH10ZrJDRhhht -9LNU873Kl4vL+xgQ3+WraK/ksrCdH4IjJlUUr+zfWWYo+MWPAgMBAAGjggEjMIIB -HzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFIDAdBgNVHQ4EFgQUxWTiIXcx29tl0D0T -Yl9sQ4z4foIwgdoGA1UdIwSB0jCBz4AUilgNzsWIc4O+ang1CsXuXu1NypOhgbOk -gbAwga0xCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8c3Nl -bGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxHjAcBgNVBAsTFVRlc3QgQ0Eg -b24gS2VyY2tob2ZmczEVMBMGA1UEAxMMUm9vdC1UZXN0LUNBMSwwKgYJKoZIhvcN -AQkBFh10ZXN0LWNhQGtlcmNraG9mZnMuZzEwY29kZS5kZYIBADAJBgNVHREEAjAA -MA0GCSqGSIb3DQEBBQUAA4GBAGPwl3GN6TxYlwnN7Za2H4lJthUkBdxrjoh7D7z4 -kxpo0JGgcBbDEpGPDNtwNg73ukwruGOiOJPGk6qZI1TtI+7joScHf1dtGUTcfFW+ -qpGkImJDrY1IV+ud6qhL2LxY4FLAuEv2iPNSbM9N3X8nB0ofWoPefISRwikYCdR8 -3m+tMYIBmzCCAZcCAQEwgbMwga0xCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcx -EzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxHjAc -BgNVBAsTFVRlc3QgQ0Egb24gS2VyY2tob2ZmczEVMBMGA1UEAxMMUm9vdC1UZXN0 -LUNBMSwwKgYJKoZIhvcNAQkBFh10ZXN0LWNhQGtlcmNraG9mZnMuZzEwY29kZS5k -ZQIBAzAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJBTEPFw0wMjA5MDMxMTA0MzBaMCMG -CSqGSIb3DQEJBDEWBBR5MsAm+0wJAVQl3AAGYmnpxA4XLjALBgkqhkiG9w0BAQEE -gYB0gCqSUCIvw+26dmMFDUz/s3MG9nusAvYJpig8DLIsAGwmAw6Pg0XsI3Wkufb6 -KMTkmyjZLAsNUYWpQgcWkUvIR68iYtI1hd610+YbZubK+IppGkxUrXtFuaMK0xQs -tC0yMxlbcDBteiJYAZTDxn7cypmz106o6k4Utf0CPmd2LQAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-1.osig.pem b/tests/text-1.osig.pem deleted file mode 100644 index 7317350ec..000000000 --- a/tests/text-1.osig.pem +++ /dev/null @@ -1,48 +0,0 @@ ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA -JIAEggPhSGlnaCBQcmllc3Q6CUFybWFtZW50cyBDaGFwdGVyIE9uZSwgdmVyc2Vz -IG5pbmUgdGhyb3VnaCB0d2VudHktc2V2ZW46CkJyby4gTWF5bmFyZDoJQW5kIFNh -aW50IEF0dGlsYSByYWlzZWQgdGhlIEhvbHkgSGFuZCBHcmVuYWRlIHVwIG9uIGhp -Z2gKCXNheWluZywgIk9oIExvcmQsIEJsZXNzIHVzIHRoaXMgSG9seSBIYW5kIEdy -ZW5hZGUsIGFuZCB3aXRoIGl0CglzbWFzaCBvdXIgZW5lbWllcyB0byB0aW55IGJp -dHMuIiAgQW5kIHRoZSBMb3JkIGRpZCBncmluLCBhbmQgdGhlCglwZW9wbGUgZGlk -IGZlYXN0IHVwb24gdGhlIGxhbWJzLCBhbmQgc3RvYXRzLCBhbmQgb3Jhbmd1dGFu -cywgYW5kCglicmVha2Zhc3QgY2VyZWFscywgYW5kIGxpbWEgYmVhbi0KSGlnaCBQ -cmllc3Q6CVNraXAgYSBiaXQsIGJyb3RoZXIuCkJyby4gTWF5bmFyZDoJQW5kIHRo -ZW4gdGhlIExvcmQgc3Bha2UsIHNheWluZzogIkZpcnN0LCBzaGFsdCB0aG91IHRh -a2UKCW91dCB0aGUgaG9seSBwaW4uICBUaGVuIHNoYWx0IHRob3UgY291bnQgdG8g -dGhyZWUuICBObyBtb3JlLCBubyBsZXNzLgoJKlRocmVlKiBzaGFsbCBiZSB0aGUg -bnVtYmVyIG9mIHRoZSBjb3VudGluZywgYW5kIHRoZSBudW1iZXIgb2YgdGhlCglj -b3VudGluZyBzaGFsbCBiZSB0aHJlZS4gICpGb3VyKiBzaGFsdCB0aG91IG5vdCBj -b3VudCwgYW5kIG5laXRoZXIKCWNvdW50IHRob3UgdHdvLCBleGNlcHRpbmcgdGhh -dCB0aG91IHRoZW4gZ29lc3Qgb24gdG8gdGhyZWUuICBGaXZlIGlzCglSSUdIVCBP -VVQuICBPbmNlIHRoZSBudW1iZXIgdGhyZWUsIGJlaW5nIHRoZSB0aGlyZCBudW1i -ZXIgYmUgcmVhY2hlZCwKCXRoZW4gbG9iYmVzdCB0aG91IHRoeSBIb2x5IEhhbmQg -R3JlbmFkZSB0b3dhcmRzIHRoeSBmb2UsIHdobywgYmVpbmcKCW5hdWdodHkgaW4g -bXkgc2lnaHQsIHNoYWxsIHNudWZmIGl0LiAgQW1lbi4KQWxsOglBbWVuLgoJCS0t -IE1vbnR5IFB5dGhvbiwgIlRoZSBIb2x5IEhhbmQgR3JlbmFkZSIKAAAAAAAAoIID -GTCCAxUwggJ+oAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMCREUx -EzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAX -BgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMB4X -DTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkGA1UEBhMCREUxEzAR -BgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNV -BAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGfMA0G -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzBi7mp -zy6EllyqLR/5Wn9UJGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7Jcus -ag4t0fi8qrDUopwvN8lQ82NIS/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQke+dd -xYsBS36iUQIDAQABo4HIMIHFMB0GA1UdDgQWBBQzN40SkcBUcYM4Xwhlv6lL+Y40 -8zCBlQYDVR0jBIGNMIGKgBQzN40SkcBUcYM4Xwhlv6lL+Y4086FvpG0wazELMAkG -A1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2Rl -IEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3Qg -Y2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAbIcEHoo4 -qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJO1Ks -HGx98+gjaCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7T6cf -v+NjLpIt8lRTfgRBhT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJBgNV -BAYTAkRFMRMwEQYDVQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBH -bWJIMRkwFwYDVQQLExBBZWd5cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNl -cnQgMQIBADAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJBTEPFw0wMjA4MDgxMjIyNDZa -MCMGCSqGSIb3DQEJBDEWBBR5MsAm+0wJAVQl3AAGYmnpxA4XLjALBgkqhkiG9w0B -AQEEgYC+7rFtegP8v+Z5yI4CH/0Y4RK48DM1oFMSz4xySpERFTk9p5RPBDhOqaaA -CVKUdmNW6xYJAFo53tQxbBTZ12woctFLbLm9rs/F6Tz2JIA9GxpXInkKYdvkaVHb -pvEQgeoezFc4fd4yB87kgq4zZTViFcCJ3OvjboCu9ltIeIn73AAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-1.txt b/tests/text-1.txt deleted file mode 100644 index b14c1a27c..000000000 --- a/tests/text-1.txt +++ /dev/null @@ -1,17 +0,0 @@ -High Priest: Armaments Chapter One, verses nine through twenty-seven: -Bro. Maynard: And Saint Attila raised the Holy Hand Grenade up on high - saying, "Oh Lord, Bless us this Holy Hand Grenade, and with it - smash our enemies to tiny bits." And the Lord did grin, and the - people did feast upon the lambs, and stoats, and orangutans, and - breakfast cereals, and lima bean- -High Priest: Skip a bit, brother. -Bro. Maynard: And then the Lord spake, saying: "First, shalt thou take - out the holy pin. Then shalt thou count to three. No more, no less. - *Three* shall be the number of the counting, and the number of the - counting shall be three. *Four* shalt thou not count, and neither - count thou two, excepting that thou then goest on to three. Five is - RIGHT OUT. Once the number three, being the third number be reached, - then lobbest thou thy Holy Hand Grenade towards thy foe, who, being - naughty in my sight, shall snuff it. Amen. -All: Amen. - -- Monty Python, "The Holy Hand Grenade" diff --git a/tests/text-2.osig-bad.pem b/tests/text-2.osig-bad.pem deleted file mode 100644 index 555844844..000000000 --- a/tests/text-2.osig-bad.pem +++ /dev/null @@ -1,28 +0,0 @@ -The signature time in this message has been tampered. - ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCAJIAEU01p -bGl0YXJ5IGludGVsbGlnZW5jZSBpcyBhIGNvbnRyYWRpY3Rpb24gaW4gdGVybXMuCiAgICAg -ICAgICAgICAgICAtLSBHcm91Y2hvIE1hcngKAAAAAAAAoIIDGTCCAxUwggJ+oAMCAQICAQAw -DQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAU -BgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNV -BAMTC3Rlc3QgY2VydCAxMB4XDTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkG -A1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgx -GTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGfMA0G -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzBi7mpzy6Ellyq -LR/5Wn9UJGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7Jcusag4t0fi8qrDUopwv -N8lQ82NIS/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQke+ddxYsBS36iUQIDAQABo4HIMIHF -MB0GA1UdDgQWBBQzN40SkcBUcYM4Xwhlv6lL+Y408zCBlQYDVR0jBIGNMIGKgBQzN40SkcBU -cYM4Xwhlv6lL+Y4086FvpG0wazELMAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYx -FjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDAS -BgNVBAMTC3Rlc3QgY2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEA -bIcEHoo4qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJO1Ks -HGx98+gjaCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7T6cfv+NjLpIt -8lRTfgRBhT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJBgNVBAYTAkRFMRMwEQYD -VQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBHbWJIMRkwFwYDVQQLExBBZWd5 -cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNlcnQgMQIBADAHBgUrDgMCGqBDMBwGCSqG -SIb3DQEJBTEPFw0wMjA4MDcxMjM4MjJaMCMGCSqGSIb3DQEJBDEWBBSzI9M4i+WJMTDoCeLu -lJP7p1PCezALBgkqhkiG9w0BAQEEgYAqoJR3uJkChUhaH0EH3U5JpQApIhVEqedaKPT6BCPP -WALFPzEa6YKzftA5e+Dap41UnB8nQ9rfwYty3hw5EulzV9iLnhGornQIgI6D5o7ymxyacsiY -EarezxGXjuPMnyXcpTOgt+vz2k3qisjzxU32zpsOuK6U82PSHysX8rH9QgAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-2.osig.pem b/tests/text-2.osig.pem deleted file mode 100644 index 57b5da9b2..000000000 --- a/tests/text-2.osig.pem +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA -JIAEU01pbGl0YXJ5IGludGVsbGlnZW5jZSBpcyBhIGNvbnRyYWRpY3Rpb24gaW4g -dGVybXMuCiAgICAgICAgICAgICAgICAtLSBHcm91Y2hvIE1hcngKAAAAAAAAoIID -GTCCAxUwggJ+oAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMCREUx -EzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAX -BgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMB4X -DTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkGA1UEBhMCREUxEzAR -BgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNV -BAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGfMA0G -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzBi7mp -zy6EllyqLR/5Wn9UJGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7Jcus -ag4t0fi8qrDUopwvN8lQ82NIS/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQke+dd -xYsBS36iUQIDAQABo4HIMIHFMB0GA1UdDgQWBBQzN40SkcBUcYM4Xwhlv6lL+Y40 -8zCBlQYDVR0jBIGNMIGKgBQzN40SkcBUcYM4Xwhlv6lL+Y4086FvpG0wazELMAkG -A1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2Rl -IEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3Qg -Y2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAbIcEHoo4 -qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJO1Ks -HGx98+gjaCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7T6cf -v+NjLpIt8lRTfgRBhT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJBgNV -BAYTAkRFMRMwEQYDVQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBH -bWJIMRkwFwYDVQQLExBBZWd5cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNl -cnQgMQIBADAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJBTEPFw0wMjA4MDgxMjM4MjJa -MCMGCSqGSIb3DQEJBDEWBBSzI9M4i+WJMTDoCeLulJP7p1PCezALBgkqhkiG9w0B -AQEEgYAqoJR3uJkChUhaH0EH3U5JpQApIhVEqedaKPT6BCPPWALFPzEa6YKzftA5 -e+Dap41UnB8nQ9rfwYty3hw5EulzV9iLnhGornQIgI6D5o7ymxyacsiYEarezxGX -juPMnyXcpTOgt+vz2k3qisjzxU32zpsOuK6U82PSHysX8rH9QgAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-2.txt b/tests/text-2.txt deleted file mode 100644 index 314c7a4e8..000000000 --- a/tests/text-2.txt +++ /dev/null @@ -1,2 +0,0 @@ -Military intelligence is a contradiction in terms. - -- Groucho Marx diff --git a/tests/text-3.txt b/tests/text-3.txt deleted file mode 100644 index 9345b550f..000000000 --- a/tests/text-3.txt +++ /dev/null @@ -1,2 +0,0 @@ -Military justice is to justice what military music is to music. - -- Groucho Marx diff --git a/tools/ChangeLog b/tools/ChangeLog deleted file mode 100644 index a81a2d301..000000000 --- a/tools/ChangeLog +++ /dev/null @@ -1,252 +0,0 @@ -2004-06-14 Werner Koch <wk@gnupg.org> - - * no-libgcrypt.c (gcry_realloc, gcry_xmalloc, gcry_xcalloc): New. - - * gpgconf-comp.c (retrieve_options_from_program) - (retrieve_options_from_file, change_options_file) - (change_options_program, gc_component_change_options): Replaced - getline by read_line and test for allocation failure. - -2004-05-21 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_options_dirmngr): Remove CRL group, put its - only option "max-replies" into LDAP group. - (gc_component): Change description of dirmngr to "Directory - Manager". - - * gpgconf-comp.c (gc_component_change_options): Move the - per-process backup file into a standard location. - -2004-05-03 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c: Add --allow-mark-trusted for the gpg-agent. - -2004-04-30 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c: Added more runtime flags for the gpg-agent - backend. - -2004-04-29 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (change_options_program): Turn on utf8-strings in - the gpgconf specific part of the config file for the GnuPG - backend. - -2004-04-28 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c: Add --ocsp-signer for the dirmngr backend. - -2004-04-20 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_options_gpg_agent): Change type of - ignore-cache-for-signing option to GC_ARG_TYPE_NONE. - -2004-04-07 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c (my_dgettext): Switch the codeset once to utf-8. - Allow building with out NLS. - -2004-03-23 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_options_dirmngr): Set GC_OPT_FLAG_ARG_OPT for - "LDAP Server". - (change_options_file): Remove assertion that tests that this flag - is not present. Handle an empty string in OPTION->new_value. - - * gpgconf.c (main): Remove obsolete warning. - -2004-03-23 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c (gc_options_gpg): New. - (gc_component_t, gc_component): Add GC_BACKEND_GPG. - (gc_options_dirmngr): Add allow-ocsp. - -2004-03-23 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_flag): Add missing flags. - - * gpgconf-comp.c: Include <signal.h>. - (gc_backend): Add new member runtime_change. - (gpg_agent_runtime_change): New function. - (gc_component_change_options): New variable runtime. Initialize - it. If an option is changed that has the GC_OPT_FLAG_RUNTIME bit - set, also set the corresponding runtime variable. Finally, call - the runtime_change callback of the backend if needed. - -2004-03-16 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c (gc_options_gpg_agent): Implemented. - (gc_options_gpgsm, gc_options_scdaemon): Implemented. - (gc_backend_t): Add GC_BACKEND_SCDAEMON. - -2004-03-12 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_component_change_options): Set the filenames - of the option's backend, not of the component. - Also use GC_BACKEND_NR, not GC_COMPONENT_NR. - -2004-03-09 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c [_riscos_]: Removed special code for RISC OS; we - don't want to clutter our code with system dependent stuff. - -2004-03-08 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (retrieve_options_from_file): Quote each string - in the list, not only the first. - -2004-02-26 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_component_list_options): Do not print empty - groups. - - * gpgconf-comp.c (option_check_validity): Check if option is - active. - (change_options_file): Implement. - - * gpgconf-comp.c (retrieve_options_from_program): Remove broken - string handling. - - * gpgconf-comp.c (change_options_program): Support all types of - options, including list types. - - * README.gpgconf: Fix description of arguments. - * gpgconf-comp.c (option_check_validity): Rewritten to properly - support optional arguments in lists. - - * README.gpgconf: Add info about optional arg and arg type 0. - * gpgconf-comp.c (gc_component_change_options): Parse list of - arg type 0 options. - (option_check_validity): Add new argument NEW_VALUE_NR. Perform - rigorous validity checks. - (change_options_program): Disable an option also if we have a new - value for it. - -2004-02-25 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_component_list_options): Correct output for - lists of arg type none. - (struct gc_option): Add new member new_flags. - (option_check_validity): Check OPTION->new_flags beside - OPTION->new_value. Add new argument FLAGS. - (gc_component_change_options): Support default flag correctly. - (change_options_program): Likewise. - -2004-02-24 Marcus Brinkmann <marcus@g10code.de> - - * README.gpgconf: Revert last change. Add new flags "default", - "default desc" and "no arg desc". Add new field ARGDEF. Add new - field FLAG to backend interface. - * gpgconf-comp.c (struct gc_option): Make flags of type unsigned - long. - (gc_component_list_options): Adjust type for flags. - Add default argument field. - (retrieve_options_from_program): Use "1" as value for non-option - arguments, not "Y". - (gc_component_change_options): Read in flags from input. - -2004-02-23 Marcus Brinkmann <marcus@g10code.de> - - * README.gpgconf: Change meaning of type 0 options value if it is - the empty string or "0". - - * gpgconf.h (struct): Add member runtime. - * gpgconf.c: Add new option oRuntime. - (main): Same here. - - * gpgconf-comp.c (hextobyte): New function. - (percent_deescape): New function. - (get_config_pathname): Percent deescape pathname if taken from - option (default) value. Use default value only if it exists and - is not empty. Use empty string otherwise. Don't include leading - quote in pathname. - (change_options_program): Percent deescape string before writing - it out. - - * gpgconf-comp.c (gc_component_list_options): Do not skip groups - on output. - -2004-02-18 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c: Added empty components for gpgsm and scdaemon. - -2004-02-12 Werner Koch <wk@gnupg.org> - - * watchgnupg.c (main): Implement option "--". - (print_version): New. - - * Makefile.am: Include cmacros.am for common flags. - -2004-02-03 Werner Koch <wk@gnupg.org> - - * addgnupghome: Try to use getent, so that it also works for NIS - setups. - -2004-01-31 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c: Some bug fixes, parse only defaults from the - program, and read the current values from the configuration file - directly. - -2004-01-30 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_error): New function, use it instead of - error() throughout. - - * gpgconf-comp.c: Use xmalloc, libcommon's asctimestamp and - gnupg_get_time, fix error() invocation and use getline() - consistently. - -2004-01-30 Werner Koch <wk@gnupg.org> - - * addgnupghome: Also set the group of copied files. - -2004-01-30 Werner Koch <wk@gnupg.org> - - * Makefile.am (sbin_SCRIPTS): New, to install addgnupghome. - (EXTRA_DIST): Added rfc822parse.c rfc822parse.h gpgparsemail.c - which might be useful for debugging. - -2004-01-29 Werner Koch <wk@gnupg.org> - - * addgnupghome: New. - -2004-01-29 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-list.c: File removed. - * README.gpgconf: New file. - * gpgconf-comp.c: New file. - * Makefile.am (gpgconf_SOURCES): Remove gpgconf-list.c, add - gpgconf-comp.c. - -2004-01-16 Werner Koch <wk@gnupg.org> - - * watchgnupg.c (main): Need to use FD_ISSET for the client - descriptors too; aiiih. Set the listening socket to non-blocking. - -2004-01-10 Werner Koch <wk@gnupg.org> - - * Makefile.am: Use GPG_ERROR_CFLAGS - -2004-01-05 Werner Koch <wk@gnupg.org> - - * Manifest: New. - * gpgconf.c, gpgconf.h, gpgconf-list.c: New. A skeleton for now. - * no-libgcrypt.c: New. - * Makefile.am: Add above. - -2003-12-23 Werner Koch <wk@gnupg.org> - - * Makefile.am: New. - * watchgnupg.c: New. - - - Copyright 2003, 2004 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. diff --git a/tools/Makefile.am b/tools/Makefile.am deleted file mode 100644 index 71a77356f..000000000 --- a/tools/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ -# Makefile.am - Tools directory -# Copyright (C) 2003 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -EXTRA_DIST = Manifest watchgnupg.c \ - rfc822parse.c rfc822parse.h gpgparsemail.c \ - addgnupghome - -AM_CPPFLAGS = -I$(top_srcdir)/intl -I$(top_srcdir)/common -include $(top_srcdir)/am/cmacros.am - -# Note, that we require GPG_ERROR_CFLAGS only because some share header files -# require that file. It is not actually used in gpgconf. -AM_CFLAGS = @GPG_ERROR_CFLAGS@ - -sbin_SCRIPTS = addgnupghome - -bin_PROGRAMS = gpgconf watchgnupg - -gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c no-libgcrypt.c - -gpgconf_LDADD = ../jnlib/libjnlib.a ../common/libcommon.a @INTLLIBS@ - -watchgnupg_SOURCES = watchgnupg.c diff --git a/tools/Manifest b/tools/Manifest deleted file mode 100644 index 96423352d..000000000 --- a/tools/Manifest +++ /dev/null @@ -1,6 +0,0 @@ -Makefile.am -watchgnupg.c -gpgconf.c -gpgconf.h -gpgconf-list.c -$names$ diff --git a/tools/README.gpgconf b/tools/README.gpgconf deleted file mode 100644 index c0d3c7c61..000000000 --- a/tools/README.gpgconf +++ /dev/null @@ -1,422 +0,0 @@ -============ - GPG Conf -============ - -CONCEPT -======= - -gpgconf provides access to the configuration of one or more components -of the GnuPG system. These components correspond more or less to the -programs that exist in the GnuPG framework, like GnuPG, GPGSM, -DirMngr, etc. But this is not a strict one-to-one relationship. Not -all configuration options are available through GPGConf. GPGConf -provides a generic and abstract method to access the most important -configuration options that can feasibly be controlled via such a -mechanism. - -GPGConf can be used to gather and change the options available in each -component, and can also provide their default values. GPGConf will -give detailed type information that can be used to restrict the user's -input without making an attempt to commit the changes. - -GPGConf provides the backend of a configuration editor. The -configuration editor would usually be a graphical user interface -program, that allows to display the current options, their default -values, and allows the user to make changes to the options. These -changes can then be made active with GPGConf again. Such a program -that uses GPGConf in this way will be called 'GUI' throughout this -document. - - -Format Conventions -================== - -Some lines in the output of GPGConf contain a list of colon-separated -fields. The following conventions apply: - -The GUI program is required to strip off trailing newline and/or carriage -return characters from the output. - -GPGConf will never leave out fields. If a certain version documents a -certain field, this field will always be present in all GPGConf -versions from that time on. - -Future versions of GPGConf might append fields to the list. New -fields will always be separated from the previously last field by a -colon separator. The GUI should be prepared to parse the last field -it knows about up until a colon or end of line. - -Not all fields are defined under all conditions. You are required to -ignore the content of undefined fields. - -Some fields contain strings that are not escaped in any way. Such -fields are described to be used "verbatim". These fields will never -contain a colon character (for obvious reasons). No de-escaping or -other formatting is required to use the field content. This is for -easy parsing of the output, when it is known that the content can -never contain any special characters. - -Some fields contain strings that are described to be -"percent-escaped". Such strings need to be de-escaped before their -content can be presented to the user. A percent-escaped string is -de-escaped by replacing all occurences of %XY by the byte that has the -hexadecimal value XY. X and Y are from the set { '0'..'9', 'a'..'f' }. - -Some fields contain strings that are described to be "localised". Such -strings are translated to the active language and formatted in the -active character set. - -Some fields contain an unsigned number. This number will always fit -into a 32-bit unsigned integer variable. The number may be followed -by a space, followed by a human readable description of that value. -You should ignore everything in the field that follows the number. - -Some fields contain a signed number. This number will always fit into -a 32-bit signed integer variable. The number may be followed by a -space, followed by a human readable description of that value. You -should ignore everything in the field that follows the number. - -Some fields contain an option argument. The format of an option -argument depends on the type of the option and on some flags: - -The simplest case is that the option does not take an argument at all -(TYPE is 0). Then the option argument is an unsigned number that -specifies how often the option occurs. If the LIST flag is not set, -then the only valid number is 1. Options that don't take an argument -never have the "default" or "optional arg" flag set. - -If the option takes a number argument (ALT-TYPE is 2 or 3), and it can -only occur once (LIST flag is not set), then the option argument is -either empty (only allowed if the argument is optional), or it is a -number. A number is a string that begins with an optional minus -character, followed by one or more digits. The number must fit into -an integer variable (unsigned or signed, depending on ALT-TYPE). - -If the option takes a number argument and it can occur more than once, -then the option argument is either empty, or it is a comma-separated -list of numbers as described above. - -If the option takes a string argument (ALT-TYPE is 1), and it can only -occur once (LIST flag is not set) then the option argument is either -empty (only allowed if the argument is optional), or it starts with a -double quote character (") followed by a percent-escaped string that -is the argument value. Note that there is only a leading double quote -character, no trailing one. The double quote character is only needed -to be able to differentiate between no value and the empty string as -value. - -If the option takes a number argument and it can occur more than once, -then the option argument is either empty, or it is a comma-separated -list of string arguments as described above. - -FIXME: Document the active language and active character set. Allow -to change it via the command line? - - -Components -========== - -A component is a set of configuration options that semantically belong -together. Furthermore, several changes to a component can be made in -an atomic way with a single operation. The GUI could for example -provide a menu with one entry for each component, or a window with one -tabulator sheet per component. - -The following interface is provided to list the available components: - -Command --list-components -------------------------- - -Outputs a list of all components available, one per line. The format -of each line is: - -NAME:DESCRIPTION - -NAME - -This field contains a name tag of the component. The name tag is used -to specify the component in all communication with GPGConf. The name -tag is to be used verbatim. It is not in any escaped format. - -DESCRIPTION - -The string in this field contains a human-readable description of the -component. It can be displayed to the user of the GUI for -informational purposes. It is percent-escaped and localized. - -Example: -$ gpgconf --list-components -gpg-agent:GPG Agent -dirmngr:CRL Manager - - -OPTIONS -======= - -Every component contains one or more options. Options may belong to a -group. The following command lists all options and the groups they -belong to: - -Command --list-options COMPONENT --------------------------------- - -Lists all options (and the groups they belong to) in the component -COMPONENT. COMPONENT is the string in the field NAME in the -output of the --list-components command. - -There is one line for each option and each group. First come all -options that are not in any group. Then comes a line describing a -group. Then come all options that belong into each group. Then comes -the next group and so on. - -The format of each line is: - -NAME:FLAGS:LEVEL:DESCRIPTION:TYPE:ALT-TYPE:ARGNAME:DEFAULT:ARGDEF:VALUE - -NAME - -This field contains a name tag for the group or option. The name tag -is used to specify the group or option in all communication with -GPGConf. The name tag is to be used verbatim. It is not in any -escaped format. - -FLAGS - -The flags field contains an unsigned number. Its value is the -OR-wise combination of the following flag values: - - 1 group If this flag is set, this is a line describing - a group and not an option. - O 2 optional arg If this flag is set, the argument is optional. - This is never set for arg type 0 (none) options. - O 4 list If this flag is set, the option can be given - multiple times. - O 8 runtime If this flag is set, the option can be changed - at runtime. - O 16 default If this flag is set, a default value is available. - O 32 default desc If this flag is set, a (runtime) default is available. - This and the 'default' flag are mutually exclusive. - O 64 no arg desc If this flag is set, and the 'optional arg' flag - is set, then the option has a special meaning if no - argument is given. - -Flags marked with a 'O' are only defined for options (ie, if the GROUP -flag is not set). - -LEVEL - -This field is defined for options and for groups. It contains an -unsigned number that specifies the expert level under which this group -or option should be displayed. The following expert levels are -defined for options (they have analogous meaning for groups): - - 0 basic This option should always be offered to the user. - 1 advanced This option may be offered to advanced users. - 2 expert This option should only be offered to expert users. - 3 invisible This option should normally never be displayed, - not even to expert users. - 4 internal This option is for internal use only. Ignore it. - -The level of a group will always be the lowest level of all options it -contains. - -DESCRIPTION - -This field is defined for options and groups. The string in this -field contains a human-readable description of the option or group. -It can be displayed to the user of the GUI for informational purposes. -It is percent-escaped and localized. - -TYPE - -This field is only defined for options. It contains an unsigned -number that specifies the type of the option's argument, if any. -The following types are defined: - - Basic types - 0 none No argument allowed. - 1 string An unformatted string. - 2 int32 A signed integer number. - 3 uint32 An unsigned integer number. - - Complex types - 32 pathname A string that describes the pathname of a file. - The file does not necessarily need to exist. - 33 ldap server A string that describes an LDAP server in the format - HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN. - -More types will be added in the future. Please see the ALT-TYPE field -for information on how to cope with unknown types. - -ALT-TYPE - -This field is identical to TYPE, except that only the types 0 to 31 -are allowed. The GUI is expected to present the user the option in -the format specified by TYPE. But if the argument type TYPE is not -supported by the GUI, it can still display the option in the more -generic basic type ALT-TYPE. The GUI must support all the defined -basic types to be able to display all options. More basic types may -be added in future versions. If the GUI encounters a basic type it -doesn't support, it should report an error and abort the operation. - -ARGNAME - -This field is only defined for options with an argument type TYPE that -is not 0. In this case it may contain a percent-escaped and localised -string that gives a short name for the argument. The field may also -be empty, though, in which case a short name is not known. - -DEFAULT - -This field is defined only for options. Its format is that of an -option argument (see section Format Conventions for details). If the -default value is empty, then no default is known. Otherwise, the -value specifies the default value for this option. Note that this -field is also meaningful if the option itself does not take a real -argument. - -ARGDEF - -This field is defined only for options for which the "optional arg" -flag is set. If the "no arg desc" flag is not set, its format is that -of an option argument (see section Format Conventions for details). -If the default value is empty, then no default is known. Otherwise, -the value specifies the default value for this option. If the "no arg -desc" flag is set, the field is either empty or contains a description -of the effect of this option if no argument is given. Note that this -field is also meaningful if the option itself does not take a real -argument. - -VALUE - -This field is defined only for options. Its format is that of an -option argument. If it is empty, then the option is not explicitely -set in the current configuration, and the default applies (if any). -Otherwise, it contains the current value of the option. Note that -this field is also meaningful if the option itself does not take a -real argument. - - -CHANGING OPTIONS -================ - -To change the options for a component, you must provide them in the -following format: - -NAME:FLAGS:NEW-VALUE - -NAME - -This is the name of the option to change. - -FLAGS - -The flags field contains an unsigned number. Its value is the -OR-wise combination of the following flag values: - - 16 default If this flag is set, the option is deleted and the - default value is used instead (if applicable). - -NEW-VALUE - -The new value for the option. This field is only defined if the -"default" flag is not set. The format is that of an option argument. -If it is empty (or the field is omitted), the default argument is used -(only allowed if the argument is optional for this option). -Otherwise, the option will be set to the specified value. - - -Example: -To set the option force, which is of basic type 0 (none). -$ echo 'force:0:1' | gpgconf --change-options dirmngr -To delete the option force: -$ echo 'force:16:' | gpgconf --change-options dirmngr - - -Option --runtime ----------------- - -If this option is set, the changes will take effect at run-time, as -far as this is possible. Otherwise, they will take effect at the next -start of the respective backend programs. - - -BACKENDS -======== - -Backends should support the following commands: - -Command --gpgconf-list ----------------------- - -List the location of the configuration file, and all default values of -all options. The location of the configuration file must be an -absolute pathname. - -The format of each line is: - -NAME:FLAGS:DEFAULT:ARGDEF - -NAME - -This field contains a name tag for the group or option. The name tag -is used to specify the group or option in all communication with -GPGConf. The name tag is to be used verbatim. It is not in any -escaped format. - -FLAGS - -The flags field contains an unsigned number. Its value is the -OR-wise combination of the following flag values: - - 16 default If this flag is set, a default value is available. - 32 default desc If this flag is set, a (runtime) default is available. - This and the "default" flag are mutually exclusive. - 64 no arg desc If this flag is set, and the "optional arg" flag - is set, then the option has a special meaning if no - argument is given. - -DEFAULT - -This field is defined only for options. Its format is that of an -option argument (see section Format Conventions for details). If the -default value is empty, then no default is known. Otherwise, the -value specifies the default value for this option. Note that this -field is also meaningful if the option itself does not take a real -argument. - -ARGDEF - -This field is defined only for options for which the "optional arg" -flag is set. If the "no arg desc" flag is not set, its format is that -of an option argument (see section Format Conventions for details). -If the default value is empty, then no default is known. Otherwise, -the value specifies the default value for this option. If the "no arg -desc" flag is set, the field is either empty or contains a description -of the effect of this option if no argument is given. Note that this -field is also meaningful if the option itself does not take a real -argument. - - -Example: -$ dirmngr --gpgconf-list -gpgconf-config-file:/mnt/marcus/.gnupg/dirmngr.conf -ldapservers-file:/mnt/marcus/.gnupg/dirmngr_ldapservers.conf -add-servers:0 -max-replies:10 - - -TODO ----- - -* Extend the backend interface to include gettext domain and -description, if available, to avoid repeating this information in -gpgconf. - -* Left out string arguments (optional) are written out exactly as -empty string arguments. Should we do quoting? - -* More string argument trouble: Special characters like newlines etc -cause trouble. Again, should we do quoting? - - diff --git a/tools/addgnupghome b/tools/addgnupghome deleted file mode 100755 index 37a427bf2..000000000 --- a/tools/addgnupghome +++ /dev/null @@ -1,122 +0,0 @@ -# !/bin/sh -*- sh -*- -# Add a new .gnupg home directory for a list of users -# -# Copyright 2004 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=addgnupghome -any_error=0 - - -error () { - echo "$PGM: $*" >&2 - any_error=1 -} - -info () { - echo "$PGM: $*" >&2 -} - -# Do it for one user -one_user () { - user="$1" - home=$(${cat_passwd} | awk -F: -v n="$user" '$1 == n {print $6}') - if [ -z "$home" ]; then - if ${cat_passwd} | awk -F: -v n="$user" '$1 == n {exit 1}'; then - error "no such user \`$user'" - else - error "no home directory for user \`$user'" - fi - return - fi - if [ ! -d "$home" ]; then - error "home directory \`$home' of user \`$user' does not exist" - return - fi - if [ -d "$home/.gnupg" ]; then - info "skipping user \`$user': \`.gnupg' already exists" - return - fi - info "creating home directory \`$home/.gnupg' for \`$user'" - if ! mkdir "$home/.gnupg" ; then - error "error creating \`$home/.gnupg'" - return - fi - - if ! chown $user "$home/.gnupg" ; then - error "error changing ownership of \`$home/.gnupg'" - return - fi - - group=$(id -g "$user") - [ -z "$group" ] && group="0" - - if [ "$group" -gt 0 ]; then - if ! chgrp $group "$home/.gnupg" ; then - error "error changing group of \`$home/.gnupg'" - return - fi - fi - - if ! cd "$home/.gnupg" ; then - error "error cd-ing to \`$home/.gnupg'" - return - fi - for f in $filelist; do - if [ -d /etc/skel/.gnupg/$f ]; then - mkdir $f - else - cp /etc/skel/.gnupg/$f $f - fi - if ! chown $user $f ; then - error "error changing ownership of \`$f'" - return - fi - if [ "$group" -gt 0 ]; then - if ! chgrp $group "$f" ; then - error "error changing group of \`$f'" - return - fi - fi - done - -} - -if [ -z "$1" ]; then - echo "usage: $PGM userids" - exit 1 -fi - -# Check whether we can use getent -if getent --help </dev/null >/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 checked" -fi - -if [ ! -d /etc/skel/.gnupg ]; then - error "skeleton directory \`/etc/skel/.gnupg' does not exist" - exit 1 -fi -cd "/etc/skel/.gnupg" || (error "error cd-ing to \`/etc/skel/.gnupg'"; exit 1) -filelist=$(find . \( -type f -or -type d \) -not -name '*~' -not -name . -print) - - -if ! umask 0077 ; then - error "error setting umask" - exit 1 -fi - -for name in $*; do - one_user $name -done - -exit $any_error diff --git a/tools/der-to-pem b/tools/der-to-pem deleted file mode 100755 index 183996654..000000000 --- a/tools/der-to-pem +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -# Convert A BER or DER encoding to PEM format. -# -# Copyright 20032 Free Software Foundation, Inc. -# -# This program 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 program 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="der-to-pem" -if [ $# == 0 ]; then - input="" -elif [ $# == 1 ]; then - input="$1" -else - echo "usage: $PGM [<inputfile>]" >&2 - exit 1 -fi - -echo "-----BEGIN CERTIFICATE-----" -mimencode $input -echo "-----END CERTIFICATE-----" - diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c deleted file mode 100644 index cc0751d0c..000000000 --- a/tools/gpgconf-comp.c +++ /dev/null @@ -1,2434 +0,0 @@ -/* gpgconf-comp.c - Configuration utility for GnuPG. - Copyright (C) 2004 Free Software Foundation, Inc. - - This file is part of GnuPG. - - GnuPG is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GnuPG is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GnuPG; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -/* FIXME use gettext.h */ -#include <libintl.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/types.h> -#include <assert.h> -#include <errno.h> -#include <time.h> -#include <stdarg.h> -#include <signal.h> - -/* For log_logv(), asctimestamp(), gnupg_get_time (). */ -#define JNLIB_NEED_LOG_LOGV -#include "util.h" - -#include "gpgconf.h" - - -/* TODO: - Components: Add more components and their options. - Robustness: Do more validation. Call programs to do validation for us. - Don't use popen, as this will not tell us if the program had a - non-zero exit code. - Add options to change backend binary path. - Extract binary path for some backends from gpgsm/gpg config. -*/ - - -#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )) -void gc_error (int status, int errnum, const char *fmt, ...) \ - __attribute__ ((format (printf, 3, 4))); -#endif - -/* Output a diagnostic message. If ERRNUM is not 0, then the output - is followed by a colon, a white space, and the error string for the - error number ERRNUM. In any case the output is finished by a - newline. The message is prepended by the program name, a colon, - and a whitespace. The output may be further formatted or - redirected by the jnlib logging facility. */ -void -gc_error (int status, int errnum, const char *fmt, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, fmt); - log_logv (JNLIB_LOG_ERROR, fmt, arg_ptr); - va_end (arg_ptr); - - if (errnum) - log_printf (": %s\n", strerror (errnum)); - else - log_printf ("\n"); - - if (status) - { - log_printf (NULL); - log_printf ("fatal error (exit status %i)\n", status); - exit (status); - } -} - - -/* Forward declaration. */ -void gpg_agent_runtime_change (void); - -/* Backend configuration. Backends are used to decide how the default - and current value of an option can be determined, and how the - option can be changed. To every option in every component belongs - exactly one backend that controls and determines the option. Some - backends are programs from the GPG system. Others might be - implemented by GPGConf itself. If you change this enum, don't - forget to update GC_BACKEND below. */ -typedef enum - { - /* Any backend, used for find_option (). */ - GC_BACKEND_ANY, - - /* The Gnu Privacy Guard. */ - GC_BACKEND_GPG, - - /* The Gnu Privacy Guard for S/MIME. */ - GC_BACKEND_GPGSM, - - /* The GPG Agent. */ - GC_BACKEND_GPG_AGENT, - - /* The GnuPG SCDaemon. */ - GC_BACKEND_SCDAEMON, - - /* The Aegypten directory manager. */ - GC_BACKEND_DIRMNGR, - - /* The LDAP server list file for the Aegypten director manager. */ - GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST, - - /* The number of the above entries. */ - GC_BACKEND_NR - } gc_backend_t; - - -/* To be able to implement generic algorithms for the various - backends, we collect all information about them in this struct. */ -static struct -{ - /* The name of the backend. */ - const char *name; - - /* The name of the program that acts as the backend. Some backends - don't have an associated program, but are implemented directly by - GPGConf. In this case, PROGRAM is NULL. */ - char *program; - - /* The runtime change callback. */ - void (*runtime_change) (void); - - /* The option name for the configuration filename of this backend. - This must be an absolute pathname. It can be an option from a - different backend (but then ordering of the options might - matter). */ - const char *option_config_filename; - - /* If this is a file backend rather than a program backend, then - this is the name of the option associated with the file. */ - const char *option_name; -} gc_backend[GC_BACKEND_NR] = - { - { NULL }, /* GC_BACKEND_ANY dummy entry. */ - { "GnuPG", "gpg", NULL, "gpgconf-gpg.conf" }, - { "GPGSM", "gpgsm", NULL, "gpgconf-gpgsm.conf" }, - { "GPG Agent", "gpg-agent", gpg_agent_runtime_change, - "gpgconf-gpg-agent.conf" }, - { "SCDaemon", "scdaemon", NULL, "gpgconf-scdaemon.conf" }, - { "DirMngr", "dirmngr", NULL, "gpgconf-dirmngr.conf" }, - { "DirMngr LDAP Server List", NULL, NULL, "ldapserverlist-file", - "LDAP Server" }, - }; - - -/* Option configuration. */ - -/* An option might take an argument, or not. Argument types can be - basic or complex. Basic types are generic and easy to validate. - Complex types provide more specific information about the intended - use, but can be difficult to validate. If you add to this enum, - don't forget to update GC_ARG_TYPE below. YOU MUST NOT CHANGE THE - NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE EXTERNAL - INTERFACE. */ -typedef enum - { - /* Basic argument types. */ - - /* No argument. */ - GC_ARG_TYPE_NONE = 0, - - /* A String argument. */ - GC_ARG_TYPE_STRING = 1, - - /* A signed integer argument. */ - GC_ARG_TYPE_INT32 = 2, - - /* An unsigned integer argument. */ - GC_ARG_TYPE_UINT32 = 3, - - /* ADD NEW BASIC TYPE ENTRIES HERE. */ - - /* Complex argument types. */ - - /* A complete pathname. */ - GC_ARG_TYPE_PATHNAME = 32, - - /* An LDAP server in the format - HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN. */ - GC_ARG_TYPE_LDAP_SERVER = 33, - - /* A 40 character fingerprint. */ - GC_ARG_TYPE_KEY_FPR = 34, - - /* ADD NEW COMPLEX TYPE ENTRIES HERE. */ - - /* The number of the above entries. */ - GC_ARG_TYPE_NR - } gc_arg_type_t; - - -/* For every argument, we record some information about it in the - following struct. */ -static struct -{ - /* For every argument type exists a basic argument type that can be - used as a fallback for input and validation purposes. */ - gc_arg_type_t fallback; - - /* Human-readable name of the type. */ - const char *name; -} gc_arg_type[GC_ARG_TYPE_NR] = - { - /* The basic argument types have their own types as fallback. */ - { GC_ARG_TYPE_NONE, "none" }, - { GC_ARG_TYPE_STRING, "string" }, - { GC_ARG_TYPE_INT32, "int32" }, - { GC_ARG_TYPE_UINT32, "uint32" }, - - /* Reserved basic type entries for future extension. */ - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - - /* The complex argument types have a basic type as fallback. */ - { GC_ARG_TYPE_STRING, "pathname" }, - { GC_ARG_TYPE_STRING, "ldap server" }, - { GC_ARG_TYPE_STRING, "key fpr" }, - }; - - -/* Every option has an associated expert level, than can be used to - hide advanced and expert options from beginners. If you add to - this list, don't forget to update GC_LEVEL below. YOU MUST NOT - CHANGE THE NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE - EXTERNAL INTERFACE. */ -typedef enum - { - /* The basic options should always be displayed. */ - GC_LEVEL_BASIC, - - /* The advanced options may be hidden from beginners. */ - GC_LEVEL_ADVANCED, - - /* The expert options should only be displayed to experts. */ - GC_LEVEL_EXPERT, - - /* The invisible options should normally never be displayed. */ - GC_LEVEL_INVISIBLE, - - /* The internal options are never exported, they mark options that - are recorded for internal use only. */ - GC_LEVEL_INTERNAL, - - /* ADD NEW ENTRIES HERE. */ - - /* The number of the above entries. */ - GC_LEVEL_NR - } gc_expert_level_t; - -/* A description for each expert level. */ -static struct -{ - const char *name; -} gc_level[] = - { - { "basic" }, - { "advanced" }, - { "expert" }, - { "invisible" }, - { "internal" } - }; - - -/* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING - FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */ -#define GC_OPT_FLAG_NONE 0UL -/* Some entries in the option list are not options, but mark the - beginning of a new group of options. These entries have the GROUP - flag set. */ -#define GC_OPT_FLAG_GROUP (1UL << 0) -/* The ARG_OPT flag for an option indicates that the argument is - optional. This is never set for GC_ARG_TYPE_NONE options. */ -#define GC_OPT_FLAG_ARG_OPT (1UL << 1) -/* The LIST flag for an option indicates that the option can occur - several times. A comma separated list of arguments is used as the - argument value. */ -#define GC_OPT_FLAG_LIST (1UL << 2) -/* The RUNTIME flag for an option indicates that the option can be - changed at runtime. */ -#define GC_OPT_FLAG_RUNTIME (1UL << 3) - -/* The following flags are incorporated from the backend. */ -/* The DEFAULT flag for an option indicates that the option has a - default value. */ -#define GC_OPT_FLAG_DEFAULT (1UL << 4) -/* The DEF_DESC flag for an option indicates that the option has a - default, which is described by the value of the default field. */ -#define GC_OPT_FLAG_DEF_DESC (1UL << 5) -/* The NO_ARG_DESC flag for an option indicates that the argument has - a default, which is described by the value of the ARGDEF field. */ -#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) - -/* A human-readable description for each flag. */ -static struct -{ - const char *name; -} gc_flag[] = - { - { "group" }, - { "optional arg" }, - { "list" }, - { "runtime" }, - { "default" }, - { "default desc" }, - { "no arg desc" } - }; - - -/* To each option, or group marker, the information in the GC_OPTION - struct is provided. If you change this, don't forget to update the - option list of each component. */ -struct gc_option -{ - /* If this is NULL, then this is a terminator in an array of unknown - length. Otherwise, if this entry is a group marker (see FLAGS), - then this is the name of the group described by this entry. - Otherwise it is the name of the option described by this - entry. The name must not contain a colon. */ - const char *name; - - /* The option flags. If the GROUP flag is set, then this entry is a - group marker, not an option, and only the fields LEVEL, - DESC_DOMAIN and DESC are valid. In all other cases, this entry - describes a new option and all fields are valid. */ - unsigned long flags; - - /* The expert level. This field is valid for options and groups. A - group has the expert level of the lowest-level option in the - group. */ - gc_expert_level_t level; - - /* A gettext domain in which the following description can be found. - If this is NULL, then DESC is not translated. Valid for groups - and options. */ - const char *desc_domain; - - /* A gettext description for this group or option. If it starts - with a '|', then the string up to the next '|' describes the - argument, and the description follows the second '|'. */ - const char *desc; - - /* The following fields are only valid for options. */ - - /* The type of the option argument. */ - gc_arg_type_t arg_type; - - /* The backend that implements this option. */ - gc_backend_t backend; - - /* The following fields are set to NULL at startup (because all - option's are declared as static variables). They are at the end - of the list so that they can be omitted from the option - declarations. */ - - /* This is true if the option is supported by this version of the - backend. */ - int active; - - /* The default value for this option. This is NULL if the option is - not present in the backend, the empty string if no default is - available, and otherwise a quoted string. */ - char *default_value; - - /* The default argument is only valid if the "optional arg" flag is - set, and specifies the default argument (value) that is used if - the argument is omitted. */ - char *default_arg; - - /* The current value of this option. */ - char *value; - - /* The new flags for this option. The only defined flag is actually - GC_OPT_FLAG_DEFAULT, and it means that the option should be - deleted. In this case, NEW_VALUE is NULL. */ - unsigned long new_flags; - - /* The new value of this option. */ - char *new_value; -}; -typedef struct gc_option gc_option_t; - -/* Use this macro to terminate an option list. */ -#define GC_OPTION_NULL { NULL } - - -/* The options of the GC_COMPONENT_GPG_AGENT component. */ -static gc_option_t gc_options_gpg_agent[] = - { - /* The configuration file to which we write the changes. */ - { "gpgconf-gpg-agent.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, - NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, - - { "Monitor", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, - { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, - "gnupg", "verbose", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - { "quiet", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, - "gnupg", "be somewhat more quiet", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - - { "Configuration", - GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, - { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "|FILE|read options from FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, - - { "Debug", - GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "gnupg", "Options useful for debugging" }, - { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, - "gnupg", "|LEVEL|set the debugging level to LEVEL", - GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT }, - { "log-file", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, - "gnupg", "|FILE|write logs to FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, - { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT }, - - { "Security", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the security" }, - { "default-cache-ttl", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, - "gnupg", "|N|expire cached PINs after N seconds", - GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT }, - { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, - "gnupg", "do not use the PIN cache when signing", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - { "allow-mark-trusted", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, - "gnupg", "allow clients to mark keys as \"trusted\"", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - { "no-grab", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT, - "gnupg", "do not grab keyboard and mouse", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - - - GC_OPTION_NULL - }; - - -/* The options of the GC_COMPONENT_SCDAEMON component. */ -static gc_option_t gc_options_scdaemon[] = - { - /* The configuration file to which we write the changes. */ - { "gpgconf-scdaemon.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, - NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON }, - - { "Monitor", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, - { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, - "gnupg", "verbose", - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "be somewhat more quiet", - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - - { "Configuration", - GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, - { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "|FILE|read options from FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON }, - { "reader-port", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "|N|connect to reader at port N", - GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "ctapi-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|NAME|use NAME as ct-API driver", - GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "pcsc-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|NAME|use NAME as PC/SC driver", - GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "disable-opensc", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "do not use the OpenSC layer", - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - { "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "do not use the internal CCID driver", - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - - - { "Debug", - GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "gnupg", "Options useful for debugging" }, - { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, - "gnupg", "|LEVEL|set the debugging level to LEVEL", - GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|FILE|write logs to FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON }, - - { "Security", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the security" }, - { "allow-admin", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "allow the use of admin card commands", - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - - - GC_OPTION_NULL - }; - - -/* The options of the GC_COMPONENT_GPG component. */ -static gc_option_t gc_options_gpg[] = - { - /* The configuration file to which we write the changes. */ - { "gpgconf-gpg.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, - NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG }, - - { "Monitor", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, - { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, - "gnupg", "verbose", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG }, - { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "be somewhat more quiet", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG }, - { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_NONE, GC_BACKEND_GPG }, - - { "Configuration", - GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, - { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "|FILE|read options from FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG }, - - { "Debug", - GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "gnupg", "Options useful for debugging" }, - { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, - "gnupg", "|LEVEL|set the debugging level to LEVEL", - GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, - { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|FILE|write logs to FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG }, -/* { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, */ -/* NULL, NULL, */ -/* GC_ARG_TYPE_UINT32, GC_BACKEND_GPG }, */ - - { "Keyserver", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Configuration for Keyservers" }, - { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "|URL|use keyserver at URL", - GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, - - - GC_OPTION_NULL - }; - - - -/* The options of the GC_COMPONENT_GPGSM component. */ -static gc_option_t gc_options_gpgsm[] = - { - /* The configuration file to which we write the changes. */ - { "gpgconf-gpgsm.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, - NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, - - { "Monitor", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, - { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, - "gnupg", "verbose", - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "be somewhat more quiet", - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - - { "Configuration", - GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, - { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "|FILE|read options from FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, - - { "Debug", - GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "gnupg", "Options useful for debugging" }, - { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, - "gnupg", "|LEVEL|set the debugging level to LEVEL", - GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM }, - { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|FILE|write logs to FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, - { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_UINT32, GC_BACKEND_GPGSM }, - - { "Security", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the security" }, - { "disable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "never consult a CRL", - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - { "enable-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "check validity using OCSP", - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - { "include-certs", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "|N|number of certificates to include", - GC_ARG_TYPE_INT32, GC_BACKEND_GPGSM }, - { "disable-policy-checks", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "do not check certificate policies", - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - { "auto-issuer-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "fetch missing issuer certificates", - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - - GC_OPTION_NULL - }; - - -/* The options of the GC_COMPONENT_DIRMNGR component. */ -static gc_option_t gc_options_dirmngr[] = - { - /* The configuration file to which we write the changes. */ - { "gpgconf-dirmngr.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, - NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, - - { "Monitor", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, - { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, - "dirmngr", "verbose", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "be somewhat more quiet", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - - { "Format", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the format of the output" }, - { "sh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "sh-style command output", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "csh-style command output", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - - { "Configuration", - GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, - { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "dirmngr", "|FILE|read options from FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, - - { "Debug", - GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "dirmngr", "Options useful for debugging" }, - { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, - "dirmngr", "|LEVEL|set the debugging level to LEVEL", - GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, - { "no-detach", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "dirmngr", "do not detach from the console", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "dirmngr", "|FILE|write logs to FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, - { "debug-wait", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, - { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, - - { "Enforcement", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the interactivity and enforcement" }, - { "batch", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "run without asking a user", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "force", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "force loading of outdated CRLs", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - - { "LDAP", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Configuration of LDAP servers to use" }, - { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "add new servers discovered in CRL distribution points" - " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "|N|set LDAP timeout to N seconds", - GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, - /* The following entry must not be removed, as it is required for - the GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST. */ - { "ldapserverlist-file", - GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, - "dirmngr", "|FILE|read LDAP server list from FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, - /* This entry must come after at least one entry for - GC_BACKEND_DIRMNGR in this component, so that the entry for - "ldapserverlist-file will be initialized before this one. */ - { "LDAP Server", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, - NULL, "LDAP server list", - GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST }, - { "max-replies", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "|N|do not return more than N items in one query", - GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, - - { "OCSP", - GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - NULL, "Configuration for OCSP" }, - { "allow-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "allow sending OCSP requests", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "dirmngr", "|URL|use OCSP responder URL", - GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, - { "ocsp-signer", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "dirmngr", "|FPR|OCSP response signed by FPR", - GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, - - - GC_OPTION_NULL - }; - - -/* Component system. Each component is a set of options that can be - configured at the same time. If you change this, don't forget to - update GC_COMPONENT below. */ -typedef enum - { - /* The classic GPG for OpenPGP. */ - GC_COMPONENT_GPG, - - /* The GPG Agent. */ - GC_COMPONENT_GPG_AGENT, - - /* The Smardcard Daemon. */ - GC_COMPONENT_SCDAEMON, - - /* GPG for S/MIME. */ - GC_COMPONENT_GPGSM, - - /* The LDAP Directory Manager for CRLs. */ - GC_COMPONENT_DIRMNGR, - - /* The number of components. */ - GC_COMPONENT_NR - } gc_component_t; - - -/* The information associated with each component. */ -static struct -{ - /* The name of this component. Must not contain a colon (':') - character. */ - const char *name; - - /* The gettext domain for the description DESC. If this is NULL, - then the description is not translated. */ - const char *desc_domain; - - /* The description for this domain. */ - const char *desc; - - /* The list of options for this component, terminated by - GC_OPTION_NULL. */ - gc_option_t *options; -} gc_component[] = - { - { "gpg", NULL, "GPG for OpenPGP", gc_options_gpg }, - { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent }, - { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon }, - { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm }, - { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr } - }; - - -/* Engine specific support. */ -void -gpg_agent_runtime_change (void) -{ - char *agent = getenv ("GPG_AGENT_INFO"); - char *pid_str; - unsigned long pid_long; - char *tail; - pid_t pid; - - if (!agent) - return; - - pid_str = strchr (agent, ':'); - if (!pid_str) - return; - - pid_str++; - errno = 0; - pid_long = strtoul (pid_str, &tail, 0); - if (errno || (*tail != ':' && *tail != '\0')) - return; - - pid = (pid_t) pid_long; - - /* Check for overflow. */ - if (pid_long != (unsigned long) pid) - return; - - /* Ignore any errors here. */ - kill (pid, SIGHUP); -} - - -/* More or less Robust version of dgettext. It has the sidefeect of - switching the codeset to utf-8 becuase this is what we want to - output. In theory it is posible to keep the orginal code set and - switch back for regular disgnostic output (redefine "_(" for that) - but given the natur of this tool, being something invoked from - other pograms, it does not make much sense. */ -static const char * -my_dgettext (const char *domain, const char *msgid) -{ -#ifdef ENABLE_NLS - if (domain) - { - static int switched_codeset; - char *text; - - if (!switched_codeset) - { - bind_textdomain_codeset (PACKAGE_GT, "utf-8"); - switched_codeset = 1; - } - text = dgettext (domain, msgid); - return text ? text : msgid; - } - else -#endif - return msgid; -} - - -/* Percent-Escape special characters. The string is valid until the - next invocation of the function. */ -static char * -percent_escape (const char *src) -{ - static char *esc_str; - static int esc_str_len; - int new_len = 3 * strlen (src) + 1; - char *dst; - - if (esc_str_len < new_len) - { - char *new_esc_str = realloc (esc_str, new_len); - if (!new_esc_str) - gc_error (1, errno, "can not escape string"); - esc_str = new_esc_str; - esc_str_len = new_len; - } - - dst = esc_str; - while (*src) - { - if (*src == '%') - { - *(dst++) = '%'; - *(dst++) = '2'; - *(dst++) = '5'; - } - else if (*src == ':') - { - /* The colon is used as field separator. */ - *(dst++) = '%'; - *(dst++) = '3'; - *(dst++) = 'a'; - } - else if (*src == ',') - { - /* The comma is used as list separator. */ - *(dst++) = '%'; - *(dst++) = '2'; - *(dst++) = 'c'; - } - else - *(dst++) = *(src); - src++; - } - *dst = '\0'; - return esc_str; -} - - -/* Convert two hexadecimal digits from STR to the value they - represent. Returns -1 if one of the characters is not a - hexadecimal digit. */ -static int -hextobyte (const char *str) -{ - int val = 0; - int i; - -#define NROFHEXDIGITS 2 - for (i = 0; i < NROFHEXDIGITS; i++) - { - if (*str >= '0' && *str <= '9') - val += *str - '0'; - else if (*str >= 'A' && *str <= 'F') - val += 10 + *str - 'A'; - else if (*str >= 'a' && *str <= 'f') - val += 10 + *str - 'a'; - else - return -1; - if (i < NROFHEXDIGITS - 1) - val *= 16; - str++; - } - return val; -} - - - -/* Percent-Deescape special characters. The string is valid until the - next invocation of the function. */ -static char * -percent_deescape (const char *src) -{ - static char *str; - static int str_len; - int new_len = 3 * strlen (src) + 1; - char *dst; - - if (str_len < new_len) - { - char *new_str = realloc (str, new_len); - if (!new_str) - gc_error (1, errno, "can not deescape string"); - str = new_str; - str_len = new_len; - } - - dst = str; - while (*src) - { - if (*src == '%') - { - int val = hextobyte (src + 1); - - if (val < 0) - gc_error (1, 0, "malformed end of string %s", src); - - *(dst++) = (char) val; - src += 3; - } - else - *(dst++) = *(src++); - } - *dst = '\0'; - return str; -} - - -/* List all components that are available. */ -void -gc_component_list_components (FILE *out) -{ - gc_component_t idx; - - for (idx = 0; idx < GC_COMPONENT_NR; idx++) - { - const char *desc = gc_component[idx].desc; - desc = my_dgettext (gc_component[idx].desc_domain, desc); - fprintf (out, "%s:%s\n", gc_component[idx].name, percent_escape (desc)); - } -} - - -/* Find the component with the name NAME. Returns -1 if not - found. */ -int -gc_component_find (const char *name) -{ - gc_component_t idx; - - for (idx = 0; idx < GC_COMPONENT_NR; idx++) - { - if (!strcmp (name, gc_component[idx].name)) - return idx; - } - return -1; -} - - -/* List the option OPTION. */ -static void -list_one_option (const gc_option_t *option, FILE *out) -{ - const char *desc = NULL; - char *arg_name = NULL; - - if (option->desc) - { - desc = my_dgettext (option->desc_domain, option->desc); - - if (*desc == '|') - { - const char *arg_tail = strchr (&desc[1], '|'); - - if (arg_tail) - { - int arg_len = arg_tail - &desc[1]; - arg_name = xmalloc (arg_len + 1); - memcpy (arg_name, &desc[1], arg_len); - arg_name[arg_len] = '\0'; - desc = arg_tail + 1; - } - } - } - - - /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR ORDER IS - PART OF THE EXTERNAL INTERFACE. YOU MUST NOT REMOVE ANY - FIELDS. */ - - /* The name field. */ - fprintf (out, "%s", option->name); - - /* The flags field. */ - fprintf (out, ":%lu", option->flags); - if (opt.verbose) - { - putc (' ', out); - - if (!option->flags) - fprintf (out, "none"); - else - { - unsigned long flags = option->flags; - unsigned long flag = 0; - unsigned long first = 1; - - while (flags) - { - if (flags & 1) - { - if (first) - first = 0; - else - putc (',', out); - fprintf (out, "%s", gc_flag[flag].name); - } - flags >>= 1; - flag++; - } - } - } - - /* The level field. */ - fprintf (out, ":%u", option->level); - if (opt.verbose) - fprintf (out, " %s", gc_level[option->level].name); - - /* The description field. */ - fprintf (out, ":%s", desc ? percent_escape (desc) : ""); - - /* The type field. */ - fprintf (out, ":%u", option->arg_type); - if (opt.verbose) - fprintf (out, " %s", gc_arg_type[option->arg_type].name); - - /* The alternate type field. */ - fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback); - if (opt.verbose) - fprintf (out, " %s", - gc_arg_type[gc_arg_type[option->arg_type].fallback].name); - - /* The argument name field. */ - fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : ""); - if (arg_name) - xfree (arg_name); - - /* The default value field. */ - fprintf (out, ":%s", option->default_value ? option->default_value : ""); - - /* The default argument field. */ - fprintf (out, ":%s", option->default_arg ? option->default_arg : ""); - - /* The value field. */ - if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE - && (option->flags & GC_OPT_FLAG_LIST) - && option->value) - /* The special format "1,1,1,1,...,1" is converted to a number - here. */ - fprintf (out, ":%u", (strlen (option->value) + 1) / 2); - else - fprintf (out, ":%s", option->value ? option->value : ""); - - /* ADD NEW FIELDS HERE. */ - - putc ('\n', out); -} - - -/* List all options of the component COMPONENT. */ -void -gc_component_list_options (int component, FILE *out) -{ - const gc_option_t *option = gc_component[component].options; - const gc_option_t *group_option = NULL; - - while (option->name) - { - /* Do not output unknown or internal options. */ - if (!(option->flags & GC_OPT_FLAG_GROUP) - && (!option->active || option->level == GC_LEVEL_INTERNAL)) - { - option++; - continue; - } - - if (option->flags & GC_OPT_FLAG_GROUP) - group_option = option; - else - { - if (group_option) - { - list_one_option (group_option, out); - group_option = NULL; - } - - list_one_option (option, out); - } - - option++; - } -} - - -/* Find the option NAME in component COMPONENT, for the backend - BACKEND. If BACKEND is GC_BACKEND_ANY, any backend will match. */ -static gc_option_t * -find_option (gc_component_t component, const char *name, - gc_backend_t backend) -{ - gc_option_t *option = gc_component[component].options; - while (option->name) - { - if (!(option->flags & GC_OPT_FLAG_GROUP) - && !strcmp (option->name, name) - && (backend == GC_BACKEND_ANY || option->backend == backend)) - break; - option++; - } - return option->name ? option : NULL; -} - - -/* Determine the configuration pathname for the component COMPONENT - and backend BACKEND. */ -static char * -get_config_pathname (gc_component_t component, gc_backend_t backend) -{ - char *pathname = NULL; - gc_option_t *option = find_option - (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY); - assert (option); - assert (option->arg_type == GC_ARG_TYPE_PATHNAME); - assert (!(option->flags & GC_OPT_FLAG_LIST)); - - if (!option->active || !option->default_value) - gc_error (1, 0, "Option %s, needed by backend %s, was not initialized", - gc_backend[backend].option_config_filename, - gc_backend[backend].name); - - if (option->value && *option->value) - pathname = percent_deescape (&option->value[1]); - else if (option->default_value && *option->default_value) - pathname = percent_deescape (&option->default_value[1]); - else - pathname = ""; - - if (pathname[0] != '/') - gc_error (1, 0, "Option %s, needed by backend %s, is not absolute", - gc_backend[backend].option_config_filename, - gc_backend[backend].name); - - return pathname; -} - - -/* Retrieve the options for the component COMPONENT from backend - BACKEND, which we already know is a program-type backend. */ -static void -retrieve_options_from_program (gc_component_t component, gc_backend_t backend) -{ - char *cmd_line; - char *line = NULL; - size_t line_len = 0; - ssize_t length; - FILE *config; - char *config_pathname; - - cmd_line = xasprintf ("%s --gpgconf-list", gc_backend[backend].program); - - config = popen (cmd_line, "r"); - if (!config) - gc_error (1, errno, "could not gather active options from %s", cmd_line); - - while ((length = read_line (config, &line, &line_len, NULL)) > 0) - { - gc_option_t *option; - char *linep; - unsigned long flags = 0; - char *default_value = NULL; - - /* Strip newline and carriage return, if present. */ - while (length > 0 - && (line[length - 1] == '\n' || line[length - 1] == '\r')) - line[--length] = '\0'; - - linep = strchr (line, ':'); - if (linep) - *(linep++) = '\0'; - - /* Extract additional flags. Default to none. */ - if (linep) - { - char *end; - char *tail; - - end = strchr (linep, ':'); - if (end) - *(end++) = '\0'; - - errno = 0; - flags = strtoul (linep, &tail, 0); - if (errno) - gc_error (1, errno, "malformed flags in option %s from %s", line, cmd_line); - if (!(*tail == '\0' || *tail == ':' || *tail == ' ')) - gc_error (1, 0, "garbage after flags in option %s from %s", line, cmd_line); - - linep = end; - } - - /* Extract default value, if present. Default to empty if - not. */ - if (linep) - { - char *end; - - end = strchr (linep, ':'); - if (end) - *(end++) = '\0'; - - if (flags & GC_OPT_FLAG_DEFAULT) - default_value = linep; - - linep = end; - } - - /* Look up the option in the component and install the - configuration data. */ - option = find_option (component, line, backend); - if (option) - { - if (option->active) - gc_error (1, errno, "option %s returned twice from %s", - line, cmd_line); - option->active = 1; - - option->flags |= flags; - if (default_value && *default_value) - option->default_value = xstrdup (default_value); - } - } - if (length < 0 || ferror (config)) - gc_error (1, errno, "error reading from %s", cmd_line); - if (fclose (config) && ferror (config)) - gc_error (1, errno, "error closing %s", cmd_line); - xfree (cmd_line); - - /* At this point, we can parse the configuration file. */ - config_pathname = get_config_pathname (component, backend); - - config = fopen (config_pathname, "r"); - if (!config) - gc_error (0, errno, "warning: can not open config file %s", - config_pathname); - else - { - while ((length = read_line (config, &line, &line_len, NULL)) > 0) - { - char *name; - char *value; - gc_option_t *option; - - name = line; - while (*name == ' ' || *name == '\t') - name++; - if (!*name || *name == '#' || *name == '\r' || *name == '\n') - continue; - - value = name; - while (*value && *value != ' ' && *value != '\t' - && *value != '#' && *value != '\r' && *value != '\n') - value++; - if (*value == ' ' || *value == '\t') - { - char *end; - - *(value++) = '\0'; - while (*value == ' ' || *value == '\t') - value++; - - end = value; - while (*end && *end != '#' && *end != '\r' && *end != '\n') - end++; - while (end > value && (end[-1] == ' ' || end[-1] == '\t')) - end--; - *end = '\0'; - } - else - *value = '\0'; - - /* Look up the option in the component and install the - configuration data. */ - option = find_option (component, line, backend); - if (option) - { - char *opt_value; - - if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE) - { - if (*value) - gc_error (0, 0, - "warning: ignoring argument %s for option %s", - value, name); - opt_value = xstrdup ("1"); - } - else if (gc_arg_type[option->arg_type].fallback - == GC_ARG_TYPE_STRING) - opt_value = xasprintf ("\"%s", percent_escape (value)); - else - { - /* FIXME: Verify that the number is sane. */ - opt_value = xstrdup (value); - } - - /* Now enter the option into the table. */ - if (!(option->flags & GC_OPT_FLAG_LIST)) - { - if (option->value) - free (option->value); - option->value = opt_value; - } - else - { - if (!option->value) - option->value = opt_value; - else - { - char *opt_val = opt_value; - - option->value = xasprintf ("%s,%s", option->value, - opt_val); - xfree (opt_value); - } - } - } - } - - if (length < 0 || ferror (config)) - gc_error (1, errno, "error reading from %s", config_pathname); - if (fclose (config) && ferror (config)) - gc_error (1, errno, "error closing %s", config_pathname); - } - - xfree (line); -} - - -/* Retrieve the options for the component COMPONENT from backend - BACKEND, which we already know is of type file list. */ -static void -retrieve_options_from_file (gc_component_t component, gc_backend_t backend) -{ - gc_option_t *list_option; - char *list_pathname; - FILE *list_file; - char *line = NULL; - size_t line_len = 0; - ssize_t length; - char *list = NULL; - - list_option = find_option (component, - gc_backend[backend].option_name, GC_BACKEND_ANY); - assert (list_option); - assert (!list_option->active); - - list_pathname = get_config_pathname (component, backend); - list_file = fopen (list_pathname, "r"); - if (!list_file) - gc_error (0, errno, "warning: can not open list file %s", list_pathname); - else - { - - while ((length = read_line (list_file, &line, &line_len, NULL)) > 0) - { - char *start; - char *end; - char *new_list; - - start = line; - while (*start == ' ' || *start == '\t') - start++; - if (!*start || *start == '#' || *start == '\r' || *start == '\n') - continue; - - end = start; - while (*end && *end != '#' && *end != '\r' && *end != '\n') - end++; - /* Walk back to skip trailing white spaces. Looks evil, but - works because of the conditions on START and END imposed - at this point (END is at least START + 1, and START is - not a whitespace character). */ - while (*(end - 1) == ' ' || *(end - 1) == '\t') - end--; - *end = '\0'; - /* FIXME: Oh, no! This is so lame! Should use realloc and - really append. */ - if (list) - { - new_list = xasprintf ("%s,\"%s", list, percent_escape (start)); - xfree (list); - list = new_list; - } - else - list = xasprintf ("\"%s", percent_escape (start)); - } - if (length < 0 || ferror (list_file)) - gc_error (1, errno, "can not read list file %s", list_pathname); - } - - list_option->active = 1; - list_option->value = list; - - xfree (line); -} - - -/* Retrieve the currently active options and their defaults from all - involved backends for this component. */ -void -gc_component_retrieve_options (int component) -{ - int backend_seen[GC_BACKEND_NR]; - gc_backend_t backend; - gc_option_t *option = gc_component[component].options; - - for (backend = 0; backend < GC_BACKEND_NR; backend++) - backend_seen[backend] = 0; - - while (option->name) - { - if (!(option->flags & GC_OPT_FLAG_GROUP)) - { - backend = option->backend; - - if (backend_seen[backend]) - { - option++; - continue; - } - backend_seen[backend] = 1; - - assert (backend != GC_BACKEND_ANY); - - if (gc_backend[backend].program) - retrieve_options_from_program (component, backend); - else - retrieve_options_from_file (component, backend); - } - option++; - } -} - - -/* Perform a simple validity check based on the type. Return in - NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of - type GC_ARG_TYPE_NONE. */ -static void -option_check_validity (gc_option_t *option, unsigned long flags, - char *new_value, unsigned long *new_value_nr) -{ - char *arg; - - if (!option->active) - gc_error (1, 0, "option %s not supported by backend", option->name); - - if (option->new_flags || option->new_value) - gc_error (1, 0, "option %s already changed", option->name); - - if (flags & GC_OPT_FLAG_DEFAULT) - { - if (*new_value) - gc_error (1, 0, "argument %s provided for deleted option %s", - new_value, option->name); - - return; - } - - /* GC_ARG_TYPE_NONE options have special list treatment. */ - if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE) - { - char *tail; - - errno = 0; - *new_value_nr = strtoul (new_value, &tail, 0); - - if (errno) - gc_error (1, errno, "invalid argument for option %s", - option->name); - if (*tail) - gc_error (1, 0, "garbage after argument for option %s", - option->name); - - if (!(option->flags & GC_OPT_FLAG_LIST)) - { - if (*new_value_nr != 1) - gc_error (1, 0, "argument for non-list option %s of type 0 " - "(none) must be 1", option->name); - } - else - { - if (*new_value_nr == 0) - gc_error (1, 0, "argument for option %s of type 0 (none) " - "must be positive", option->name); - } - - return; - } - - arg = new_value; - do - { - if (*arg == '\0' || *arg == ',') - { - if (!(option->flags & GC_OPT_FLAG_ARG_OPT)) - gc_error (1, 0, "argument required for option %s", option->name); - - if (*arg == ',' && !(option->flags & GC_OPT_FLAG_LIST)) - gc_error (1, 0, "list found for non-list option %s", option->name); - } - else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING) - { - if (*arg != '"') - gc_error (1, 0, "string argument for option %s must begin " - "with a quote (\") character", option->name); - } - else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32) - { - errno = 0; - (void) strtol (arg, &arg, 0); - - if (errno) - gc_error (1, errno, "invalid argument for option %s", - option->name); - - if (*arg != '\0' && *arg != ',') - gc_error (1, 0, "garbage after argument for option %s", - option->name); - } - else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32) - { - errno = 0; - (void) strtoul (arg, &arg, 0); - - if (errno) - gc_error (1, errno, "invalid argument for option %s", - option->name); - - if (*arg != '\0' && *arg != ',') - gc_error (1, 0, "garbage after argument for option %s", - option->name); - } - arg = strchr (arg, ','); - if (arg) - arg++; - } - while (arg && *arg); -} - - -/* Create and verify the new configuration file for the specified - backend and component. Returns 0 on success and -1 on error. */ -static int -change_options_file (gc_component_t component, gc_backend_t backend, - char **src_filenamep, char **dest_filenamep, - char **orig_filenamep) -{ - static const char marker[] = "###+++--- GPGConf ---+++###"; - /* True if we are within the marker in the config file. */ - int in_marker = 0; - gc_option_t *option; - char *line = NULL; - size_t line_len; - ssize_t length; - int res; - int fd; - FILE *src_file = NULL; - FILE *dest_file = NULL; - char *src_filename; - char *dest_filename; - char *orig_filename; - char *arg; - char *cur_arg = NULL; - - option = find_option (component, - gc_backend[backend].option_name, GC_BACKEND_ANY); - assert (option); - assert (option->active); - assert (gc_arg_type[option->arg_type].fallback != GC_ARG_TYPE_NONE); - - /* FIXME. Throughout the function, do better error reporting. */ - /* Note that get_config_pathname() calls percent_deescape(), so we - call this before processing the arguments. */ - dest_filename = xstrdup (get_config_pathname (component, backend)); - src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ()); - orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ()); - - arg = option->new_value; - if (arg && arg[0] == '\0') - arg = NULL; - else if (arg) - { - char *end; - - arg++; - end = strchr (arg, ','); - if (end) - *end = '\0'; - - cur_arg = percent_deescape (arg); - if (end) - { - *end = ','; - arg = end + 1; - } - else - arg = NULL; - } - - res = link (dest_filename, orig_filename); - if (res < 0 && errno != ENOENT) - return -1; - if (res < 0) - { - xfree (orig_filename); - orig_filename = NULL; - } - - /* We now initialize the return strings, so the caller can do the - cleanup for us. */ - *src_filenamep = src_filename; - *dest_filenamep = dest_filename; - *orig_filenamep = orig_filename; - - /* Use open() so that we can use O_EXCL. */ - fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644); - if (fd < 0) - return -1; - src_file = fdopen (fd, "w"); - res = errno; - if (!src_file) - { - errno = res; - return -1; - } - - /* Only if ORIG_FILENAME is not NULL did the configuration file - exist already. In this case, we will copy its content into the - new configuration file, changing it to our liking in the - process. */ - if (orig_filename) - { - dest_file = fopen (dest_filename, "r"); - if (!dest_file) - goto change_file_one_err; - - while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0) - { - int disable = 0; - char *start; - - if (!strncmp (marker, line, sizeof (marker) - 1)) - { - if (!in_marker) - in_marker = 1; - else - break; - } - - start = line; - while (*start == ' ' || *start == '\t') - start++; - if (*start && *start != '\r' && *start != '\n' && *start != '#') - { - char *end; - char *endp; - char saved_end; - - endp = start; - end = endp; - - /* Search for the end of the line. */ - while (*endp && *endp != '#' && *endp != '\r' && *endp != '\n') - { - endp++; - if (*endp && *endp != ' ' && *endp != '\t' - && *endp != '\r' && *endp != '\n' && *endp != '#') - end = endp + 1; - } - saved_end = *end; - *end = '\0'; - - if ((option->new_flags & GC_OPT_FLAG_DEFAULT) - || !cur_arg || strcmp (start, cur_arg)) - disable = 1; - else - { - /* Find next argument. */ - if (arg) - { - char *arg_end; - - arg++; - arg_end = strchr (arg, ','); - if (arg_end) - *arg_end = '\0'; - - cur_arg = percent_deescape (arg); - if (arg_end) - { - *arg_end = ','; - arg = arg_end + 1; - } - else - arg = NULL; - } - else - cur_arg = NULL; - } - - *end = saved_end; - } - - if (disable) - { - if (!in_marker) - { - fprintf (src_file, - "# GPGConf disabled this option here at %s\n", - asctimestamp (gnupg_get_time ())); - if (ferror (src_file)) - goto change_file_one_err; - fprintf (src_file, "# %s", line); - if (ferror (src_file)) - goto change_file_one_err; - } - } - else - { - fprintf (src_file, "%s", line); - if (ferror (src_file)) - goto change_file_one_err; - } - } - if (length < 0 || ferror (dest_file)) - goto change_file_one_err; - } - - if (!in_marker) - { - /* There was no marker. This is the first time we edit the - file. We add our own marker at the end of the file and - proceed. Note that we first write a newline, this guards us - against files which lack the newline at the end of the last - line, while it doesn't hurt us in all other cases. */ - fprintf (src_file, "\n%s\n", marker); - if (ferror (src_file)) - goto change_file_one_err; - } - - /* At this point, we have copied everything up to the end marker - into the new file, except for the arguments we are going to add. - Now, dump the new arguments and write the end marker, possibly - followed by the rest of the original file. */ - while (cur_arg) - { - fprintf (src_file, "%s\n", cur_arg); - - /* Find next argument. */ - if (arg) - { - char *end; - - arg++; - end = strchr (arg, ','); - if (end) - *end = '\0'; - - cur_arg = percent_deescape (arg); - if (end) - { - *end = ','; - arg = end + 1; - } - else - arg = NULL; - } - else - cur_arg = NULL; - } - - fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ())); - if (ferror (src_file)) - goto change_file_one_err; - - if (!in_marker) - { - fprintf (src_file, "# GPGConf edited this configuration file.\n"); - if (ferror (src_file)) - goto change_file_one_err; - fprintf (src_file, "# It will disable options before this marked " - "block, but it will\n"); - if (ferror (src_file)) - goto change_file_one_err; - fprintf (src_file, "# never change anything below these lines.\n"); - if (ferror (src_file)) - goto change_file_one_err; - } - if (dest_file) - { - while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0) - { - fprintf (src_file, "%s", line); - if (ferror (src_file)) - goto change_file_one_err; - } - if (length < 0 || ferror (dest_file)) - goto change_file_one_err; - } - xfree (line); - line = NULL; - - res = fclose (src_file); - if (res) - { - res = errno; - close (fd); - if (dest_file) - fclose (dest_file); - errno = res; - return -1; - } - close (fd); - if (dest_file) - { - res = fclose (dest_file); - if (res) - return -1; - } - return 0; - - change_file_one_err: - xfree (line); - res = errno; - if (src_file) - { - fclose (src_file); - close (fd); - } - if (dest_file) - fclose (dest_file); - errno = res; - return -1; -} - - -/* Create and verify the new configuration file for the specified - backend and component. Returns 0 on success and -1 on error. */ -static int -change_options_program (gc_component_t component, gc_backend_t backend, - char **src_filenamep, char **dest_filenamep, - char **orig_filenamep) -{ - static const char marker[] = "###+++--- GPGConf ---+++###"; - /* True if we are within the marker in the config file. */ - int in_marker = 0; - gc_option_t *option; - char *line = NULL; - size_t line_len; - ssize_t length; - int res; - int fd; - FILE *src_file = NULL; - FILE *dest_file = NULL; - char *src_filename; - char *dest_filename; - char *orig_filename; - - /* FIXME. Throughout the function, do better error reporting. */ - dest_filename = xstrdup (get_config_pathname (component, backend)); - src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ()); - orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ()); - - res = link (dest_filename, orig_filename); - if (res < 0 && errno != ENOENT) - return -1; - if (res < 0) - { - xfree (orig_filename); - orig_filename = NULL; - } - - /* We now initialize the return strings, so the caller can do the - cleanup for us. */ - *src_filenamep = src_filename; - *dest_filenamep = dest_filename; - *orig_filenamep = orig_filename; - - /* Use open() so that we can use O_EXCL. */ - fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644); - if (fd < 0) - return -1; - src_file = fdopen (fd, "w"); - res = errno; - if (!src_file) - { - errno = res; - return -1; - } - - /* Only if ORIG_FILENAME is not NULL did the configuration file - exist already. In this case, we will copy its content into the - new configuration file, changing it to our liking in the - process. */ - if (orig_filename) - { - dest_file = fopen (dest_filename, "r"); - if (!dest_file) - goto change_one_err; - - while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0) - { - int disable = 0; - char *start; - - if (!strncmp (marker, line, sizeof (marker) - 1)) - { - if (!in_marker) - in_marker = 1; - else - break; - } - - start = line; - while (*start == ' ' || *start == '\t') - start++; - if (*start && *start != '\r' && *start != '\n' && *start != '#') - { - char *end; - char saved_end; - - end = start; - while (*end && *end != ' ' && *end != '\t' - && *end != '\r' && *end != '\n' && *end != '#') - end++; - saved_end = *end; - *end = '\0'; - - option = find_option (component, start, backend); - *end = saved_end; - if (option && ((option->new_flags & GC_OPT_FLAG_DEFAULT) - || option->new_value)) - disable = 1; - } - if (disable) - { - if (!in_marker) - { - fprintf (src_file, - "# GPGConf disabled this option here at %s\n", - asctimestamp (gnupg_get_time ())); - if (ferror (src_file)) - goto change_one_err; - fprintf (src_file, "# %s", line); - if (ferror (src_file)) - goto change_one_err; - } - } - else - { - fprintf (src_file, "%s", line); - if (ferror (src_file)) - goto change_one_err; - } - } - if (length < 0 || ferror (dest_file)) - goto change_one_err; - } - - if (!in_marker) - { - /* There was no marker. This is the first time we edit the - file. We add our own marker at the end of the file and - proceed. Note that we first write a newline, this guards us - against files which lack the newline at the end of the last - line, while it doesn't hurt us in all other cases. */ - fprintf (src_file, "\n%s\n", marker); - if (ferror (src_file)) - goto change_one_err; - } - /* At this point, we have copied everything up to the end marker - into the new file, except for the options we are going to change. - Now, dump the changed options (except for those we are going to - revert to their default), and write the end marker, possibly - followed by the rest of the original file. */ - - /* We have to turn on UTF8 strings for GnuPG. */ - if (backend == GC_BACKEND_GPG) - fprintf (src_file, "utf8-strings\n"); - - option = gc_component[component].options; - while (option->name) - { - if (!(option->flags & GC_OPT_FLAG_GROUP) - && option->backend == backend - && option->new_value) - { - char *arg = option->new_value; - - do - { - if (*arg == '\0' || *arg == ',') - { - fprintf (src_file, "%s\n", option->name); - if (ferror (src_file)) - goto change_one_err; - } - else if (gc_arg_type[option->arg_type].fallback - == GC_ARG_TYPE_NONE) - { - assert (*arg == '1'); - fprintf (src_file, "%s\n", option->name); - if (ferror (src_file)) - goto change_one_err; - - arg++; - } - else if (gc_arg_type[option->arg_type].fallback - == GC_ARG_TYPE_STRING) - { - char *end; - - assert (*arg == '"'); - arg++; - - end = strchr (arg, ','); - if (end) - *end = '\0'; - - fprintf (src_file, "%s %s\n", option->name, - percent_deescape (arg)); - if (ferror (src_file)) - goto change_one_err; - - if (end) - *end = ','; - arg = end; - } - else - { - char *end; - - end = strchr (arg, ','); - if (end) - *end = '\0'; - - fprintf (src_file, "%s %s\n", option->name, arg); - if (ferror (src_file)) - goto change_one_err; - - if (end) - *end = ','; - arg = end; - } - - assert (arg == NULL || *arg == '\0' || *arg == ','); - if (arg && *arg == ',') - arg++; - } - while (arg && *arg); - } - option++; - } - - fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ())); - if (ferror (src_file)) - goto change_one_err; - - if (!in_marker) - { - fprintf (src_file, "# GPGConf edited this configuration file.\n"); - if (ferror (src_file)) - goto change_one_err; - fprintf (src_file, "# It will disable options before this marked " - "block, but it will\n"); - if (ferror (src_file)) - goto change_one_err; - fprintf (src_file, "# never change anything below these lines.\n"); - if (ferror (src_file)) - goto change_one_err; - } - if (dest_file) - { - while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0) - { - fprintf (src_file, "%s", line); - if (ferror (src_file)) - goto change_one_err; - } - if (length < 0 || ferror (dest_file)) - goto change_one_err; - } - xfree (line); - line = NULL; - - res = fclose (src_file); - if (res) - { - res = errno; - close (fd); - if (dest_file) - fclose (dest_file); - errno = res; - return -1; - } - close (fd); - if (dest_file) - { - res = fclose (dest_file); - if (res) - return -1; - } - return 0; - - change_one_err: - xfree (line); - res = errno; - if (src_file) - { - fclose (src_file); - close (fd); - } - if (dest_file) - fclose (dest_file); - errno = res; - return -1; -} - - -/* Read the modifications from IN and apply them. */ -void -gc_component_change_options (int component, FILE *in) -{ - int err = 0; - int runtime[GC_BACKEND_NR]; - char *src_pathname[GC_BACKEND_NR]; - char *dest_pathname[GC_BACKEND_NR]; - char *orig_pathname[GC_BACKEND_NR]; - gc_backend_t backend; - gc_option_t *option; - char *line = NULL; - size_t line_len = 0; - ssize_t length; - - for (backend = 0; backend < GC_BACKEND_NR; backend++) - { - runtime[backend] = 0; - src_pathname[backend] = NULL; - dest_pathname[backend] = NULL; - orig_pathname[backend] = NULL; - } - - while ((length = read_line (in, &line, &line_len, NULL)) > 0) - { - char *linep; - unsigned long flags = 0; - char *new_value = ""; - unsigned long new_value_nr; - - /* Strip newline and carriage return, if present. */ - while (length > 0 - && (line[length - 1] == '\n' || line[length - 1] == '\r')) - line[--length] = '\0'; - - linep = strchr (line, ':'); - if (linep) - *(linep++) = '\0'; - - /* Extract additional flags. Default to none. */ - if (linep) - { - char *end; - char *tail; - - end = strchr (linep, ':'); - if (end) - *(end++) = '\0'; - - errno = 0; - flags = strtoul (linep, &tail, 0); - if (errno) - gc_error (1, errno, "malformed flags in option %s", line); - if (!(*tail == '\0' || *tail == ':' || *tail == ' ')) - gc_error (1, 0, "garbage after flags in option %s", line); - - linep = end; - } - - /* Extract default value, if present. Default to empty if - not. */ - if (linep) - { - char *end; - - end = strchr (linep, ':'); - if (end) - *(end++) = '\0'; - - new_value = linep; - - linep = end; - } - - option = find_option (component, line, GC_BACKEND_ANY); - if (!option) - gc_error (1, 0, "unknown option %s", line); - - option_check_validity (option, flags, new_value, &new_value_nr); - - if (option->flags & GC_OPT_FLAG_RUNTIME) - runtime[option->backend] = 1; - - option->new_flags = flags; - if (!(flags & GC_OPT_FLAG_DEFAULT)) - { - if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE - && (option->flags & GC_OPT_FLAG_LIST)) - { - char *str; - - /* We convert the number to a list of 1's for - convenient list handling. */ - assert (new_value_nr > 0); - option->new_value = xmalloc ((2 * (new_value_nr - 1) + 1) + 1); - str = option->new_value; - *(str++) = '1'; - while (--new_value_nr > 0) - { - *(str++) = ','; - *(str++) = '1'; - } - *(str++) = '\0'; - } - else - option->new_value = xstrdup (new_value); - } - } - - /* Now that we have collected and locally verified the changes, - write them out to new configuration files, verify them - externally, and then commit them. */ - option = gc_component[component].options; - while (option->name) - { - /* Go on if we have already seen this backend, or if there is - nothing to do. */ - if (src_pathname[option->backend] - || !(option->new_flags || option->new_value)) - { - option++; - continue; - } - - if (gc_backend[option->backend].program) - err = change_options_program (component, option->backend, - &src_pathname[option->backend], - &dest_pathname[option->backend], - &orig_pathname[option->backend]); - else - err = change_options_file (component, option->backend, - &src_pathname[option->backend], - &dest_pathname[option->backend], - &orig_pathname[option->backend]); - - if (err) - break; - - option++; - } - - if (!err) - { - int i; - - for (i = 0; i < GC_BACKEND_NR; i++) - { - if (src_pathname[i]) - { - /* FIXME: Make a verification here. */ - - assert (dest_pathname[i]); - - if (orig_pathname[i]) - err = rename (src_pathname[i], dest_pathname[i]); - else - { - /* This is a bit safer than rename() because we - expect DEST_PATHNAME not to be there. If it - happens to be there, this will fail. */ - err = link (src_pathname[i], dest_pathname[i]); - if (!err) - unlink (src_pathname[i]); - } - if (err) - break; - src_pathname[i] = NULL; - } - } - } - - if (err) - { - int i; - int saved_errno = errno; - - /* An error occured. */ - for (i = 0; i < GC_BACKEND_NR; i++) - { - if (src_pathname[i]) - { - /* The change was not yet committed. */ - unlink (src_pathname[i]); - if (orig_pathname[i]) - unlink (orig_pathname[i]); - } - else - { - /* The changes were already committed. FIXME: This is a - tad dangerous, as we don't know if we don't overwrite - a version of the file that is even newer than the one - we just installed. */ - if (orig_pathname[i]) - rename (orig_pathname[i], dest_pathname[i]); - else - unlink (dest_pathname[i]); - } - } - gc_error (1, saved_errno, "could not commit changes"); - } - - /* If it all worked, notify the daemons of the changes. */ - if (opt.runtime) - for (backend = 0; backend < GC_BACKEND_NR; backend++) - { - if (runtime[backend] && gc_backend[backend].runtime_change) - (*gc_backend[backend].runtime_change) (); - } - - /* Move the per-process backup file into its place. */ - for (backend = 0; backend < GC_BACKEND_NR; backend++) - if (orig_pathname[backend]) - { - char *backup_pathname; - - assert (dest_pathname[backend]); - - backup_pathname = xasprintf ("%s.gpgconf.bak", dest_pathname[backend]); - rename (orig_pathname[backend], backup_pathname); - } - - xfree (line); -} diff --git a/tools/gpgconf.c b/tools/gpgconf.c deleted file mode 100644 index 7aca335fa..000000000 --- a/tools/gpgconf.c +++ /dev/null @@ -1,206 +0,0 @@ -/* gpgconf.c - Configuration utility for GnuPG - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "gpgconf.h" -#include "i18n.h" - -/* Constants to identify the commands and options. */ -enum cmd_and_opt_values - { - aNull = 0, - oDryRun = 'n', - oOutput = 'o', - oQuiet = 'q', - oVerbose = 'v', - oRuntime = 'r', - oComponent = 'c', - oNoVerbose = 500, - oHomedir, - - aListComponents, - aListOptions, - aChangeOptions, - - }; - - -/* The list of commands and options. */ -static ARGPARSE_OPTS opts[] = - { - { 300, NULL, 0, N_("@Commands:\n ") }, - - { aListComponents, "list-components", 256, N_("list all components") }, - { aListOptions, "list-options", 256, N_("|COMPONENT|list options") }, - { aChangeOptions, "change-options", 256, N_("|COMPONENT|change options") }, - - { 301, NULL, 0, N_("@\nOptions:\n ") }, - - { oOutput, "output", 2, N_("use as output file") }, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("quiet") }, - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - { oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") }, - - /* hidden options */ - { oNoVerbose, "no-verbose", 0, "@"}, - {0} - }; - - -/* Print usage information and and provide strings for help. */ -static const char * -my_strusage( int level ) -{ - const char *p; - - switch (level) - { - case 11: p = "gpgconf (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: gpgconf [options] (-h for help)"); - break; - case 41: - p = _("Syntax: gpgconf [options]\n" - "Manage configuration options for tools of the GnuPG system\n"); - break; - - default: p = NULL; break; - } - return p; -} - - -/* Initialize the gettext system. */ -static void -i18n_init(void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file (PACKAGE_GT); -#else -# ifdef ENABLE_NLS -# ifdef HAVE_LC_MESSAGES - setlocale (LC_TIME, ""); - setlocale (LC_MESSAGES, ""); -# else - setlocale (LC_ALL, "" ); -# endif - bindtextdomain (PACKAGE_GT, LOCALEDIR); - textdomain (PACKAGE_GT); -# endif -#endif -} - - -/* gpgconf main. */ -int -main (int argc, char **argv) -{ - ARGPARSE_ARGS pargs; - const char *fname; - int no_more_options = 0; - enum cmd_and_opt_values cmd = 0; - - set_strusage (my_strusage); - log_set_prefix ("gpgconf", 1); - - i18n_init(); - - /* Parse the command line. */ - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags = 1; /* Do not remove the args. */ - while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts)) - { - switch (pargs.r_opt) - { - case oOutput: opt.outfile = pargs.r.ret_str; break; - case oQuiet: opt.quiet = 1; break; - case oDryRun: opt.dry_run = 1; break; - case oRuntime: - opt.runtime = 1; - break; - case oVerbose: opt.verbose++; break; - case oNoVerbose: opt.verbose = 0; break; - - case aListComponents: - case aListOptions: - case aChangeOptions: - cmd = pargs.r_opt; - break; - - default: pargs.err = 2; break; - } - } - - if (log_get_errorcount (0)) - exit (2); - - fname = argc ? *argv : NULL; - - switch (cmd) - { - case aListComponents: - default: - /* List all components. */ - gc_component_list_components (stdout); - break; - - case aListOptions: - case aChangeOptions: - if (!fname) - { - fputs (N_("usage: gpgconf [options] "), stderr); - fputs (N_("Need one component argument"), stderr); - putc ('\n',stderr); - exit (2); - } - else - { - int idx = gc_component_find (fname); - if (idx < 0) - { - fputs (N_("Component not found"), stderr); - putc ('\n', stderr); - exit (1); - } - gc_component_retrieve_options (idx); - if (cmd == aListOptions) - gc_component_list_options (idx, stdout); - else - gc_component_change_options (idx, stdin); - } - } - - return 0; -} - - - diff --git a/tools/gpgconf.h b/tools/gpgconf.h deleted file mode 100644 index 138380b6d..000000000 --- a/tools/gpgconf.h +++ /dev/null @@ -1,58 +0,0 @@ -/* gpgconf.h - Global definitions for gpgconf - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GPGCONF_H -#define GPGCONF_H - -#include "../common/util.h" - -/* We keep all global options in the structure OPT. */ -struct -{ - int verbose; /* Verbosity level. */ - int quiet; /* Be extra quiet. */ - int dry_run; /* Don't change any persistent data. */ - int runtime; /* Make changes active at runtime. */ - char *outfile; /* Name of output file. */ - - int component; /* The active component. */ -} opt; - - - -/*-- gpgconf-comp.c --*/ -/* List all components that are available. */ -void gc_component_list_components (FILE *out); - -/* Find the component with the name NAME. Returns -1 if not - found. */ -int gc_component_find (const char *name); - -/* Retrieve the currently active options and their defaults from all - involved backends for this component. */ -void gc_component_retrieve_options (int component); - -/* List all options of the component COMPONENT. */ -void gc_component_list_options (int component, FILE *out); - -/* Read the modifications from IN and apply them. */ -void gc_component_change_options (int component, FILE *in); - -#endif /*GPGCONF_H*/ diff --git a/tools/gpgparsemail.c b/tools/gpgparsemail.c deleted file mode 100644 index fa848c8f6..000000000 --- a/tools/gpgparsemail.c +++ /dev/null @@ -1,705 +0,0 @@ -/* gpgparsemail.c - Standalone crypto mail parser - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -/* This utility prints an RFC8222, possible MIME structured, message - in an annotated format with the first column having an indicator - for the content of the line.. Several options are available to - scrutinize the message. S/MIME and OpenPGP suuport is included. */ - - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <errno.h> -#include <stdarg.h> -#include <assert.h> -#include <time.h> -#include <signal.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/wait.h> - -#include "rfc822parse.h" - - -#define PGM "gpgparsemail" - -/* Option flags. */ -static int verbose; -static int debug; -static int opt_crypto; /* Decrypt or verify messages. */ -static int opt_no_header; /* Don't output the header lines. */ - -/* Structure used to communicate with the parser callback. */ -struct parse_info_s { - int show_header; /* Show the header lines. */ - int show_data; /* Show the data lines. */ - unsigned int skip_show; /* Temporary disable above for these - number of lines. */ - int show_data_as_note; /* The next data line should be shown - as a note. */ - int show_boundary; - int nesting_level; - - int gpgsm_mime; /* gpgsm shall be used from S/MIME. */ - char *signing_protocol; - int hashing_level; /* The nesting level we are hashing. */ - int hashing; - FILE *hash_file; - FILE *sig_file; - int verify_now; /* Falg set when all signature data is - available. */ -}; - - -/* Print diagnostic message and exit with failure. */ -static void -die (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", PGM); - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - putc ('\n', stderr); - - exit (1); -} - - -/* Print diagnostic message. */ -static void -err (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", PGM); - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - putc ('\n', stderr); -} - -static void * -xmalloc (size_t n) -{ - void *p = malloc (n); - if (!p) - die ("out of core: %s", strerror (errno)); - return p; -} - -/* static void * */ -/* xcalloc (size_t n, size_t m) */ -/* { */ -/* void *p = calloc (n, m); */ -/* if (!p) */ -/* die ("out of core: %s", strerror (errno)); */ -/* return p; */ -/* } */ - -/* static void * */ -/* xrealloc (void *old, size_t n) */ -/* { */ -/* void *p = realloc (old, n); */ -/* if (!p) */ -/* die ("out of core: %s", strerror (errno)); */ -/* return p; */ -/* } */ - -static char * -xstrdup (const char *string) -{ - void *p = malloc (strlen (string)+1); - if (!p) - die ("out of core: %s", strerror (errno)); - strcpy (p, string); - return p; -} - -static char * -stpcpy (char *a,const char *b) -{ - while (*b) - *a++ = *b++; - *a = 0; - - return (char*)a; -} - - -static int -run_gnupg (int smime, int sig_fd, int data_fd, int *close_list) -{ - int rp[2]; - pid_t pid; - int i, c, is_status; - unsigned int pos; - char status_buf[10]; - const char *cmd = smime? "gpgsm":"gpg"; - FILE *fp; - - if (pipe (rp) == -1) - die ("error creating a pipe: %s", strerror (errno)); - - pid = fork (); - if (pid == -1) - die ("error forking process: %s", strerror (errno)); - - if (!pid) - { /* Child. */ - char data_fd_buf[50]; - int fd; - - /* Connect our signature fd to stdin. */ - if (sig_fd != 0) - { - if (dup2 (sig_fd, 0) == -1) - die ("dup2 stdin failed: %s", strerror (errno)); - } - - /* Keep our data fd and format it for gpg/gpgsm use. */ - sprintf (data_fd_buf, "-&%d", data_fd); - - /* Send stdout to the bit bucket. */ - fd = open ("/dev/null", O_WRONLY); - if (fd == -1) - die ("can't open `/dev/null': %s", strerror (errno)); - if (fd != 1) - { - if (dup2 (fd, 1) == -1) - die ("dup2 stderr failed: %s", strerror (errno)); - } - - /* Connect stderr to our pipe. */ - if (rp[1] != 2) - { - if (dup2 (rp[1], 2) == -1) - die ("dup2 stderr failed: %s", strerror (errno)); - } - - /* Close other files. */ - for (i=0; (fd=close_list[i]) != -1; i++) - if (fd > 2 && fd != data_fd) - close (fd); - errno = 0; - - execlp (cmd, cmd, - "--enable-special-filenames", - "--status-fd", "2", - "--assume-base64", - "--verify", - "--", - "-", data_fd_buf, - NULL); - - die ("failed to exec the crypto command: %s", strerror (errno)); - } - - /* Parent. */ - close (rp[1]); - - fp = fdopen (rp[0], "r"); - if (!fp) - die ("can't fdopen pipe for reading: %s", strerror (errno)); - - pos = 0; - is_status = 0; - assert (sizeof status_buf > 9); - while ((c=getc (fp)) != EOF) - { - if (pos < 9) - status_buf[pos] = c; - else - { - if (pos == 9) - { - is_status = !memcmp (status_buf, "[GNUPG:] ", 9); - if (is_status) - fputs ( "c ", stdout); - else if (verbose) - fputs ( "# ", stdout); - fwrite (status_buf, 9, 1, stdout); - } - putchar (c); - } - if (c == '\n') - { - if (verbose && pos < 9) - { - fputs ( "# ", stdout); - fwrite (status_buf, pos+1, 1, stdout); - } - pos = 0; - } - else - pos++; - } - if (pos) - { - if (verbose && pos < 9) - { - fputs ( "# ", stdout); - fwrite (status_buf, pos+1, 1, stdout); - } - putchar ('\n'); - } - fclose (fp); - - while ( (i=waitpid (pid, NULL, 0)) == -1 && errno == EINTR) - ; - if (i == -1) - die ("waiting for child failed: %s", strerror (errno)); - - return 0; -} - - - - -/* Verify the signature in the current temp files. */ -static void -verify_signature (struct parse_info_s *info) -{ - int close_list[10]; - - assert (info->hash_file); - assert (info->sig_file); - rewind (info->hash_file); - rewind (info->sig_file); - -/* printf ("# Begin hashed data\n"); */ -/* while ( (c=getc (info->hash_file)) != EOF) */ -/* putchar (c); */ -/* printf ("# End hashed data signature\n"); */ -/* printf ("# Begin signature\n"); */ -/* while ( (c=getc (info->sig_file)) != EOF) */ -/* putchar (c); */ -/* printf ("# End signature\n"); */ -/* rewind (info->hash_file); */ -/* rewind (info->sig_file); */ - - close_list[0] = -1; - run_gnupg (1, fileno (info->sig_file), fileno (info->hash_file), close_list); -} - - - - - -/* Prepare for a multipart/signed. - FIELD_CTX is the parsed context of the content-type header.*/ -static void -mime_signed_begin (struct parse_info_s *info, rfc822parse_t msg, - rfc822parse_field_t field_ctx) -{ - const char *s; - s = rfc822parse_query_parameter (field_ctx, "protocol", 1); - if (s) - { - printf ("h signed.protocol: %s\n", s); - if (!strcmp (s, "application/pkcs7-signature") - || !strcmp (s, "application/x-pkcs7-signature")) - { - if (info->gpgsm_mime) - err ("note: ignoring nested pkcs7-signature"); - else - { - info->gpgsm_mime = 1; - free (info->signing_protocol); - info->signing_protocol = xstrdup (s); - } - } - else if (verbose) - printf ("# this protocol is not supported\n"); - } -} - - -/* Prepare for a multipart/encrypted. - FIELD_CTX is the parsed context of the content-type header.*/ -static void -mime_encrypted_begin (struct parse_info_s *info, rfc822parse_t msg, - rfc822parse_field_t field_ctx) -{ - const char *s; - s = rfc822parse_query_parameter (field_ctx, "protocol", 0); - if (s) - printf ("h encrypted.protocol: %s\n", s); -} - - - -/* Print the event received by the parser for debugging as comment - line. */ -static void -show_event (rfc822parse_event_t event) -{ - const char *s; - - switch (event) - { - case RFC822PARSE_OPEN: s= "Open"; break; - case RFC822PARSE_CLOSE: s= "Close"; break; - case RFC822PARSE_CANCEL: s= "Cancel"; break; - case RFC822PARSE_T2BODY: s= "T2Body"; break; - case RFC822PARSE_FINISH: s= "Finish"; break; - case RFC822PARSE_RCVD_SEEN: s= "Rcvd_Seen"; break; - case RFC822PARSE_LEVEL_DOWN: s= "Level_Down"; break; - case RFC822PARSE_LEVEL_UP: s= "Level_Up"; break; - case RFC822PARSE_BOUNDARY: s= "Boundary"; break; - case RFC822PARSE_LAST_BOUNDARY: s= "Last_Boundary"; break; - case RFC822PARSE_BEGIN_HEADER: s= "Begin_Header"; break; - case RFC822PARSE_PREAMBLE: s= "Preamble"; break; - case RFC822PARSE_EPILOGUE: s= "Epilogue"; break; - default: s= "[unknown event]"; break; - } - printf ("# *** got RFC822 event %s\n", s); -} - -/* This function is called by the parser to communicate events. This - callback comminucates with the main program using a structure - passed in OPAQUE. Should retrun 0 or set errno and return -1. */ -static int -message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg) -{ - struct parse_info_s *info = opaque; - - if (debug) - show_event (event); - if (event == RFC822PARSE_OPEN) - { - /* Initialize for a new message. */ - info->show_header = 1; - } - else if (event == RFC822PARSE_T2BODY) - { - rfc822parse_field_t ctx; - - ctx = rfc822parse_parse_field (msg, "Content-Type", -1); - if (ctx) - { - const char *s1, *s2; - s1 = rfc822parse_query_media_type (ctx, &s2); - if (s1) - { - printf ("h media: %*s%s %s\n", - info->nesting_level*2, "", s1, s2); - if (info->gpgsm_mime == 3) - { - char *buf = xmalloc (strlen (s1) + strlen (s2) + 2); - strcpy (stpcpy (stpcpy (buf, s1), "/"), s2); - assert (info->signing_protocol); - if (strcmp (buf, info->signing_protocol)) - err ("invalid S/MIME structure; expected `%s', found `%s'", - info->signing_protocol, buf); - else - { - printf ("c begin_signature\n"); - info->gpgsm_mime++; - if (opt_crypto) - { - assert (!info->sig_file); - info->sig_file = tmpfile (); - if (!info->sig_file) - die ("error creating temp file: %s", - strerror (errno)); - } - } - free (buf); - } - else if (!strcmp (s1, "multipart")) - { - if (!strcmp (s2, "signed")) - mime_signed_begin (info, msg, ctx); - else if (!strcmp (s2, "encrypted")) - mime_encrypted_begin (info, msg, ctx); - } - } - else - printf ("h media: %*s none\n", info->nesting_level*2, ""); - - rfc822parse_release_field (ctx); - } - else - printf ("h media: %*stext plain [assumed]\n", - info->nesting_level*2, ""); - info->show_header = 0; - info->show_data = 1; - info->skip_show = 1; - } - else if (event == RFC822PARSE_PREAMBLE) - info->show_data_as_note = 1; - else if (event == RFC822PARSE_LEVEL_DOWN) - { - printf ("b down\n"); - info->nesting_level++; - } - else if (event == RFC822PARSE_LEVEL_UP) - { - printf ("b up\n"); - if (info->nesting_level) - info->nesting_level--; - else - err ("invalid structure (bad nesting level)"); - } - else if (event == RFC822PARSE_BOUNDARY || event == RFC822PARSE_LAST_BOUNDARY) - { - info->show_data = 0; - info->show_boundary = 1; - if (event == RFC822PARSE_BOUNDARY) - { - info->show_header = 1; - info->skip_show = 1; - printf ("b part\n"); - } - else - printf ("b last\n"); - - if (info->gpgsm_mime == 2 && info->nesting_level == info->hashing_level) - { - printf ("c end_hash\n"); - info->gpgsm_mime++; - info->hashing = 0; - } - else if (info->gpgsm_mime == 4) - { - printf ("c end_signature\n"); - info->verify_now = 1; - } - } - else if (event == RFC822PARSE_BEGIN_HEADER) - { - if (info->gpgsm_mime == 1) - { - printf ("c begin_hash\n"); - info->hashing = 1; - info->hashing_level = info->nesting_level; - info->gpgsm_mime++; - - if (opt_crypto) - { - assert (!info->hash_file); - info->hash_file = tmpfile (); - if (!info->hash_file) - die ("failed to create temporary file: %s", strerror (errno)); - } - } - } - - return 0; -} - - -/* Read a message from FP and process it according to the global - options. */ -static void -parse_message (FILE *fp) -{ - char line[5000]; - size_t length; - rfc822parse_t msg; - unsigned int lineno = 0; - int no_cr_reported = 0; - struct parse_info_s info; - - memset (&info, 0, sizeof info); - - msg = rfc822parse_open (message_cb, &info); - if (!msg) - die ("can't open parser: %s", strerror (errno)); - - /* Fixme: We should not use fgets becuase it can't cope with - embedded nul characters. */ - while (fgets (line, sizeof (line), fp)) - { - lineno++; - if (lineno == 1 && !strncmp (line, "From ", 5)) - continue; /* We better ignore a leading From line. */ - - length = strlen (line); - if (length && line[length - 1] == '\n') - line[--length] = 0; - else - err ("line number %u too long or last line not terminated", lineno); - if (length && line[length - 1] == '\r') - line[--length] = 0; - else if (verbose && !no_cr_reported) - { - err ("non canonical ended line detected (line %u)", lineno); - no_cr_reported = 1; - } - - - if (rfc822parse_insert (msg, line, length)) - die ("parser failed: %s", strerror (errno)); - - if (info.hashing) - { - /* Delay hashing of the CR/LF because the last line ending - belongs to the next boundary. */ - if (debug) - printf ("# hashing %s`%s'\n", info.hashing==2?"CR,LF+":"", line); - if (opt_crypto) - { - if (info.hashing == 2) - fputs ("\r\n", info.hash_file); - fputs (line, info.hash_file); - if (ferror (info.hash_file)) - die ("error writing to temporary file: %s", strerror (errno)); - } - - info.hashing = 2; - } - - if (info.sig_file && opt_crypto) - { - if (info.verify_now) - { - verify_signature (&info); - fclose (info.hash_file); - info.hash_file = NULL; - fclose (info.sig_file); - info.sig_file = NULL; - info.gpgsm_mime = 0; - } - else - { - fputs (line, info.sig_file); - fputs ("\r\n", info.sig_file); - if (ferror (info.sig_file)) - die ("error writing to temporary file: %s", strerror (errno)); - } - } - - if (info.show_boundary) - { - if (!opt_no_header) - printf (":%s\n", line); - info.show_boundary = 0; - } - - if (info.skip_show) - info.skip_show--; - else if (info.show_data) - { - if (info.show_data_as_note) - { - if (verbose) - printf ("# DATA: %s\n", line); - info.show_data_as_note = 0; - } - else - printf (" %s\n", line); - } - else if (info.show_header && !opt_no_header) - printf (".%s\n", line); - - } - - rfc822parse_close (msg); -} - - -int -main (int argc, char **argv) -{ - int last_argc = -1; - - if (argc) - { - argc--; argv++; - } - while (argc && last_argc != argc ) - { - last_argc = argc; - if (!strcmp (*argv, "--")) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--help")) - { - puts ( - "Usage: " PGM " [OPTION] [FILE]\n" - "Parse a mail message into an annotated format.\n\n" - " --crypto decrypt or verify messages\n" - " --no-header don't output the header lines\n" - " --verbose enable extra informational output\n" - " --debug enable additional debug output\n" - " --help display this help and exit\n\n" - "With no FILE, or when FILE is -, read standard input.\n\n" - "Report bugs to <bug-gnupg@gnu.org>."); - exit (0); - } - else if (!strcmp (*argv, "--verbose")) - { - verbose = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--debug")) - { - verbose = debug = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--crypto")) - { - opt_crypto = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--no-header")) - { - opt_no_header = 1; - argc--; argv++; - } - } - - if (argc > 1) - die ("usage: " PGM " [OPTION] [FILE] (try --help for more information)\n"); - - signal (SIGPIPE, SIG_IGN); - - if (argc && strcmp (*argv, "-")) - { - FILE *fp = fopen (*argv, "rb"); - if (!fp) - die ("can't open `%s': %s", *argv, strerror (errno)); - parse_message (fp); - fclose (fp); - } - else - parse_message (stdin); - - return 0; -} - - -/* -Local Variables: -compile-command: "gcc -Wall -g -o gpgparsemail rfc822parse.c gpgparsemail.c" -End: -*/ diff --git a/tools/no-libgcrypt.c b/tools/no-libgcrypt.c deleted file mode 100644 index 0fabec90d..000000000 --- a/tools/no-libgcrypt.c +++ /dev/null @@ -1,105 +0,0 @@ -/* no-libgcrypt.c - Replacement functions for libgcrypt. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "../common/util.h" -#include "i18n.h" - - -/* Replace libgcrypt's malloc functions which are used by - ../jnlib/libjnlib.a . ../common/util.h defines macros to map them - to xmalloc etc. */ -static void -out_of_core (void) -{ - log_fatal (_("error allocating enough memory: %s\n"), strerror (errno)); -} - - -void * -gcry_malloc (size_t n) -{ - return malloc (n); -} - -void * -gcry_xmalloc (size_t n) -{ - void *p = malloc (n); - if (!p) - out_of_core (); - return p; -} - - -void * -gcry_realloc (void *a, size_t n) -{ - return realloc (a, n); -} - -void * -gcry_xrealloc (void *a, size_t n) -{ - void *p = realloc (a, n); - if (!p) - out_of_core (); - return p; -} - - - -void * -gcry_calloc (size_t n, size_t m) -{ - return calloc (n, m); -} - -void * -gcry_xcalloc (size_t n, size_t m) -{ - void *p = calloc (n, m); - if (!p) - out_of_core (); - return p; -} - - -char * -gcry_xstrdup (const char *string) -{ - void *p = malloc (strlen (string)+1); - if (!p) - out_of_core (); - strcpy( p, string ); - return p; -} - -void -gcry_free (void *a) -{ - if (a) - free (a); -} diff --git a/tools/rfc822parse.c b/tools/rfc822parse.c deleted file mode 100644 index be1cf4a47..000000000 --- a/tools/rfc822parse.c +++ /dev/null @@ -1,1235 +0,0 @@ -/* rfc822parse.c - Simple mail and MIME parser - * Copyright (C) 1999, 2000 Werner Koch, Duesseldorf - * Copyright (C) 2003, g10 Code GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -/* According to RFC822 binary 0 are allowed at many places. We - * do not handle this correct especially in the field parsing code. It - * should be easy to fix and the API provides a interfcaes which returns - * the length but in addition makes sure that returned strings are always - * ended by a \0. - * - * Furthermore, the case of field names is changed and thus it is not - * always a good idea to use these modified header - * lines (e.g. signatures may break). - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdarg.h> -#include <assert.h> - -#include "rfc822parse.h" - -enum token_type -{ - tSPACE, - tATOM, - tQUOTED, - tDOMAINLIT, - tSPECIAL -}; - -/* For now we directly use our TOKEN as the parse context */ -typedef struct rfc822parse_field_context *TOKEN; -struct rfc822parse_field_context -{ - TOKEN next; - enum token_type type; - struct { - unsigned int cont:1; - unsigned int lowered:1; - } flags; - /*TOKEN owner_pantry; */ - char data[1]; -}; - -struct hdr_line -{ - struct hdr_line *next; - int cont; /* This is a continuation of the previous line. */ - unsigned char line[1]; -}; - -typedef struct hdr_line *HDR_LINE; - - -struct part -{ - struct part *right; /* The next part. */ - struct part *down; /* A contained part. */ - HDR_LINE hdr_lines; /* Header lines os that part. */ - HDR_LINE *hdr_lines_tail; /* Helper for adding lines. */ - char *boundary; /* Only used in the first part. */ -}; -typedef struct part *part_t; - -struct rfc822parse_context -{ - rfc822parse_cb_t callback; - void *callback_value; - int callback_error; - int in_body; - int in_preamble; /* Wether we are before the first boundary. */ - part_t parts; /* The tree of parts. */ - part_t current_part; /* Whom we are processing (points into parts). */ - const char *boundary; /* Current boundary. */ -}; - -static HDR_LINE find_header (rfc822parse_t msg, const char *name, - int which, HDR_LINE * rprev); - - -static size_t -length_sans_trailing_ws (const unsigned char *line, size_t len) -{ - const unsigned char *p, *mark; - size_t n; - - for (mark=NULL, p=line, n=0; n < len; n++, p++) - { - if (strchr (" \t\r\n", *p )) - { - if( !mark ) - mark = p; - } - else - mark = NULL; - } - - if (mark) - return mark - line; - return len; -} - - -static void -lowercase_string (unsigned char *string) -{ - for (; *string; string++) - if (*string >= 'A' && *string <= 'Z') - *string = *string - 'A' + 'a'; -} - -/* Transform a header name into a standard capitalized format; i.e - "Content-Type". Conversion stops at the colon. As usual we don't - use the localized versions of ctype.h. - */ -static void -capitalize_header_name (unsigned char *name) -{ - int first = 1; - - for (; *name && *name != ':'; name++) - if (*name == '-') - first = 1; - else if (first) - { - if (*name >= 'a' && *name <= 'z') - *name = *name - 'a' + 'A'; - first = 0; - } - else if (*name >= 'A' && *name <= 'Z') - *name = *name - 'A' + 'a'; -} - - -static char * -stpcpy (char *a,const char *b) -{ - while (*b) - *a++ = *b++; - *a = 0; - - return (char*)a; -} - - -/* If a callback has been registerd, call it for the event of type - EVENT. */ -static int -do_callback (rfc822parse_t msg, rfc822parse_event_t event) -{ - int rc; - - if (!msg->callback || msg->callback_error) - return 0; - rc = msg->callback (msg->callback_value, event, msg); - if (rc) - msg->callback_error = rc; - return rc; -} - -static part_t -new_part (void) -{ - part_t part; - - part = calloc (1, sizeof *part); - if (part) - { - part->hdr_lines_tail = &part->hdr_lines; - } - return part; -} - - -static void -release_part (part_t part) -{ - part_t tmp; - HDR_LINE hdr, hdr2; - - for (; part; part = tmp) - { - tmp = part->right; - if (part->down) - release_part (part->down); - for (hdr = part->hdr_lines; hdr; hdr = hdr2) - { - hdr2 = hdr->next; - free (hdr); - } - free (part->boundary); - free (part); - } -} - - -static void -release_handle_data (rfc822parse_t msg) -{ - release_part (msg->parts); - msg->parts = NULL; - msg->current_part = NULL; - msg->boundary = NULL; -} - - -/* Create a new parsing context for an entire rfc822 message and - return it. CB and CB_VALUE may be given to callback for certain - events. NULL is returned on error with errno set appropriately. */ -rfc822parse_t -rfc822parse_open (rfc822parse_cb_t cb, void *cb_value) -{ - rfc822parse_t msg = calloc (1, sizeof *msg); - if (msg) - { - msg->parts = msg->current_part = new_part (); - if (!msg->parts) - { - free (msg); - msg = NULL; - } - else - { - msg->callback = cb; - msg->callback_value = cb_value; - if (do_callback (msg, RFC822PARSE_OPEN)) - { - release_handle_data (msg); - free (msg); - msg = NULL; - } - } - } - return msg; -} - - -void -rfc822parse_cancel (rfc822parse_t msg) -{ - if (msg) - { - do_callback (msg, RFC822PARSE_CANCEL); - release_handle_data (msg); - free (msg); - } -} - - -void -rfc822parse_close (rfc822parse_t msg) -{ - if (msg) - { - do_callback (msg, RFC822PARSE_CLOSE); - release_handle_data (msg); - free (msg); - } -} - -static part_t -find_parent (part_t tree, part_t target) -{ - part_t part; - - for (part = tree->down; part; part = part->right) - { - if (part == target) - return tree; /* Found. */ - if (part->down) - { - part_t tmp = find_parent (part, target); - if (tmp) - return tmp; - } - } - return NULL; -} - -static void -set_current_part_to_parent (rfc822parse_t msg) -{ - part_t parent; - - assert (msg->current_part); - parent = find_parent (msg->parts, msg->current_part); - if (!parent) - return; /* Already at the top. */ - -#ifndef NDEBUG - { - part_t part; - for (part = parent->down; part; part = part->right) - if (part == msg->current_part) - break; - assert (part); - } -#endif - msg->current_part = parent; - - parent = find_parent (msg->parts, parent); - msg->boundary = parent? parent->boundary: NULL; -} - - - -/**************** - * We have read in all header lines and are about to receive the body - * part. The delimiter line has already been processed. - * - * FIXME: we's better return an error in case of memory failures. - */ -static int -transition_to_body (rfc822parse_t msg) -{ - rfc822parse_field_t ctx; - int rc; - - rc = do_callback (msg, RFC822PARSE_T2BODY); - if (!rc) - { - /* Store the boundary if we have multipart type. */ - ctx = rfc822parse_parse_field (msg, "Content-Type", -1); - if (ctx) - { - const char *s; - - s = rfc822parse_query_media_type (ctx, NULL); - if (s && !strcmp (s,"multipart")) - { - s = rfc822parse_query_parameter (ctx, "boundary", 0); - if (s) - { - assert (!msg->current_part->boundary); - msg->current_part->boundary = malloc (strlen (s) + 1); - if (msg->current_part->boundary) - { - part_t part; - - strcpy (msg->current_part->boundary, s); - msg->boundary = msg->current_part->boundary; - part = new_part (); - if (!part) - { - int save_errno = errno; - rfc822parse_release_field (ctx); - errno = save_errno; - return -1; - } - rc = do_callback (msg, RFC822PARSE_LEVEL_DOWN); - assert (!msg->current_part->down); - msg->current_part->down = part; - msg->current_part = part; - msg->in_preamble = 1; - } - } - } - rfc822parse_release_field (ctx); - } - } - - return rc; -} - -/* We have just passed a MIME boundary and need to prepare for new part. - headers. */ -static int -transition_to_header (rfc822parse_t msg) -{ - part_t part; - - assert (msg->current_part); - assert (!msg->current_part->right); - - part = new_part (); - if (!part) - return -1; - - msg->current_part->right = part; - msg->current_part = part; - return 0; -} - - -static int -insert_header (rfc822parse_t msg, const unsigned char *line, size_t length) -{ - HDR_LINE hdr; - - assert (msg->current_part); - if (!length) - { - msg->in_body = 1; - return transition_to_body (msg); - } - - if (!msg->current_part->hdr_lines) - do_callback (msg, RFC822PARSE_BEGIN_HEADER); - - length = length_sans_trailing_ws (line, length); - hdr = malloc (sizeof (*hdr) + length); - if (!hdr) - return -1; - hdr->next = NULL; - hdr->cont = (*line == ' ' || *line == '\t'); - memcpy (hdr->line, line, length); - hdr->line[length] = 0; /* Make it a string. */ - - /* Transform a field name into canonical format. */ - if (!hdr->cont && strchr (line, ':')) - capitalize_header_name (hdr->line); - - *msg->current_part->hdr_lines_tail = hdr; - msg->current_part->hdr_lines_tail = &hdr->next; - - /* Lets help the caller to prevent mail loops and issue an event for - * every Received header. */ - if (length >= 9 && !memcmp (line, "Received:", 9)) - do_callback (msg, RFC822PARSE_RCVD_SEEN); - return 0; -} - - -/**************** - * Note: We handle the body transparent to allow binary zeroes in it. - */ -static int -insert_body (rfc822parse_t msg, const unsigned char *line, size_t length) -{ - int rc = 0; - - if (length > 2 && *line == '-' && line[1] == '-' && msg->boundary) - { - size_t blen = strlen (msg->boundary); - - if (length == blen + 2 - && !memcmp (line+2, msg->boundary, blen)) - { - rc = do_callback (msg, RFC822PARSE_BOUNDARY); - msg->in_body = 0; - if (!rc && !msg->in_preamble) - rc = transition_to_header (msg); - msg->in_preamble = 0; - } - else if (length == blen + 4 - && line[length-2] =='-' && line[length-1] == '-' - && !memcmp (line+2, msg->boundary, blen)) - { - rc = do_callback (msg, RFC822PARSE_LAST_BOUNDARY); - msg->boundary = NULL; /* No current boundary anymore. */ - set_current_part_to_parent (msg); - - /* Fixme: The next should acctually be sent right before the - next boundary, so that we can mark the epilogue. */ - if (!rc) - rc = do_callback (msg, RFC822PARSE_LEVEL_UP); - } - } - if (msg->in_preamble && !rc) - rc = do_callback (msg, RFC822PARSE_PREAMBLE); - - return rc; -} - -/* Insert the next line into the parser. Return 0 on success or true - on error with errno set appropriately. */ -int -rfc822parse_insert (rfc822parse_t msg, const unsigned char *line, size_t length) -{ - return (msg->in_body - ? insert_body (msg, line, length) - : insert_header (msg, line, length)); -} - - -/* Tell the parser that we have finished the message. */ -int -rfc822parse_finish (rfc822parse_t msg) -{ - return do_callback (msg, RFC822PARSE_FINISH); -} - - - -/**************** - * Get a copy of a header line. The line is returned as one long - * string with LF to separate the continuation line. Caller must free - * the return buffer. which may be used to enumerate over all lines. - * Wildcards are allowed. This function works on the current headers; - * i.e. the regular mail headers or the MIME headers of the current - * part. - * - * WHICH gives the mode: - * -1 := Take the last occurence - * n := Take the n-th one. - * - * Returns a newly allocated buffer or NULL on error. errno is set in - * case of a memory failure or set to 0 if the requested field is not - * available. - */ -char * -rfc822parse_get_field (rfc822parse_t msg, const char *name, int which) -{ - HDR_LINE h, h2; - char *buf, *p; - size_t n; - - h = find_header (msg, name, which, NULL); - if (!h) - { - errno = 0; - return NULL; /* no such field */ - } - - n = strlen (h->line) + 1; - for (h2 = h->next; h2 && h2->cont; h2 = h2->next) - n += strlen (h2->line) + 1; - - buf = p = malloc (n); - if (buf) - { - p = stpcpy (p, h->line); - *p++ = '\n'; - for (h2 = h->next; h2 && h2->cont; h2 = h2->next) - { - p = stpcpy (p, h2->line); - *p++ = '\n'; - } - p[-1] = 0; - } - return buf; -} - - -/**************** - * Enumerate all header. Caller has to provide the address of a pointer - * which has to be initialzed to NULL, the caller should then never change this - * pointer until he has closed the enumeration by passing again the address - * of the pointer but with msg set to NULL. - * The function returns pointers to all the header lines or NULL when - * all lines have been enumerated or no headers are available. - */ -const char * -rfc822parse_enum_header_lines (rfc822parse_t msg, void **context) -{ - HDR_LINE l; - - if (!msg) /* Close. */ - return NULL; - - if (*context == msg || !msg->current_part) - return NULL; - - l = *context ? (HDR_LINE) *context : msg->current_part->hdr_lines; - - if (l) - { - *context = l->next ? (void *) (l->next) : (void *) msg; - return l->line; - } - *context = msg; /* Mark end of list. */ - return NULL; -} - - - -/**************** - * Find a header field. If the Name does end in an asterisk this is meant - * to be a wildcard. - * - * which -1 : Retrieve the last field - * >0 : Retrieve the n-th field - - * RPREV may be used to return the predecessor of the returned field; - * which may be NULL for the very first one. It has to be initialzed - * to either NULL in which case the search start at the first header line, - * or it may point to a headerline, where the search should start - */ -static HDR_LINE -find_header (rfc822parse_t msg, const char *name, int which, HDR_LINE *rprev) -{ - HDR_LINE hdr, prev = NULL, mark = NULL; - unsigned char *p; - size_t namelen, n; - int found = 0; - int glob = 0; - - if (!msg->current_part) - return NULL; - - namelen = strlen (name); - if (namelen && name[namelen - 1] == '*') - { - namelen--; - glob = 1; - } - - hdr = msg->current_part->hdr_lines; - if (rprev && *rprev) - { - /* spool forward to the requested starting place. - * we cannot simply set this as we have to return - * the previous list element too */ - for (; hdr && hdr != *rprev; prev = hdr, hdr = hdr->next) - ; - } - - for (; hdr; prev = hdr, hdr = hdr->next) - { - if (hdr->cont) - continue; - if (!(p = strchr (hdr->line, ':'))) - continue; /* invalid header, just skip it. */ - n = p - hdr->line; - if (!n) - continue; /* invalid name */ - if ((glob ? (namelen <= n) : (namelen == n)) - && !memcmp (hdr->line, name, namelen)) - { - found++; - if (which == -1) - mark = hdr; - else if (found == which) - { - if (rprev) - *rprev = prev; - return hdr; - } - } - } - if (mark && rprev) - *rprev = prev; - return mark; -} - - - -static const char * -skip_ws (const char *s) -{ - while (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n') - s++; - return s; -} - - -static void -release_token_list (TOKEN t) -{ - while (t) - { - TOKEN t2 = t->next; - /* fixme: If we have owner_pantry, put the token back to - * this pantry so that it can be reused later */ - free (t); - t = t2; - } -} - - -static TOKEN -new_token (enum token_type type, const char *buf, size_t length) -{ - TOKEN t; - - /* fixme: look through our pantries to find a suitable - * token for reuse */ - t = malloc (sizeof *t + length); - if (t) - { - t->next = NULL; - t->type = type; - memset (&t->flags, 0, sizeof (t->flags)); - t->data[0] = 0; - if (buf) - { - memcpy (t->data, buf, length); - t->data[length] = 0; /* Make sure it is a C string. */ - } - else - t->data[0] = 0; - } - return t; -} - -static TOKEN -append_to_token (TOKEN old, const char *buf, size_t length) -{ - size_t n = strlen (old->data); - TOKEN t; - - t = malloc (sizeof *t + n + length); - if (t) - { - t->next = old->next; - t->type = old->type; - t->flags = old->flags; - memcpy (t->data, old->data, n); - memcpy (t->data + n, buf, length); - t->data[n + length] = 0; - old->next = NULL; - release_token_list (old); - } - return t; -} - - - -/* - Parse a field into tokens as defined by rfc822. - */ -static TOKEN -parse_field (HDR_LINE hdr) -{ - static const char specials[] = "<>@.,;:\\[]\"()"; - static const char specials2[] = "<>@.,;:"; - static const char tspecials[] = "/?=<>@,;:\\[]\"()"; - static const char tspecials2[] = "/?=<>@.,;:"; - static struct - { - const unsigned char *name; - size_t namelen; - } tspecial_header[] = { - { "Content-Type", 12}, - { "Content-Transfer-Encoding", 25}, - { NULL, 0} - }; - const char *delimiters; - const char *delimiters2; - const unsigned char *line, *s, *s2; - size_t n; - int i, invalid = 0; - TOKEN t, tok, *tok_tail; - - errno = 0; - if (!hdr) - return NULL; - - tok = NULL; - tok_tail = &tok; - - line = hdr->line; - if (!(s = strchr (line, ':'))) - return NULL; /* oops */ - - n = s - line; - if (!n) - return NULL; /* oops: invalid name */ - - delimiters = specials; - delimiters2 = specials2; - for (i = 0; tspecial_header[i].name; i++) - { - if (n == tspecial_header[i].namelen - && !memcmp (line, tspecial_header[i].name, n)) - { - delimiters = tspecials; - delimiters2 = tspecials2; - break; - } - } - - s++; /* Move over the colon. */ - for (;;) - { - if (!*s) - { - if (!hdr->next || !hdr->next->cont) - break; - hdr = hdr->next; - s = hdr->line; - } - - if (*s == '(') - { - int level = 1; - int in_quote = 0; - - invalid = 0; - for (s++;; s++) - { - if (!*s) - { - if (!hdr->next || !hdr->next->cont) - break; - hdr = hdr->next; - s = hdr->line; - } - - if (in_quote) - { - if (*s == '\"') - in_quote = 0; - else if (*s == '\\' && s[1]) /* what about continuation? */ - s++; - } - else if (*s == ')') - { - if (!--level) - break; - } - else if (*s == '(') - level++; - else if (*s == '\"') - in_quote = 1; - } - if (!*s) - ; /* Actually this is an error, but we don't care about it. */ - else - s++; - } - else if (*s == '\"' || *s == '[') - { - /* We do not check for non-allowed nesting of domainliterals */ - int term = *s == '\"' ? '\"' : ']'; - invalid = 0; - s++; - t = NULL; - - for (;;) - { - for (s2 = s; *s2; s2++) - { - if (*s2 == term) - break; - else if (*s2 == '\\' && s2[1]) /* what about continuation? */ - s2++; - } - - t = (t - ? append_to_token (t, s, s2 - s) - : new_token (term == '\"'? tQUOTED : tDOMAINLIT, s, s2 - s)); - if (!t) - goto failure; - - if (*s2 || !hdr->next || !hdr->next->cont) - break; - hdr = hdr->next; - s = hdr->line; - } - *tok_tail = t; - tok_tail = &t->next; - s = s2; - if (*s) - s++; /* skip the delimiter */ - } - else if ((s2 = strchr (delimiters2, *s))) - { /* Special characters which are not handled above. */ - invalid = 0; - t = new_token (tSPECIAL, s, 1); - if (!t) - goto failure; - *tok_tail = t; - tok_tail = &t->next; - s++; - } - else if (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n') - { - invalid = 0; - s = skip_ws (s + 1); - } - else if (*s > 0x20 && !(*s & 128)) - { /* Atom. */ - invalid = 0; - for (s2 = s + 1; *s2 > 0x20 - && !(*s2 & 128) && !strchr (delimiters, *s2); s2++) - ; - t = new_token (tATOM, s, s2 - s); - if (!t) - goto failure; - *tok_tail = t; - tok_tail = &t->next; - s = s2; - } - else - { /* Invalid character. */ - if (!invalid) - { /* For parsing we assume only one space. */ - t = new_token (tSPACE, NULL, 0); - if (!t) - goto failure; - *tok_tail = t; - tok_tail = &t->next; - invalid = 1; - } - s++; - } - } - - return tok; - - failure: - { - int save = errno; - release_token_list (tok); - errno = save; - } - return NULL; -} - - - - -/**************** - * Find and parse a header field. - * WHICH indicates what to do if there are multiple instance of the same - * field (like "Received"); the following value are defined: - * -1 := Take the last occurence - * 0 := Reserved - * n := Take the n-th one. - * Returns a handle for further operations on the parse context of the field - * or NULL if the field was not found. - */ -rfc822parse_field_t -rfc822parse_parse_field (rfc822parse_t msg, const char *name, int which) -{ - HDR_LINE hdr; - - if (!which) - return NULL; - - hdr = find_header (msg, name, which, NULL); - if (!hdr) - return NULL; - return parse_field (hdr); -} - -void -rfc822parse_release_field (rfc822parse_field_t ctx) -{ - if (ctx) - release_token_list (ctx); -} - - - -/**************** - * Check whether T points to a parameter. - * A parameter starts with a semicolon and it is assumed that t - * points to exactly this one. - */ -static int -is_parameter (TOKEN t) -{ - t = t->next; - if (!t || t->type != tATOM) - return 0; - t = t->next; - if (!t || !(t->type == tSPECIAL && t->data[0] == '=')) - return 0; - t = t->next; - if (!t) - return 1; /* We assume that an non existing value is an empty one. */ - return t->type == tQUOTED || t->type == tATOM; -} - -/* - Some header (Content-type) have a special syntax where attribute=value - pairs are used after a leading semicolon. The parse_field code - knows about these fields and changes the parsing to the one defined - in RFC2045. - Returns a pointer to the value which is valid as long as the - parse context is valid; NULL is returned in case that attr is not - defined in the header, a missing value is reppresented by an empty string. - - With LOWER_VALUE set to true, a matching field valuebe be - lowercased. - - Note, that ATTR should be lowercase. - */ -const char * -rfc822parse_query_parameter (rfc822parse_field_t ctx, const char *attr, - int lower_value) -{ - TOKEN t, a; - - for (t = ctx; t; t = t->next) - { - /* skip to the next semicolon */ - for (; t && !(t->type == tSPECIAL && t->data[0] == ';'); t = t->next) - ; - if (!t) - return NULL; - if (is_parameter (t)) - { /* Look closer. */ - a = t->next; /* We know that this is an atom */ - if ( !a->flags.lowered ) - { - lowercase_string (a->data); - a->flags.lowered = 1; - } - if (!strcmp (a->data, attr)) - { /* found */ - t = a->next->next; - /* Either T is now an atom, a quoted string or NULL in - * which case we return an empty string. */ - - if ( lower_value && t && !t->flags.lowered ) - { - lowercase_string (t->data); - t->flags.lowered = 1; - } - return t ? t->data : ""; - } - } - } - return NULL; -} - -/**************** - * This function may be used for the Content-Type header to figure out - * the media type and subtype. Note, that the returned strings are - * guaranteed to be lowercase as required by MIME. - * - * Returns: a pointer to the media type and if subtype is not NULL, - * a pointer to the subtype. - */ -const char * -rfc822parse_query_media_type (rfc822parse_field_t ctx, const char **subtype) -{ - TOKEN t = ctx; - const char *type; - - if (t->type != tATOM) - return NULL; - if (!t->flags.lowered) - { - lowercase_string (t->data); - t->flags.lowered = 1; - } - type = t->data; - t = t->next; - if (!t || t->type != tSPECIAL || t->data[0] != '/') - return NULL; - t = t->next; - if (!t || t->type != tATOM) - return NULL; - - if (subtype) - { - if (!t->flags.lowered) - { - lowercase_string (t->data); - t->flags.lowered = 1; - } - *subtype = t->data; - } - return type; -} - - - - - -#ifdef TESTING - -/* Internal debug function to print the structure of the message. */ -static void -dump_structure (rfc822parse_t msg, part_t part, int indent) -{ - if (!part) - { - printf ("*** Structure of this message:\n"); - part = msg->parts; - } - - for (; part; part = part->right) - { - rfc822parse_field_t ctx; - part_t save_part; /* ugly hack - we should have a function to - get part inforation. */ - const char *s; - - save_part = msg->current_part; - msg->current_part = part; - ctx = rfc822parse_parse_field (msg, "Content-Type", -1); - msg->current_part = save_part; - if (ctx) - { - const char *s1, *s2; - s1 = rfc822parse_query_media_type (ctx, &s2); - if (s1) - printf ("*** %*s %s/%s", indent*2, "", s1, s2); - else - printf ("*** %*s [not found]", indent*2, ""); - - s = rfc822parse_query_parameter (ctx, "boundary", 0); - if (s) - printf (" (boundary=\"%s\")", s); - rfc822parse_release_field (ctx); - } - else - printf ("*** %*s text/plain [assumed]", indent*2, ""); - putchar('\n'); - - if (part->down) - dump_structure (msg, part->down, indent + 1); - } - -} - - - -static void -show_param (rfc822parse_field_t ctx, const char *name) -{ - const char *s; - - if (!ctx) - return; - s = rfc822parse_query_parameter (ctx, name, 0); - if (s) - printf ("*** %s: `%s'\n", name, s); -} - - - -static void -show_event (rfc822parse_event_t event) -{ - const char *s; - - switch (event) - { - case RFC822PARSE_OPEN: s= "Open"; break; - case RFC822PARSE_CLOSE: s= "Close"; break; - case RFC822PARSE_CANCEL: s= "Cancel"; break; - case RFC822PARSE_T2BODY: s= "T2Body"; break; - case RFC822PARSE_FINISH: s= "Finish"; break; - case RFC822PARSE_RCVD_SEEN: s= "Rcvd_Seen"; break; - case RFC822PARSE_BOUNDARY: s= "Boundary"; break; - case RFC822PARSE_LAST_BOUNDARY: s= "Last_Boundary"; break; - default: s= "***invalid event***"; break; - } - printf ("*** got RFC822 event %s\n", s); -} - -static int -msg_cb (void *dummy_arg, rfc822parse_event_t event, rfc822parse_t msg) -{ - show_event (event); - if (event == RFC822PARSE_T2BODY) - { - rfc822parse_field_t ctx; - void *ectx; - const char *line; - - for (ectx=NULL; (line = rfc822parse_enum_header_lines (msg, &ectx)); ) - { - printf ("*** HDR: %s\n", line); - } - rfc822parse_enum_header_lines (NULL, &ectx); /* Close enumerator. */ - - ctx = rfc822parse_parse_field (msg, "Content-Type", -1); - if (ctx) - { - const char *s1, *s2; - s1 = rfc822parse_query_media_type (ctx, &s2); - if (s1) - printf ("*** media: `%s/%s'\n", s1, s2); - else - printf ("*** media: [not found]\n"); - show_param (ctx, "boundary"); - show_param (ctx, "protocol"); - rfc822parse_release_field (ctx); - } - else - printf ("*** media: text/plain [assumed]\n"); - - } - - - return 0; -} - - - -int -main (int argc, char **argv) -{ - char line[5000]; - size_t length; - rfc822parse_t msg; - - msg = rfc822parse_open (msg_cb, NULL); - if (!msg) - abort (); - - while (fgets (line, sizeof (line), stdin)) - { - length = strlen (line); - if (length && line[length - 1] == '\n') - line[--length] = 0; - if (length && line[length - 1] == '\r') - line[--length] = 0; - if (rfc822parse_insert (msg, line, length)) - abort (); - } - - dump_structure (msg, NULL, 0); - - rfc822parse_close (msg); - return 0; -} -#endif - -/* -Local Variables: -compile-command: "gcc -Wall -g -DTESTING -o rfc822parse rfc822parse.c" -End: -*/ diff --git a/tools/rfc822parse.h b/tools/rfc822parse.h deleted file mode 100644 index 1293117ac..000000000 --- a/tools/rfc822parse.h +++ /dev/null @@ -1,79 +0,0 @@ -/* rfc822parse.h - Simple mail and MIME parser - * Copyright (C) 1999 Werner Koch, Duesseldorf - * Copyright (C) 2003, g10 Code GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef RFC822PARSE_H -#define RFC822PARSE_H - -struct rfc822parse_context; -typedef struct rfc822parse_context *rfc822parse_t; - -typedef enum - { - RFC822PARSE_OPEN = 1, - RFC822PARSE_CLOSE, - RFC822PARSE_CANCEL, - RFC822PARSE_T2BODY, - RFC822PARSE_FINISH, - RFC822PARSE_RCVD_SEEN, - RFC822PARSE_LEVEL_DOWN, - RFC822PARSE_LEVEL_UP, - RFC822PARSE_BOUNDARY, - RFC822PARSE_LAST_BOUNDARY, - RFC822PARSE_BEGIN_HEADER, - RFC822PARSE_PREAMBLE, - RFC822PARSE_EPILOGUE - } -rfc822parse_event_t; - -struct rfc822parse_field_context; -typedef struct rfc822parse_field_context *rfc822parse_field_t; - - -typedef int (*rfc822parse_cb_t) (void *opaque, - rfc822parse_event_t event, - rfc822parse_t msg); - - -rfc822parse_t rfc822parse_open (rfc822parse_cb_t cb, void *opaque_value); - -void rfc822parse_close (rfc822parse_t msg); - -void rfc822parse_cancel (rfc822parse_t msg); -int rfc822parse_finish (rfc822parse_t msg); - -int rfc822parse_insert (rfc822parse_t msg, - const unsigned char *line, size_t length); - -char *rfc822parse_get_field (rfc822parse_t msg, const char *name, int which); - -const char *rfc822parse_enum_header_lines (rfc822parse_t msg, void **context); - -rfc822parse_field_t rfc822parse_parse_field (rfc822parse_t msg, - const char *name, - int which); - -void rfc822parse_release_field (rfc822parse_field_t field); - -const char *rfc822parse_query_parameter (rfc822parse_field_t ctx, - const char *attr, int lower_value); - -const char *rfc822parse_query_media_type (rfc822parse_field_t ctx, - const char **subtype); - -#endif /*RFC822PARSE_H */ diff --git a/tools/watchgnupg.c b/tools/watchgnupg.c deleted file mode 100644 index 7f79f2f18..000000000 --- a/tools/watchgnupg.c +++ /dev/null @@ -1,389 +0,0 @@ -/* watchgnupg.c - Socket server for GnuPG logs - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <errno.h> -#include <stdarg.h> -#include <assert.h> -#include <unistd.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <fcntl.h> -#include <time.h> - -#define PGM "watchgnupg" - -/* Allow for a standalone build. */ -#ifdef VERSION -#define MYVERSION_LINE PGM " (GnuPG) " VERSION -#define BUGREPORT_LINE "\nReport bugs to <bug-gnupg@gnu.org>.\n" -#else -#define MYVERSION_LINE PGM -#define BUGREPORT_LINE "" -#endif - -static int verbose; - - -static void -die (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", PGM); - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - putc ('\n', stderr); - - exit (1); -} - - -/* static void */ -/* err (const char *format, ...) */ -/* { */ -/* va_list arg_ptr; */ - -/* fflush (stdout); */ -/* fprintf (stderr, "%s: ", PGM); */ - -/* va_start (arg_ptr, format); */ -/* vfprintf (stderr, format, arg_ptr); */ -/* va_end (arg_ptr); */ -/* putc ('\n', stderr); */ -/* } */ - -static void * -xmalloc (size_t n) -{ - void *p = malloc (n); - if (!p) - die ("out of core"); - return p; -} - -static void * -xcalloc (size_t n, size_t m) -{ - void *p = calloc (n, m); - if (!p) - die ("out of core"); - return p; -} - -static void * -xrealloc (void *old, size_t n) -{ - void *p = realloc (old, n); - if (!p) - die ("out of core"); - return p; -} - - -struct client_s { - struct client_s *next; - int fd; - size_t size; /* Allocated size of buffer. */ - size_t len; /* Current length of buffer. */ - unsigned char *buffer; /* Buffer to with data already read. */ - -}; -typedef struct client_s *client_t; - - - -static void -print_fd_and_time (int fd) -{ - struct tm *tp; - time_t atime = time (NULL); - - tp = localtime (&atime); - printf ("%3d - %04d-%02d-%02d %02d:%02d:%02d ", - fd, - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec ); -} - - -/* Print LINE for the client identified by C. Calling this function - witgh LINE set to NULL, will flush the internal buffer. */ -static void -print_line (client_t c, const char *line) -{ - const char *s; - size_t n; - - if (!line) - { - if (c->buffer && c->len) - { - print_fd_and_time (c->fd); - fwrite (c->buffer, c->len, 1, stdout); - putc ('\n', stdout); - c->len = 0; - } - return; - } - - while ((s = strchr (line, '\n'))) - { - print_fd_and_time (c->fd); - if (c->buffer && c->len) - { - fwrite (c->buffer, c->len, 1, stdout); - c->len = 0; - } - fwrite (line, s - line + 1, 1, stdout); - line = s + 1; - } - n = strlen (line); - if (n) - { - if (c->len + n >= c->size) - { - c->size += ((n + 255) & ~255); - c->buffer = (c->buffer - ? xrealloc (c->buffer, c->size) - : xmalloc (c->size)); - } - memcpy (c->buffer + c->len, line, n); - c->len += n; - } -} - - -static void -print_version (int with_help) -{ - fputs (MYVERSION_LINE "\n" - "Copyright (C) 2004 Free Software Foundation, Inc.\n" - "This program comes with ABSOLUTELY NO WARRANTY.\n" - "This is free software, and you are welcome to redistribute it\n" - "under certain conditions. See the file COPYING for details.\n", - stdout); - - if (with_help) - fputs ("\n" - "Usage: " PGM " [OPTIONS] SOCKETNAME\n" - "Open the local socket SOCKETNAME and display log messages\n" - "\n" - " --force delete an already existing socket file\n" - " --verbose enable extra informational output\n" - " --version print version of the program and exit\n" - " --help display this help and exit\n" - BUGREPORT_LINE, stdout ); - - exit (0); -} - -int -main (int argc, char **argv) -{ - int last_argc = -1; - int force = 0; - - struct sockaddr_un srvr_addr; - int addrlen; - int server; - int flags; - client_t client_list = NULL; - - if (argc) - { - argc--; argv++; - } - while (argc && last_argc != argc ) - { - last_argc = argc; - if (!strcmp (*argv, "--")) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--version")) - print_version (0); - else if (!strcmp (*argv, "--help")) - print_version (1); - else if (!strcmp (*argv, "--verbose")) - { - verbose = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--force")) - { - force = 1; - argc--; argv++; - } - } - - if (argc != 1) - { - fprintf (stderr, "usage: " PGM " socketname\n"); - exit (1); - } - - - if (verbose) - fprintf (stderr, "opening socket `%s'\n", *argv); - - setvbuf (stdout, NULL, _IOLBF, 0); - - server = socket (PF_LOCAL, SOCK_STREAM, 0); - if (server == -1) - die ("socket() failed: %s\n", strerror (errno)); - - /* We better set the listening socket to non-blocking so that we - don't get bitten by race conditions in accept. The should not - happen for Unix Domain sockets but well, shit happens. */ - flags = fcntl (server, F_GETFL, 0); - if (flags == -1) - die ("fcntl (F_GETFL) failed: %s\n", strerror (errno)); - if ( fcntl (server, F_SETFL, (flags | O_NONBLOCK)) == -1) - die ("fcntl (F_SETFL) failed: %s\n", strerror (errno)); - - - memset (&srvr_addr, 0, sizeof srvr_addr); - srvr_addr.sun_family = AF_LOCAL; - strncpy (srvr_addr.sun_path, *argv, sizeof (srvr_addr.sun_path) - 1); - srvr_addr.sun_path[sizeof (srvr_addr.sun_path) - 1] = 0; - addrlen = (offsetof (struct sockaddr_un, sun_path) - + strlen (srvr_addr.sun_path) + 1); - - - again: - if (bind (server, (struct sockaddr *) &srvr_addr, addrlen)) - { - if (errno == EADDRINUSE && force) - { - force = 0; - remove (srvr_addr.sun_path); - goto again; - } - die ("bind to `%s' failed: %s\n", *argv, strerror (errno)); - } - - if (listen (server, 5)) - die ("listen failed: %s\n", strerror (errno)); - - for (;;) - { - fd_set rfds; - int max_fd; - client_t client; - - /* Usually we don't have that many connections, thus it is okay - to set them allways from scratch and don't maintain an active - fd_set. */ - FD_ZERO (&rfds); - FD_SET (server, &rfds); - max_fd = server; - for (client = client_list; client; client = client->next) - if (client->fd != -1) - { - FD_SET (client->fd, &rfds); - if (client->fd > max_fd) - max_fd = client->fd; - } - - if (select (max_fd + 1, &rfds, NULL, NULL, NULL) <= 0) - continue; /* Ignore any errors. */ - - if (FD_ISSET (server, &rfds)) /* New connection. */ - { - struct sockaddr_un clnt_addr; - int fd; - - addrlen = sizeof clnt_addr; - fd = accept (server, (struct sockaddr *) &clnt_addr, &addrlen); - if (fd == -1) - { - printf ("[accepting connection failed: %s]\n", strerror (errno)); - } - else if (fd >= FD_SETSIZE) - { - close (fd); - printf ("[connection request denied: too many connections]\n"); - } - else - { - for (client = client_list; client && client->fd != -1; - client = client->next) - ; - if (!client) - { - client = xcalloc (1, sizeof *client); - client->next = client_list; - client_list = client; - } - client->fd = fd; - printf ("[client at fd %d connected]\n", client->fd); - } - } - for (client = client_list; client; client = client->next) - if (client->fd != -1 && FD_ISSET (client->fd, &rfds)) - { - char line[256]; - int n; - - n = read (client->fd, line, sizeof line - 1); - if (n == 1) - { - int save_errno = errno; - print_line (client, NULL); /* flush */ - printf ("[client at fd %d read error: %s]\n", - client->fd, strerror (save_errno)); - close (client->fd); - client->fd = -1; - } - else if (!n) - { - print_line (client, NULL); /* flush */ - close (client->fd); - printf ("[client at fd %d disconnected]\n", client->fd); - client->fd = -1; - } - else - { - line[n] = 0; - print_line (client, line); - } - } - } - - return 0; -} - - -/* -Local Variables: -compile-command: "gcc -Wall -g -o watchgnupg watchgnupg.c" -End: -*/